public MTModel(BinaryReader Reader, MTMaterials MRLData, MTShaderEffects Shader) : this() { string Magic = Reader.ReadPaddedString(4); ushort Version = Reader.ReadUInt16(); ushort BonesCount = Reader.ReadUInt16(); ushort MeshesCount = Reader.ReadUInt16(); ushort MaterialsCount = Reader.ReadUInt16(); uint TotalVerticesCount = Reader.ReadUInt32(); uint TotalIndicesCount = Reader.ReadUInt32(); uint TotalTrianglesCount = Reader.ReadUInt32(); uint VerticesBufferLength = Reader.ReadUInt32(); uint HeaderPadding1c = Reader.ReadUInt32(); //? uint MeshGroupsCount = Reader.ReadUInt32(); uint BoneIndicesCount = Reader.ReadUInt32(); uint SkeletonAddress = Reader.ReadUInt32(); uint MeshGroupsAddr = Reader.ReadUInt32(); uint MaterialNamesAddress = Reader.ReadUInt32(); uint MeshesAddress = Reader.ReadUInt32(); uint VerticesBufferAddress = Reader.ReadUInt32(); uint IndicesBufferAddress = Reader.ReadUInt32(); uint ModelFileLength = Reader.ReadUInt32(); BoundingSphere = Reader.ReadVector4(); BoundingBoxMin = Reader.ReadVector4(); BoundingBoxMax = Reader.ReadVector4(); string[] MaterialNames = new string[MaterialsCount]; Reader.BaseStream.Seek(MaterialNamesAddress, SeekOrigin.Begin); for (int Index = 0; Index < MaterialsCount; Index++) { MaterialNames[Index] = Reader.ReadPaddedString(0x80); } for (int Index = 0; Index < MeshesCount; Index++) { Reader.BaseStream.Seek(MeshesAddress + Index * 0x30, SeekOrigin.Begin); MTMesh Mesh = new MTMesh( Reader, Shader, VerticesBufferAddress, IndicesBufferAddress); string MaterialName = MaterialNames[Mesh.MaterialIndex]; uint MaterialHash = CRC32Hash.Hash(MaterialName); int MaterialIndex = Materials.FindIndex(x => x.NameHash == MaterialHash); if (MaterialIndex == -1) { MTMaterial Mat = MRLData.Materials.FirstOrDefault(x => x.NameHash == MaterialHash); if (Mat != null) { Mat.Name = MaterialName; MaterialIndex = Materials.Count; Materials.Add(Mat); } else { MaterialIndex = 0; } } Mesh.MaterialIndex = (uint)MaterialIndex; Meshes.Add(Mesh); } for (int Index = 0; Index < BonesCount; Index++) { Reader.BaseStream.Seek(SkeletonAddress + Index * 0x18, SeekOrigin.Begin); sbyte BoneIndex = Reader.ReadSByte(); sbyte Parent = Reader.ReadSByte(); sbyte Opposite = Reader.ReadSByte(); byte Padding = Reader.ReadByte(); float ChildDistance = Reader.ReadSingle(); float ParentDistance = Reader.ReadSingle(); Vector3 Position = Reader.ReadVector3(); Skeleton.Add(new MTBone() { ParentIndex = Parent, OppositeIndex = Opposite, ChildDistance = ChildDistance, ParentDistance = ParentDistance, Position = Position }); } for (int Index = 0; Index < BonesCount; Index++) { Skeleton[Index].LocalTransform = Reader.ReadMatrix4x4RH(); } for (int Index = 0; Index < BonesCount; Index++) { Skeleton[Index].WorldTransform = Reader.ReadMatrix4x4RH(); } Reader.BaseStream.Seek(0x100, SeekOrigin.Current); BoneIndicesGroups = new byte[BoneIndicesCount][]; for (int i = 0; i < BoneIndicesCount; i++) { int Count = Reader.ReadInt32(); BoneIndicesGroups[i] = new byte[Count]; for (int j = 0; j < Count; j++) { BoneIndicesGroups[i][j] = Reader.ReadByte(); } Reader.BaseStream.Seek(0x18 - Count, SeekOrigin.Current); } }
public MTShaderEffects(BinaryReader Reader) { string Magic = Reader.ReadNullTerminatedString(); //MFX Reader.BaseStream.Seek(8, SeekOrigin.Current); //Unknown stuff uint DescriptorsCount = Reader.ReadUInt32(); uint FragShaderCount = Reader.ReadUInt32(); uint VtxShaderCount = Reader.ReadUInt32(); uint FragShaderAddr = Reader.ReadUInt32(); uint VtxShaderAddr = Reader.ReadUInt32(); uint StringsTblAddr = Reader.ReadUInt32(); uint VtxProgramAddr = Reader.ReadUInt32(); long VtxFormatsAddr = Reader.BaseStream.Position; for (uint i = 0; i < DescriptorsCount; i++) { Reader.BaseStream.Seek(VtxFormatsAddr + i * 4, SeekOrigin.Begin); Reader.BaseStream.Seek(Reader.ReadUInt32(), SeekOrigin.Begin); if (Reader.BaseStream.Position == 0) { continue; } string DescName = GetName(Reader, StringsTblAddr); string TypeName = GetName(Reader, StringsTblAddr); ushort DescType = Reader.ReadUInt16(); ushort MapLength = Reader.ReadUInt16(); //Actual length is value / 2? Not sure ushort MapIndex = Reader.ReadUInt16(); ushort DescIndex = Reader.ReadUInt16(); uint MapAddress = Reader.ReadUInt32(); //Not sure what this address actually points to uint Hash = (CRC32Hash.Hash(DescName) << 12) | DescIndex; MTShaderEffect Desc = new MTShaderEffect(); if (TypeName == "__InputLayout") { Desc = new MTAttributesGroup(Reader, StringsTblAddr); } else { switch (DescType) { case 2: Desc = new MTTextureMap(Reader); break; case 5: Desc = new MTAlphaBlend(Reader); break; case 6: Desc = new MTDepthStencil(Reader); break; } } Desc.Name = DescName; Desc.Type = TypeName; Descriptors.Add(Hash, Desc); } for (uint i = 0; i < FragShaderCount; i++) { Reader.BaseStream.Seek(FragShaderAddr + i * 4, SeekOrigin.Begin); Reader.BaseStream.Seek(Reader.ReadUInt32(), SeekOrigin.Begin); FragmentLighting.Add(new MTFragmentLighting(Reader)); } }