Esempio n. 1
0
        public override void LoadFile()
        {
            // We can ensure based on content-type that files are models
            if (FileInfo.Type != FileType.Model)
            {
                Console.WriteLine($"Attempted to load {FilePath} of content type {FileInfo.Type} as a model, returning...");
                return;
            }

            FileHeader = MdlStructs.ModelFileHeader.Read(Reader);

            VertexDeclarations = new MdlStructs.VertexDeclarationStruct[FileHeader.VertexDeclarationCount];
            for (int i = 0; i < FileHeader.VertexDeclarationCount; i++)
            {
                VertexDeclarations[i] = MdlStructs.VertexDeclarationStruct.Read(Reader);
            }

            StringCount = Reader.ReadUInt16();
            Reader.ReadUInt16();
            uint stringSize = Reader.ReadUInt32();

            Strings = Reader.ReadBytes((int)stringSize);

            ModelHeader       = Reader.ReadStructure <MdlStructs.ModelHeader>();
            ElementIds        = new MdlStructs.ElementIdStruct[ModelHeader.ElementIdCount];
            Meshes            = new MdlStructs.MeshStruct[ModelHeader.MeshCount];
            BoneTables        = new MdlStructs.BoneTableStruct[ModelHeader.BoneTableCount];
            Shapes            = new MdlStructs.ShapeStruct[ModelHeader.ShapeCount];
            BoneBoundingBoxes = new MdlStructs.BoundingBoxStruct[ModelHeader.BoneCount];

            for (int i = 0; i < ModelHeader.ElementIdCount; i++)
            {
                ElementIds[i] = MdlStructs.ElementIdStruct.Read(Reader);
            }
            Lods = Reader.ReadStructuresAsArray <MdlStructs.LodStruct>(3);

            if (ModelHeader.ExtraLodEnabled)
            {
                ExtraLods = Reader.ReadStructuresAsArray <MdlStructs.ExtraLodStruct>(3);
            }

            for (int i = 0; i < ModelHeader.MeshCount; i++)
            {
                Meshes[i] = MdlStructs.MeshStruct.Read(Reader);
            }
            AttributeNameOffsets   = Reader.ReadStructures <UInt32>(ModelHeader.AttributeCount).ToArray();
            TerrainShadowMeshes    = Reader.ReadStructuresAsArray <MdlStructs.TerrainShadowMeshStruct>(ModelHeader.TerrainShadowMeshCount);
            Submeshes              = Reader.ReadStructuresAsArray <MdlStructs.SubmeshStruct>(ModelHeader.SubmeshCount);
            TerrainShadowSubmeshes = Reader.ReadStructuresAsArray <MdlStructs.TerrainShadowSubmeshStruct>(ModelHeader.TerrainShadowSubmeshCount);

            MaterialNameOffsets = Reader.ReadStructures <UInt32>(ModelHeader.MaterialCount).ToArray();
            BoneNameOffsets     = Reader.ReadStructures <UInt32>(ModelHeader.BoneCount).ToArray();
            for (int i = 0; i < ModelHeader.BoneTableCount; i++)
            {
                BoneTables[i] = MdlStructs.BoneTableStruct.Read(Reader);
            }

            for (int i = 0; i < ModelHeader.ShapeCount; i++)
            {
                Shapes[i] = MdlStructs.ShapeStruct.Read(Reader);
            }
            ShapeMeshes = Reader.ReadStructuresAsArray <MdlStructs.ShapeMeshStruct>(ModelHeader.ShapeMeshCount);
            ShapeValues = Reader.ReadStructuresAsArray <MdlStructs.ShapeValueStruct>(ModelHeader.ShapeValueCount);

            uint submeshBoneMapSize = Reader.ReadUInt32();

            SubmeshBoneMap = Reader.ReadStructures <UInt16>((int)submeshBoneMapSize / 2).ToArray();

            byte paddingAmount = Reader.ReadByte();

            Reader.Seek(Reader.BaseStream.Position + paddingAmount);

            // Dunno what this first one is for?
            BoundingBoxes            = MdlStructs.BoundingBoxStruct.Read(Reader);
            ModelBoundingBoxes       = MdlStructs.BoundingBoxStruct.Read(Reader);
            WaterBoundingBoxes       = MdlStructs.BoundingBoxStruct.Read(Reader);
            VerticalFogBoundingBoxes = MdlStructs.BoundingBoxStruct.Read(Reader);
            for (int i = 0; i < ModelHeader.BoneCount; i++)
            {
                BoneBoundingBoxes[i] = MdlStructs.BoundingBoxStruct.Read(Reader);
            }
        }
Esempio n. 2
0
    public MdlFile(byte[] data)
    {
        using var stream = new MemoryStream(data);
        using var r      = new BinaryReader(stream);

        var header = LoadModelFileHeader(r);

        LodCount         = header.LodCount;
        VertexBufferSize = header.VertexBufferSize;
        IndexBufferSize  = header.IndexBufferSize;
        VertexOffset     = header.VertexOffset;
        IndexOffset      = header.IndexOffset;
        for (var i = 0; i < 3; ++i)
        {
            if (VertexOffset[i] > 0)
            {
                VertexOffset[i] -= header.RuntimeSize;
            }

            if (IndexOffset[i] > 0)
            {
                IndexOffset[i] -= header.RuntimeSize;
            }
        }

        VertexDeclarations = new MdlStructs.VertexDeclarationStruct[header.VertexDeclarationCount];
        for (var i = 0; i < header.VertexDeclarationCount; ++i)
        {
            VertexDeclarations[i] = MdlStructs.VertexDeclarationStruct.Read(r);
        }

        var(offsets, strings) = LoadStrings(r);

        var modelHeader = LoadModelHeader(r);

        ElementIds = new MdlStructs.ElementIdStruct[modelHeader.ElementIdCount];
        for (var i = 0; i < modelHeader.ElementIdCount; i++)
        {
            ElementIds[i] = MdlStructs.ElementIdStruct.Read(r);
        }

        Lods      = r.ReadStructuresAsArray <MdlStructs.LodStruct>(3);
        ExtraLods = modelHeader.ExtraLodEnabled
            ? r.ReadStructuresAsArray <MdlStructs.ExtraLodStruct>(3)
            : Array.Empty <MdlStructs.ExtraLodStruct>();

        Meshes = new MdlStructs.MeshStruct[modelHeader.MeshCount];
        for (var i = 0; i < modelHeader.MeshCount; i++)
        {
            Meshes[i] = MdlStructs.MeshStruct.Read(r);
        }

        Attributes = new string[modelHeader.AttributeCount];
        for (var i = 0; i < modelHeader.AttributeCount; ++i)
        {
            var offset    = r.ReadUInt32();
            var stringIdx = offsets.AsSpan().IndexOf(offset);
            Attributes[i] = stringIdx >= 0 ? strings[stringIdx] : string.Empty;
        }

        TerrainShadowMeshes    = r.ReadStructuresAsArray <MdlStructs.TerrainShadowMeshStruct>(modelHeader.TerrainShadowMeshCount);
        SubMeshes              = r.ReadStructuresAsArray <MdlStructs.SubmeshStruct>(modelHeader.SubmeshCount);
        TerrainShadowSubMeshes = r.ReadStructuresAsArray <MdlStructs.TerrainShadowSubmeshStruct>(modelHeader.TerrainShadowSubmeshCount);

        Materials = new string[modelHeader.MaterialCount];
        for (var i = 0; i < modelHeader.MaterialCount; ++i)
        {
            var offset    = r.ReadUInt32();
            var stringIdx = offsets.AsSpan().IndexOf(offset);
            Materials[i] = stringIdx >= 0 ? strings[stringIdx] : string.Empty;
        }

        Bones = new string[modelHeader.BoneCount];
        for (var i = 0; i < modelHeader.BoneCount; ++i)
        {
            var offset    = r.ReadUInt32();
            var stringIdx = offsets.AsSpan().IndexOf(offset);
            Bones[i] = stringIdx >= 0 ? strings[stringIdx] : string.Empty;
        }

        BoneTables = new MdlStructs.BoneTableStruct[modelHeader.BoneTableCount];
        for (var i = 0; i < modelHeader.BoneTableCount; i++)
        {
            BoneTables[i] = MdlStructs.BoneTableStruct.Read(r);
        }

        Shapes = new Shape[modelHeader.ShapeCount];
        for (var i = 0; i < modelHeader.ShapeCount; i++)
        {
            Shapes[i] = new Shape(MdlStructs.ShapeStruct.Read(r), offsets, strings);
        }

        ShapeMeshes = r.ReadStructuresAsArray <MdlStructs.ShapeMeshStruct>(modelHeader.ShapeMeshCount);
        ShapeValues = r.ReadStructuresAsArray <MdlStructs.ShapeValueStruct>(modelHeader.ShapeValueCount);

        var submeshBoneMapSize = r.ReadUInt32();

        SubMeshBoneMap = r.ReadStructures <ushort>(( int )submeshBoneMapSize / 2).ToArray();

        var paddingAmount = r.ReadByte();

        r.Seek(r.BaseStream.Position + paddingAmount);

        // Dunno what this first one is for?
        BoundingBoxes            = MdlStructs.BoundingBoxStruct.Read(r);
        ModelBoundingBoxes       = MdlStructs.BoundingBoxStruct.Read(r);
        WaterBoundingBoxes       = MdlStructs.BoundingBoxStruct.Read(r);
        VerticalFogBoundingBoxes = MdlStructs.BoundingBoxStruct.Read(r);
        BoneBoundingBoxes        = new MdlStructs.BoundingBoxStruct[modelHeader.BoneCount];
        for (var i = 0; i < modelHeader.BoneCount; i++)
        {
            BoneBoundingBoxes[i] = MdlStructs.BoundingBoxStruct.Read(r);
        }

        RemainingData = r.ReadBytes(( int )(r.BaseStream.Length - r.BaseStream.Position));
    }