public MT5Mesh(ModelNode node, MT5Node newNode) { Node = newNode; foreach (MeshFace face in node.Faces) { MT5StripAttributes attr = new MT5StripAttributes(MT5MeshEntryType.StripAttrib_0200); StripEntries.Add(attr); MT5StripTexture tex = new MT5StripTexture(); tex.TextureIndex = (ushort)face.TextureIndex; StripEntries.Add(tex); MT5UVSize unk0B00 = new MT5UVSize(); StripEntries.Add(unk0B00); if (face.HasUVs && face.HasColors) { MT5Strip strip = new MT5Strip(MT5MeshEntryType.Strip_1C00, this); strip.Faces.Add(face); StripEntries.Add(strip); } if (face.HasUVs) { MT5Strip strip = new MT5Strip(MT5MeshEntryType.Strip_1900, this); strip.Faces.Add(face); StripEntries.Add(strip); } if (face.HasColors) { MT5Strip strip = new MT5Strip(MT5MeshEntryType.Strip_1A00, this); strip.Faces.Add(face); StripEntries.Add(strip); } } }
public void Read(BinaryReader reader, MT5Node node) { Node = node; ParentNode = (MT5Node)node.Parent; Offset = (uint)reader.BaseStream.Position; //Console.WriteLine("MeshOffset: {0}", Offset); PolyType = reader.ReadUInt32(); VerticesOffset = reader.ReadUInt32(); VertexCount = reader.ReadInt32(); FacesOffset = reader.ReadUInt32(); Node.Center = new Vector3() { X = reader.ReadSingle(), Y = reader.ReadSingle(), Z = reader.ReadSingle() }; Node.Radius = reader.ReadSingle(); //Read strips/faces reader.BaseStream.Seek(FacesOffset, SeekOrigin.Begin); //read strip functions while (reader.BaseStream.Position < reader.BaseStream.Length - 4) { ushort stripType = reader.ReadUInt16(); if ((MT5MeshEntryType)stripType == MT5MeshEntryType.End) { MT5_End stripEnd = new MT5_End(); StripEntries.Add(stripEnd); break; } switch ((MT5MeshEntryType)stripType) { case MT5MeshEntryType.Zero: MT5_Zero stripZero = new MT5_Zero(); StripEntries.Add(stripZero); continue; case MT5MeshEntryType.ZeroN: MT5_ZeroN stripZeroN = new MT5_ZeroN(); StripEntries.Add(stripZeroN); continue; case MT5MeshEntryType.StripAttrib_0200: case MT5MeshEntryType.StripAttrib_0300: case MT5MeshEntryType.StripAttrib_0400: case MT5MeshEntryType.StripAttrib_0500: case MT5MeshEntryType.StripAttrib_0600: case MT5MeshEntryType.StripAttrib_0700: MT5StripAttributes stripAttributes = new MT5StripAttributes((MT5MeshEntryType)stripType); stripAttributes.Read(reader); CurrentIsUVH = stripAttributes.IsUVH; CurrentMirrorU = stripAttributes.MirrorU; CurrentMirrorV = stripAttributes.MirrorV; StripEntries.Add(stripAttributes); continue; //ignored by d3t case MT5MeshEntryType.Unknown_0E00: case MT5MeshEntryType.Unknown_0F00: MT5_0E00_0F00 strip_0E00_0F00 = new MT5_0E00_0F00((MT5MeshEntryType)stripType); strip_0E00_0F00.Read(reader); StripEntries.Add(strip_0E00_0F00); continue; //ignored by d3t case MT5MeshEntryType.Unknown_8000: case MT5MeshEntryType.Unknown_A000: MT5_8000_A000 strip_8000_A000 = new MT5_8000_A000((MT5MeshEntryType)stripType); strip_8000_A000.Read(reader); StripEntries.Add(strip_8000_A000); continue; case MT5MeshEntryType.UVSize_0B00: MT5UVSize uvSize = new MT5UVSize(); uvSize.Read(reader); CurrentUVSize = uvSize.Value; StripEntries.Add(uvSize); continue; case MT5MeshEntryType.Texture: MT5StripTexture stripTexture = new MT5StripTexture(); stripTexture.Read(reader); CurrentTextureIndex = stripTexture.TextureIndex; if (CurrentTextureIndex < Node.MT5.Textures.Count) { if (Node.MT5.Textures[(int)CurrentTextureIndex] == null) { continue; } if (MT5.UVMirrorTextureResize) { Node.MT5.Textures[(int)CurrentTextureIndex].Image.MirrorResize(CurrentMirrorU, CurrentMirrorV); } } StripEntries.Add(stripTexture); continue; //Face strips case MT5MeshEntryType.Strip_1000: case MT5MeshEntryType.Strip_1100: case MT5MeshEntryType.Strip_1200: case MT5MeshEntryType.Strip_1300: case MT5MeshEntryType.Strip_1400: case MT5MeshEntryType.Strip_1800: case MT5MeshEntryType.Strip_1900: case MT5MeshEntryType.Strip_1A00: case MT5MeshEntryType.Strip_1B00: case MT5MeshEntryType.Strip_1C00: MT5Strip strip = new MT5Strip((MT5MeshEntryType)stripType, this); strip.Read(reader); StripEntries.Add(strip); continue; default: //unknown type defaults to breaking stripType = (ushort)MT5MeshEntryType.End; break; } if ((MT5MeshEntryType)stripType == MT5MeshEntryType.End) { MT5_End stripEnd = new MT5_End(); StripEntries.Add(stripEnd); break; } } //Read vertices reader.BaseStream.Seek(VerticesOffset, SeekOrigin.Begin); for (int i = 0; i < VertexCount; i++) { Vector3 pos; pos.X = reader.ReadSingle(); pos.Y = reader.ReadSingle(); pos.Z = reader.ReadSingle(); Node.VertexPositions.Add(pos); Vector3 norm; norm.X = reader.ReadSingle(); norm.Y = reader.ReadSingle(); norm.Z = reader.ReadSingle(); Node.VertexNormals.Add(norm); } if (ParentNode != null && ParentNode.MeshData != null) { //Because for performance/memory saving the vertices from the parent can be used via negativ vertex indices //we just copy the parent vertices so we can use them with modified vertex offsets //Apply the inverted transform matrix of the node on vertices so they get canceled out by the final transform. Matrix4 matrix = Node.GetTransformMatrixSelf().Inverted(); for (int i = 0; i < ParentNode.VertexCount; i++) { Vector3 pos = new Vector3(ParentNode.VertexPositions[i]); Vector3 norm = new Vector3(ParentNode.VertexNormals[i]); pos = Vector3.TransformPosition(pos, matrix); norm = Vector3.TransformPosition(norm, matrix); Node.VertexPositions.Add(pos); Node.VertexNormals.Add(norm); } } }