public void Load(System.IO.Stream stream) { CanSave = true; Text = FileName; //Set renderer //Load it to a drawables list Renderer = new MDL_Renderer(); DrawableContainer.Name = FileName; DrawableContainer.Drawables.Add(Renderer); using (var reader = new FileReader(stream)) { reader.SetByteOrder(true); while (reader.EndOfStream == false) { long chunkStart = reader.Position; int opcode = reader.ReadInt32(); int lengthOfStruct = reader.ReadInt32(); // basic error checking if ((chunkStart & 0x1F) != 0) { throw new Exception($"Chunk start ({chunkStart}) not on boundary!"); } switch (opcode) { case 0x10: // VERTICES int vertexCount = reader.ReadInt32(); Vertices = new Vertex[vertexCount]; SkipPadding(reader, 0x20); for (int i = 0; i < vertexCount; i++) { float x = reader.ReadSingle(); float y = reader.ReadSingle(); float z = reader.ReadSingle(); Vertices[i] = new Vertex { pos = new Vector3(x, y, z) }; } SkipPadding(reader, 0x20); break; case 0x11: int vertexNormalCount = reader.ReadInt32(); VertexNormals = new Vertex[vertexNormalCount]; SkipPadding(reader, 0x20); for (int i = 0; i < vertexNormalCount; i++) { float x = reader.ReadSingle(); float y = reader.ReadSingle(); float z = reader.ReadSingle(); VertexNormals[i] = new Vertex { nrm = new Vector3(x, y, z) }; } SkipPadding(reader, 0x20); break; case 0x13: // COLOURS int colorCount = reader.ReadInt32(); Colors = new Vertex[colorCount]; SkipPadding(reader, 0x20); for (int i = 0; i < colorCount; i++) { byte x = reader.ReadByte(); byte y = reader.ReadByte(); byte z = reader.ReadByte(); byte w = reader.ReadByte(); Colors[i] = new Vertex { col = new Vector4(x, y, z, w) }; } SkipPadding(reader, 0x20); break; case 0x50: int meshCount = reader.ReadInt32(); SkipPadding(reader, 0x20); for (int i = 0; i < meshCount; i++) { //Create a renderable object for our mesh var renderedMesh = new GenericRenderedObject { Checked = true, ImageKey = "mesh", SelectedImageKey = "mesh", Text = $"Mesh {i}" }; Nodes.Add(renderedMesh); Renderer.Meshes.Add(renderedMesh); STGenericPolygonGroup polyGroup = new STGenericPolygonGroup(); renderedMesh.PolygonGroups.Add(polyGroup); reader.ReadInt32(); int vtxDescriptor = reader.ReadInt32(); int mtxGroupCount = reader.ReadInt32(); Console.WriteLine("mtxGroupCount " + mtxGroupCount); for (int a = 0; a < mtxGroupCount; a++) { int unkCount = reader.ReadInt32(); for (int unkIter = 0; unkIter < unkCount; unkIter++) { reader.ReadInt16(); } int dispListCount = reader.ReadInt32(); Console.WriteLine("dispListCount " + dispListCount); for (int b = 0; b < dispListCount; b++) { reader.ReadInt32(); reader.ReadInt32(); int displacementSize = reader.ReadInt32(); SkipPadding(reader, 0x20); long end_displist = reader.Position + displacementSize; Console.WriteLine("end_displist " + end_displist); Console.WriteLine("displacementSize " + displacementSize); Console.WriteLine("reader.Position " + reader.Position); while (reader.Position < end_displist) { byte faceOpCode = reader.ReadByte(); if (faceOpCode == 0x98 || faceOpCode == 0xA0) { short vCount = reader.ReadInt16(); int[] polys = new int[vCount]; for (int vc = 0; vc < vCount; vc++) { if ((vtxDescriptor & 0x1) == 0x1) { reader.ReadByte(); // Position Matrix } if ((vtxDescriptor & 0x2) == 0x2) { reader.ReadByte(); // tex1 matrix } ushort vtxPosIndex = reader.ReadUInt16(); uint normalID = 0; if (VertexNormals.Length > 0) { normalID = reader.ReadUInt16(); } uint colorID = 0; if ((vtxDescriptor & 0x4) == 0x4) { colorID = reader.ReadUInt16(); } int tmpVar = vtxDescriptor >> 3; uint texCoordID = 0; for (int c = 0; c < 8; c++) { if ((tmpVar & 0x1) == 0x1) { if (c == 0) { texCoordID = reader.ReadUInt16(); } } tmpVar >>= 1; } Vertex vert = new Vertex { pos = Vertices[vtxPosIndex].pos, nrm = VertexNormals[normalID].nrm, //col = Colors[colorID].col }; polys[vc] = renderedMesh.vertices.Count; renderedMesh.vertices.Add(vert); } List <Triangle> curPolys = ToTris(polys, faceOpCode); foreach (Triangle poly in curPolys) { Console.WriteLine($"{poly.A} {poly.B} {poly.C}"); polyGroup.faces.Add(poly.A); polyGroup.faces.Add(poly.B); polyGroup.faces.Add(poly.C); } } } } } Console.WriteLine("vertices " + renderedMesh.vertices.Count); Console.WriteLine("faces " + renderedMesh.PolygonGroups[0].faces.Count); Console.WriteLine("Vertices " + Vertices.Length); } break; default: reader.Seek(lengthOfStruct, System.IO.SeekOrigin.Current); break; } } } }
public void Load(System.IO.Stream stream) { CanSave = true; Text = FileName; //Set renderer //Load it to a drawables list Renderer = new MDL_Renderer(); Skeleton = new STSkeleton(); DrawableContainer.Name = FileName; DrawableContainer.Drawables.Add(Renderer); DrawableContainer.Drawables.Add(Skeleton); using (var reader = new FileReader(stream)) { reader.SetByteOrder(true); string[] JointNames = new string[0]; Joint[] Joints = new Joint[0]; Envelopes = new Envelope[0]; while (reader.EndOfStream == false) { long chunkStart = reader.Position; int opcode = reader.ReadInt32(); int lengthOfStruct = reader.ReadInt32(); // basic error checking if ((chunkStart & 0x1F) != 0) { throw new Exception($"Chunk start ({chunkStart}) not on boundary!"); } switch ((ChunkNames)opcode) { case ChunkNames.VertexPosition: Vertices = ReadVector3Array(reader); break; case ChunkNames.VertexNormal: VertexNormals = ReadVector3Array(reader); break; case ChunkNames.VertexColor: Colors = ReadVertexColors(reader); break; case ChunkNames.Mesh: ReadMeshChunk(reader); break; case ChunkNames.Envelope: Envelopes = ParseArray <Envelope>(reader); break; case ChunkNames.JointName: JointNames = ReadStrings(reader); break; case ChunkNames.Joint: Joints = ParseArray <Joint>(reader); break; default: reader.Seek(lengthOfStruct, System.IO.SeekOrigin.Current); break; } } for (int i = 0; i < Joints.Length; i++) { STBone bone = new STBone(Skeleton); bone.parentIndex = Joints[i].ParentIndex; bone.Position = Joints[i].Position; bone.EulerRotation = Joints[i].Rotation; bone.Scale = Joints[i].Scale; Skeleton.bones.Add(bone); } Skeleton.reset(); Skeleton.update(); foreach (var mesh in Renderer.Meshes) { for (int v = 0; v < mesh.vertices.Count; v++) { var vertex = mesh.vertices[v]; if (vertex.boneIds.Count == 1) { var transform = Skeleton.bones[vertex.boneIds[0]].Transform; vertex.pos = Vector3.TransformPosition(vertex.pos, transform); } } } } }