コード例 #1
0
        // Methods
        public override void Load(Stream fileStream)
        {
            var reader = new GensReader(fileStream);

            Header = new GensHeader(reader);
            Read(reader);
        }
コード例 #2
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new GensReader(fileStream, true);

            Header = new GensHeader(reader);

            // Root Node
            uint lightType = reader.ReadUInt32();

            if (lightType < 0 || lightType > 1)
            {
                throw new InvalidDataException(
                          $"Cannot read light - unknown light type! ({lightType})");
            }

            // Data
            LightType = (LightTypes)lightType;

            Position = reader.ReadVector3();
            Color    = reader.ReadVector3();

            if (LightType == LightTypes.Omni)
            {
                UnknownTotal1 = reader.ReadUInt32();
                UnknownTotal2 = reader.ReadUInt32();
                UnknownTotal3 = reader.ReadUInt32();

                OmniInnerRange = reader.ReadSingle();
                OmniOuterRange = reader.ReadSingle();
            }
        }
コード例 #3
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new GensReader(fileStream);

            Header = new GensHeader(reader);

            // Root Node
            uint modelFileNameOffset = reader.ReadUInt32();
            uint matrixOffset        = reader.ReadUInt32();
            uint fileNameOffset      = reader.ReadUInt32();
            uint instanceTotal       = reader.ReadUInt32();
            uint fileNameOffsetEnd   = reader.ReadUInt32();

            // File Name
            reader.JumpTo(fileNameOffset, false);
            FileName = reader.ReadNullTerminatedString();

            // Matrix
            reader.JumpTo(matrixOffset, false);
            for (int x = 0; x < 4; ++x)
            {
                for (int y = 0; y < 4; ++y)
                {
                    matrix[x, y] = reader.ReadSingle();
                }
            }

            // Model File Name
            reader.JumpTo(modelFileNameOffset, false);
            ModelFileName = reader.ReadNullTerminatedString();

            // Mesh "Loaders" (what?)
            // TODO
        }
コード例 #4
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new GensReader(fileStream, true);

            Header = new GensHeader(reader);

            // Root Node
            uint instanceInfoCount         = reader.ReadUInt32();
            uint instanceInfoOffsetsOffset = reader.ReadUInt32();

            uint terrainModelCount         = reader.ReadUInt32();
            uint terrainModelOffsetsOffset = reader.ReadUInt32();

            // Instance Infos
            InstanceInfos = new InstanceInfoEntry[instanceInfoCount];
            reader.JumpTo(instanceInfoOffsetsOffset, false);

            for (uint i = 0; i < instanceInfoCount; ++i)
            {
                var  instanceInfo       = new InstanceInfoEntry();
                uint instanceInfoOffset = reader.ReadUInt32();
                long curPos             = reader.BaseStream.Position;
                reader.JumpTo(instanceInfoOffset, false);

                uint fileNameCount         = reader.ReadUInt32();
                uint fileNameOffsetsOffset = reader.ReadUInt32();
                uint boundingSphereOffset  = reader.ReadUInt32();
                reader.JumpTo(fileNameOffsetsOffset, false);

                // File Names
                instanceInfo.FileNames = new string[fileNameCount];
                for (uint i2 = 0; i2 < fileNameCount; ++i2)
                {
                    instanceInfo.FileNames[i2] = reader.GetString();
                }

                // Bounding Sphere
                reader.JumpTo(boundingSphereOffset, false);
                instanceInfo.BoundingSphereCenter = reader.ReadVector3();
                instanceInfo.BoundingSphereRadius = reader.ReadSingle();

                InstanceInfos[i]           = instanceInfo;
                reader.BaseStream.Position = curPos;
            }

            // Terrain Models
            TerrainModels = new string[terrainModelCount];
            reader.JumpTo(terrainModelOffsetsOffset, false);

            for (uint i = 0; i < terrainModelCount; ++i)
            {
                TerrainModels[i] = reader.GetString();
            }
        }
コード例 #5
0
        public override void Load(Stream fileStream)
        {
            var reader = new GensReader(fileStream);

            Header = new GensHeader(reader);

            uint textureCount   = reader.ReadUInt32();
            uint texturesOffset = reader.ReadUInt32();

            reader.JumpTo(texturesOffset, false);
            Read(reader, textureCount);
        }
コード例 #6
0
            // Methods
            public unsafe void Read(GensReader reader, float *data, float scale = 1)
            {
                switch ((DataTypes)Type)
                {
                case DataTypes.Vector2:
                    *data   = reader.ReadSingle() * scale;
                    *++data = reader.ReadSingle() * scale;
                    break;

                case DataTypes.Vector2_Half:
                    *data   = reader.ReadHalf();
                    *++data = reader.ReadHalf();
                    break;

                case DataTypes.Vector3:
                    *data   = reader.ReadSingle() * scale;
                    *++data = reader.ReadSingle() * scale;
                    *++data = reader.ReadSingle() * scale;
                    break;

                case DataTypes.Vector3_360:
                    // TODO: Read this properly
                    reader.ReadUInt32();
                    break;

                case DataTypes.Vector3_Forces:
                    // TODO: Read this properly
                    reader.ReadUInt32();
                    break;

                case DataTypes.Vector4:
                    *data   = reader.ReadSingle() * scale;
                    *++data = reader.ReadSingle() * scale;
                    *++data = reader.ReadSingle() * scale;
                    *++data = reader.ReadSingle() * scale;
                    break;

                case DataTypes.Vector4_Byte:
                case DataTypes.Indices:
                    // TODO: Read this properly
                    reader.ReadUInt32();
                    break;

                case DataTypes.Indices_Byte:
                    // TODO: Read this properly
                    reader.ReadUInt32();
                    break;
                }
            }
コード例 #7
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new GensReader(fileStream, true);

            Header = new GensHeader(reader);

            // Root Node
            uint lightTotal       = reader.ReadUInt32();
            uint lightTableOffset = reader.ReadUInt32();

            // Data
            reader.JumpTo(lightTableOffset, false);
            for (uint i = 0; i < lightTotal; ++i)
            {
                LightNames.Add(reader.GetString());
            }
        }
コード例 #8
0
        public virtual void Load(Stream fileStream, bool isTerrain, float scale = 1)
        {
            // Header
            var reader = new GensReader(fileStream);

            Header = reader.ReadHeader();

            // Data
            uint meshCount         = reader.ReadUInt32();
            uint meshOffsetsOffset = reader.ReadUInt32();

            if (isTerrain)
            {
                uint modelNameOffset = reader.ReadUInt32(); // TODO: Use this
                uint modelFlag       = reader.ReadUInt32(); // TODO: Use this
            }
            else
            {
                // TODO: Read the skeleton
            }

            // Mesh Offsets
            var meshOffsets = new uint[meshCount];

            reader.JumpTo(meshOffsetsOffset, false);

            for (uint i = 0; i < meshCount; ++i)
            {
                meshOffsets[i] = reader.ReadUInt32();
            }

            // Meshes
            for (uint i = 0; i < meshCount; ++i)
            {
                reader.JumpTo(meshOffsets[i], false);
                ReadMesh(reader, scale);
            }
        }
コード例 #9
0
        public override void Load(Stream fileStream)
        {
            var reader = new GensReader(fileStream);

            Header = new GensHeader(reader);

            // Root Node
            uint entryCount    = reader.ReadUInt32();
            uint entriesOffset = reader.ReadUInt32();

            // AR Entry Offsets
            var entryOffsets = new uint[entryCount];

            reader.JumpTo(entriesOffset, false);

            for (uint i = 0; i < entryCount; ++i)
            {
                entryOffsets[i] = reader.ReadUInt32();
            }

            // AR Entries
            for (uint i = 0; i < entryCount; ++i)
            {
                reader.JumpTo(entryOffsets[i], false);

                uint nameOffset = reader.ReadUInt32();
                uint offset     = reader.ReadUInt32();
                uint size       = reader.ReadUInt32();

                reader.JumpTo(nameOffset, false);
                Entries.Add(new AREntry()
                {
                    PFDOffset = offset,
                    Size      = size,
                    Name      = reader.ReadNullTerminatedString()
                });
            }
        }
コード例 #10
0
        protected void ReadMesh(GensReader reader, float scale = 1)
        {
            // SubMesh Slots
            uint curPos = (uint)reader.BaseStream.Position;

            for (int i = 0; i < SubMeshSlotCount;)
            {
                uint subMeshCount         = reader.ReadUInt32();
                uint subMeshOffsetsOffset = reader.ReadUInt32();

                // TODO: Add support for water SubMesh
                if (i == SubMeshSlotCount - 1)
                {
                    break;
                }

                // SubMesh Offsets
                var subMeshOffsets = new uint[subMeshCount];
                reader.JumpTo(subMeshOffsetsOffset, false);

                for (uint i2 = 0; i2 < subMeshCount; ++i2)
                {
                    subMeshOffsets[i2] = reader.ReadUInt32();
                }

                // SubMeshes
                for (uint i2 = 0; i2 < subMeshCount; ++i2)
                {
                    reader.JumpTo(subMeshOffsets[i2], false);
                    var m = ReadSubMesh(reader, scale);
                    m.Slot = (Mesh.Slots)i;
                }

                reader.JumpTo(curPos + (++i * 8));
            }
        }
コード例 #11
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new GensReader(fileStream);

            Header = new GensHeader(reader);

            // Root Node
            uint groupCount         = reader.ReadUInt32();
            uint groupOffsetsOffset = reader.ReadUInt32();

            GroupEntries = new TerrainGroupEntry[groupCount];

            // Group Offsets
            var groupOffsets = new uint[groupCount];

            reader.JumpTo(groupOffsetsOffset, false);

            for (uint i = 0; i < groupCount; ++i)
            {
                groupOffsets[i] = reader.ReadUInt32();
            }

            // Groups
            for (uint i = 0; i < groupCount; ++i)
            {
                var group = new TerrainGroupEntry();
                reader.JumpTo(groupOffsets[i], false);

                // Entry
                uint centerPosOffset = reader.ReadUInt32();
                uint fileNameOffset  = reader.ReadUInt32();
                group.UncompressedGroupSize = reader.ReadUInt32();
                uint sphereCount         = reader.ReadUInt32();
                uint sphereOffsetsOffset = reader.ReadUInt32();
                group.SubsetID = reader.ReadUInt32();

                // Center position
                reader.JumpTo(centerPosOffset, false);
                group.CenterPosition = reader.ReadVector3();
                group.CenterRadius   = reader.ReadSingle();

                // FileName
                reader.JumpTo(fileNameOffset, false);
                group.FileName = reader.ReadNullTerminatedString();

                // Sphere Offsets
                var sphereOffsets = new uint[sphereCount];
                reader.JumpTo(sphereOffsetsOffset, false);

                for (uint i2 = 0; i2 < sphereCount; ++i2)
                {
                    sphereOffsets[i2] = reader.ReadUInt32();
                }

                // Spheres
                var spheres = new TerrainSphere[sphereCount];
                for (uint i2 = 0; i2 < sphereCount; ++i2)
                {
                    reader.JumpTo(sphereOffsets[i2], false);
                    spheres[i2] = new TerrainSphere()
                    {
                        Center       = reader.ReadVector3(),
                        CenterRadius = reader.ReadSingle()
                    };
                }

                group.Spheres   = spheres;
                GroupEntries[i] = group;
            }
        }
コード例 #12
0
        protected virtual string Read(Stream fileStream,
                                      bool readAdditionalString = false)
        {
            // Header
            var reader = new GensReader(fileStream);

            Header.Read(reader);

            uint metaDataOffset    = reader.ReadUInt32();
            uint metaAnimsSize     = reader.ReadUInt32();
            uint keyframesOffset   = reader.ReadUInt32();
            uint keyframesSize     = reader.ReadUInt32();
            uint stringTableOffset = reader.ReadUInt32();
            uint stringTableSize   = reader.ReadUInt32();

            // MetaData
            reader.JumpTo(metaDataOffset, false);
            uint materialNameOffset     = reader.ReadUInt32();
            uint additionalStringOffset = (readAdditionalString) ?
                                          reader.ReadUInt32() : 0;

            uint animCount   = reader.ReadUInt32();
            var  animOffsets = new uint[animCount];

            for (uint i = 0; i < animCount; ++i)
            {
                animOffsets[i] = reader.ReadUInt32();
            }

            // Animations
            for (uint i = 0; i < animCount; ++i)
            {
                reader.JumpTo(animOffsets[i], false);
                Animations.Add(new Animation(reader));
            }

            // Keyframes
            foreach (var anim in Animations)
            {
                foreach (var set in anim.KeyframeSets)
                {
                    set.ReadKeyframes(reader, keyframesOffset);
                }
            }

            // String Table
            name = ReadString(materialNameOffset);
            string additionalString = (readAdditionalString) ?
                                      ReadString(additionalStringOffset) : null;

            foreach (var anim in Animations)
            {
                anim.BlendType = ReadString(anim.BlendTypeOffset);
            }

            return(additionalString);

            // Sub-Methods
            string ReadString(uint off)
            {
                reader.JumpTo(stringTableOffset + off, false);
                return(reader.ReadNullTerminatedString());
            }
        }
コード例 #13
0
        protected unsafe Mesh ReadSubMesh(GensReader reader, float scale = 1)
        {
            uint offset; // Generic uint reused for different data

            // Offsets
            uint materialNameOffset, faceCount, faceOffset, vertexCount,
                 vertexSize, vertexOffset, vertexFormatOffset, boneCount,
                 boneOffset, textureUnitCount, textureUnitOffsetsOffset;

            if (Header.RootNodeType == PS3RootType)
            {
                uint unknownOffset1 = reader.ReadUInt32(); // VertexFormat?
                materialNameOffset       = reader.ReadUInt32();
                boneCount                = reader.ReadUInt32();
                boneOffset               = reader.ReadUInt32(); // ?
                textureUnitCount         = reader.ReadUInt32();
                textureUnitOffsetsOffset = reader.ReadUInt32();

                // Possibly vertex format?
                reader.JumpTo(unknownOffset1, false);
                int unknown1 = reader.ReadInt32();
                int unknown2 = reader.ReadInt32();
                int unknown3 = reader.ReadInt32();
                int unknown4 = reader.ReadInt32();

                uint unknownOffset2 = reader.ReadUInt32();
                uint unknownCount1  = reader.ReadUInt32();
                vertexOffset = reader.ReadUInt32();

                // TODO
                throw new NotImplementedException(
                          "ERROR: Cannot yet read PS3 terrain-models");
            }
            else
            {
                materialNameOffset       = reader.ReadUInt32();
                faceCount                = reader.ReadUInt32();
                faceOffset               = reader.ReadUInt32();
                vertexCount              = reader.ReadUInt32();
                vertexSize               = reader.ReadUInt32();
                vertexOffset             = reader.ReadUInt32();
                vertexFormatOffset       = reader.ReadUInt32();
                boneCount                = reader.ReadUInt32();
                boneOffset               = reader.ReadUInt32();
                textureUnitCount         = reader.ReadUInt32();
                textureUnitOffsetsOffset = reader.ReadUInt32();
            }

            // Faces
            var faces = new ushort[faceCount];

            reader.JumpTo(faceOffset, false);

            // Convert faces from triangle strips
            // Basically taken from LibGens because I honestly
            // don't think there's another way to do it lol
            int    newStrip = 3, newIndex = 0;
            ushort face1 = 0, face2 = 0, face3 = 0, t;
            uint   count = 0, faceIndex = 0;

            // HACK: We go through the whole loop twice, the first time just
            // to get the new faceCount, second time to actually get the faces.
            // This way we don't have to do any copying (yes, lists do it too)
            // which is a huge performance improvement.
            for (uint i = 0; i < faceCount; ++i)
            {
                t        = reader.ReadUInt16();
                faces[i] = t;

                if (t == 0xFFFF)
                {
                    newStrip = 3;
                    newIndex = 0;
                }
                else
                {
                    newStrip -= 1;
                    face3     = face2;
                    face2     = face1;
                    face1     = t;

                    if (newStrip == 0)
                    {
                        if ((face1 != face2) && (face2 != face3) && (face1 != face3))
                        {
                            count += 3;
                        }

                        newStrip = 1;
                        ++newIndex;
                    }
                }
            }

            // Alright, we've got the new count!
            // Time to actually get the faces.
            var newFaces = new uint[count];

            newStrip = 3; newIndex = 0;
            face1    = face2 = face3 = 0;

            for (uint i = 0; i < faceCount; ++i)
            {
                t = faces[i];
                if (t == 0xFFFF)
                {
                    newStrip = 3;
                    newIndex = 0;
                }
                else
                {
                    newStrip -= 1;
                    face3     = face2;
                    face2     = face1;
                    face1     = t;

                    if (newStrip == 0)
                    {
                        if ((face1 != face2) && (face2 != face3) && (face1 != face3))
                        {
                            if ((newIndex % 2) == 0)
                            {
                                newFaces[faceIndex]   = face1;
                                newFaces[++faceIndex] = face2;
                                newFaces[++faceIndex] = face3;
                            }
                            else
                            {
                                newFaces[faceIndex]   = face3;
                                newFaces[++faceIndex] = face2;
                                newFaces[++faceIndex] = face1;
                            }

                            ++faceIndex;
                        }

                        newStrip = 1;
                        ++newIndex;
                    }
                }
            }

            // Vertex Format
            var vertexFormat = new List <VertexFormatElement>();
            var fs           = reader.BaseStream;

            reader.JumpTo(vertexFormatOffset, false);

            for (byte i = 0; i < 0xFF; ++i)
            {
                offset = reader.ReadUInt32();
                if (offset > 1000)
                {
                    break;
                }

                var element = new VertexFormatElement()
                {
                    Offset = offset,
                    Type   = reader.ReadUInt32(),
                    ID     = reader.ReadUInt16(),
                    Index  = reader.ReadByte()
                };

                vertexFormat.Add(element);
                fs.ReadByte();
            }

            // Vertices
            var data = new float[vertexCount * Mesh.StructureLength];
            var idc  = new float[vertexCount * 4]; // TODO: Care

            // HACK: Read this stuff using pointers to avoid boundry checks.
            fixed(float *dataStart = data)
            fixed(float *idcp = idc)
            {
                float *dp; // Pointer to data
                uint   structStart;

                for (uint i = 0; i < vertexCount; ++i)
                {
                    // Set default vertex coloring
                    structStart = (i * Mesh.StructureLength);
                    dp          = dataStart + structStart + Mesh.ColorPos;

                    // RGBA = 1, 1, 1, 1
                    *dp = 1; *++dp = 1;
                    *++dp = 1; *++dp = 1;

                    // Just to be accurate
                    offset = (vertexOffset + (i * vertexSize));
                    foreach (var element in vertexFormat)
                    {
                        reader.JumpTo(offset + element.Offset, false);
                        switch (element.ID)
                        {
                        // Vertex Positions
                        case 0:
                            element.Read(reader, dataStart +
                                         structStart + Mesh.VertPos, scale);
                            break;

                        // Bone Weights
                        case 1:
                            // TODO
                            element.Read(reader, idcp);
                            break;

                        // Bone Indices
                        case 2:
                            // TODO
                            element.Read(reader, idcp);
                            break;

                        // Normals
                        case 3:
                            // TODO: Do I need to scale normals?
                            element.Read(reader, dataStart +
                                         structStart + Mesh.NormPos);
                            break;

                        // UV Coordinates
                        case 5:
                            if (element.Index < 1)
                            {
                                element.Read(reader, dataStart +
                                             structStart + Mesh.UVPos);
                            }
                            else
                            {
                                // TODO: Read multi-UV Channels
                                element.Read(reader, idcp);
                            }
                            break;

                        // Tangents
                        case 6:
                            // TODO
                            element.Read(reader, idcp);
                            break;

                        // Binormals
                        case 7:
                            // TODO
                            element.Read(reader, idcp);
                            break;

                        // Vertex Colors
                        case 10:
                            element.Read(reader, dataStart +
                                         structStart + Mesh.ColorPos);
                            break;
                        }
                    }

                    ++dp;
                }
            }

            // Bones
            reader.JumpTo(boneOffset, false);
            var bones = reader.ReadBytes((int)boneCount);

            // Texture Unit Offsets
            var textureUnitOffsets = new uint[textureUnitCount];

            reader.JumpTo(textureUnitOffsetsOffset, false);

            for (uint i = 0; i < textureUnitCount; ++i)
            {
                textureUnitOffsets[i] = reader.ReadUInt32();
            }

            // Texture Units
            for (uint i = 0; i < textureUnitCount; ++i)
            {
                // TODO: Actually use this data
                reader.JumpTo(textureUnitOffsets[i], false);
                uint textureUnitNameOffset = reader.ReadUInt32();
                uint textureUnitID         = reader.ReadUInt32();

                // Texture Unit Name
                reader.JumpTo(textureUnitNameOffset, false);
                string textureUnitName = reader.ReadNullTerminatedString();
            }

            // Material Name
            reader.JumpTo(materialNameOffset, false);
            string materialName = reader.ReadNullTerminatedString();

            // Generate a HedgeLib mesh and add it to the array
            var mesh = new Mesh()
            {
                VertexData   = data,
                Triangles    = newFaces,
                MaterialName = materialName
            };

            Meshes.Add(mesh);
            return(mesh);
        }
コード例 #14
0
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new GensReader(fileStream);

            Header = reader.ReadHeader();

            // Root Node
            uint shaderOffset    = reader.ReadUInt32();
            uint subShaderOffset = reader.ReadUInt32();
            uint texsetOffset    = reader.ReadUInt32();
            uint texturesOffset  = reader.ReadUInt32();

            MaterialFlag      = reader.ReadByte(); // ?
            NoBackFaceCulling = reader.ReadBoolean();
            AdditiveBlending  = reader.ReadBoolean();
            UnknownFlag1      = reader.ReadByte();

            byte paramCount   = reader.ReadByte();
            byte padding1     = reader.ReadByte();
            byte unknownFlag2 = reader.ReadByte(); // Might be an enum, might just be a boolean?
            byte textureCount = reader.ReadByte();

            uint paramsOffset = reader.ReadUInt32();
            uint padding2     = reader.ReadUInt32();
            uint unknown1     = reader.ReadUInt32();

            // Padding/Unknown Value Checks
            if (padding1 != 0)
            {
                Console.WriteLine($"WARNING: Material Padding1 != 0 ({padding1})");
            }

            if (unknownFlag2 > 1)
            {
                Console.WriteLine($"WARNING: Material UnknownFlag2 > 1 ({unknownFlag2})");
            }

            if (padding2 != 0)
            {
                Console.WriteLine($"WARNING: Material Padding2 != 0 ({padding2})");
            }

            // Shader Name
            reader.JumpTo(shaderOffset, false);
            ShaderName = reader.ReadNullTerminatedString();

            // Sub-Shader Name
            reader.JumpTo(subShaderOffset, false);
            SubShaderName = reader.ReadNullTerminatedString();

            // Parameter Offsets
            var paramOffsets = new uint[paramCount];

            reader.JumpTo(paramsOffset, false);

            for (uint i = 0; i < paramCount; ++i)
            {
                paramOffsets[i] = reader.ReadUInt32();
            }

            // Parameters
            parameters.Clear();
            for (uint i = 0; i < paramCount; ++i)
            {
                reader.JumpTo(paramOffsets[i], false);
                var param = new Parameter()
                {
                    ParamFlag1 = reader.ReadUInt16(),
                    ParamFlag2 = reader.ReadUInt16()
                };

                uint paramNameOffset  = reader.ReadUInt32();
                uint paramValueOffset = reader.ReadUInt32();

                // Parameter Name
                reader.JumpTo(paramNameOffset, false);
                param.Name = reader.ReadNullTerminatedString();

                // Parameter Value
                reader.JumpTo(paramValueOffset, false);
                param.Value = reader.ReadVector4();

                parameters.Add(param);
            }

            // Texset
            reader.JumpTo(texsetOffset, false);
            if (Header.RootNodeType == 1) // TODO: Maybe check for textureCount < 1 instead?
            {
                TexsetName = reader.ReadNullTerminatedString();
            }
            else
            {
                Texset.Read(reader, textureCount);

                // Texture Offsets
                var texOffsets = new uint[textureCount];
                reader.JumpTo(texturesOffset, false);

                for (uint i = 0; i < textureCount; ++i)
                {
                    texOffsets[i] = reader.ReadUInt32();
                }

                // Textures
                for (int i = 0; i < textureCount; ++i)
                {
                    reader.JumpTo(texOffsets[i], false);
                    Texset.Textures[i].Read(reader);
                }
            }
        }