public Model(string object_name, uint triangleCount, uint vertexCount, PassthroughGP passGP, TopologyIP topoIP, MaterialGroup matg, Object3D parent) : base(object_name, parent) { this.size = 0; // TODO: Get rid of all referring to things by section ID outside of read/write of model files so we don't have to do this. SectionId = (uint)object_name.GetHashCode(); this.version = 3; this.PassthroughGP = passGP; this.TopologyIP = topoIP; this.RenderAtoms = new List <RenderAtom>(); RenderAtom nmi = new RenderAtom { BaseVertex = 0, TriangleCount = triangleCount, BaseIndex = 0, GeometrySliceLength = vertexCount, MaterialId = 0 }; this.RenderAtoms.Add(nmi); //this.unknown9 = 0; this.MaterialGroup = matg; this.lightset_ID = 0; this.properties_bitmap = 0; this.BoundingRadius = 1; this.unknown13 = 6; this.SkinBones = null; }
public Model(BinaryReader instream, SectionHeader section) : base(instream) { this.RenderAtoms = new List <RenderAtom>(); this.size = section.size; SectionId = section.id; this.version = instream.ReadUInt32(); if (this.version == 6) { this.BoundsMin = instream.ReadVector3(); this.BoundsMax = instream.ReadVector3(); this.v6_unknown7 = instream.ReadSingle(); this.v6_unknown8 = instream.ReadUInt32(); } else { PostLoadRef <PassthroughGP>(instream.ReadUInt32(), i => PassthroughGP = i); PostLoadRef <TopologyIP>(instream.ReadUInt32(), i => TopologyIP = i); var renderAtomCount = instream.ReadUInt32(); for (int x = 0; x < renderAtomCount; x++) { RenderAtom item = new RenderAtom(); item.BaseVertex = instream.ReadUInt32(); item.TriangleCount = instream.ReadUInt32(); item.BaseIndex = instream.ReadUInt32(); item.GeometrySliceLength = instream.ReadUInt32(); item.MaterialId = instream.ReadUInt32(); this.RenderAtoms.Add(item); } //this.unknown9 = instream.ReadUInt32(); PostLoadRef <MaterialGroup>(instream.ReadUInt32(), i => MaterialGroup = i); this.lightset_ID = instream.ReadUInt32(); // this is a section id afaik // Bitmap that stores properties about the model // Bits: // 1: cast_shadows // 3: has_opacity this.properties_bitmap = instream.ReadUInt32(); this.BoundsMin = instream.ReadVector3(); this.BoundsMax = instream.ReadVector3(); this.BoundingRadius = instream.ReadSingle(); this.unknown13 = instream.ReadUInt32(); PostLoadRef <SkinBones>(instream.ReadUInt32(), i => SkinBones = i); } this.remaining_data = null; if ((section.offset + 12 + section.size) > instream.BaseStream.Position) { remaining_data = instream.ReadBytes((int)((section.offset + 12 + section.size) - instream.BaseStream.Position)); } }
public static MeshData FromGltfMesh(GLTF.Mesh mesh) { var vcount = mesh.Primitives.Select(prim => prim.VertexAccessors["POSITION"].Count).Sum(); if (vcount >= ushort.MaxValue) { throw new Exception($"Too many vertices ({vcount}) in mesh {mesh.Name}. Limit is 65535"); } var attribsUsed = mesh.Primitives.First().VertexAccessors.Select(i => i.Key).OrderBy(i => i); var ok = mesh.Primitives.Select(i => i.VertexAccessors.Keys.OrderBy(j => j)).Aggregate(true, (acc, curr) => acc && curr.SequenceEqual(attribsUsed)); if (!ok) { throw new Exception("Vertex attributes not consistent between Primitives. Diesel cannot represent this."); } var ms = new MeshData(); ms.materials = mesh.Primitives.Select(i => i.Material?.Name ?? "Material: Default Material").Distinct().ToList(); uint currentBaseVertex = 0; uint currentBaseIndex = 0; foreach (var prim in mesh.Primitives) { var vertices = GetVerticesFromPrimitive(prim).ToList(); var primFaces = prim.GetTriangleIndices().ToList(); var matname = prim.Material?.Name ?? "Material: Default Material"; var ra = new DM.RenderAtom { BaseIndex = currentBaseIndex, BaseVertex = currentBaseVertex, MaterialId = (uint)ms.materials.IndexOf(matname), TriangleCount = (uint)primFaces.Count }; var vertexIds = new Dictionary <Vertex, int>(); foreach (var(A, B, C) in primFaces) { var vtxA = vertices[A]; var vtxB = vertices[B]; var vtxC = vertices[C]; if (!vertexIds.ContainsKey(vtxA)) { vertexIds[vtxA] = ms.AppendVertex(vtxA); } if (!vertexIds.ContainsKey(vtxB)) { vertexIds[vtxB] = ms.AppendVertex(vtxB); } if (!vertexIds.ContainsKey(vtxC)) { vertexIds[vtxC] = ms.AppendVertex(vtxC); } var df = new DM.Face( (ushort)vertexIds[vtxA], (ushort)vertexIds[vtxB], (ushort)vertexIds[vtxC] ); ms.faces.Add(df); } ra.GeometrySliceLength = (uint)vertexIds.Count; ms.renderAtoms.Add(ra); currentBaseIndex += ra.TriangleCount * 3; currentBaseVertex += ra.GeometrySliceLength; } return(ms); }