Пример #1
0
            private TreeNode SetWrapperNode(Node Node, TreeNode parentNode)
            {
                if (Node.IsMesh)
                {
                    List <TreeNode> MeshNodes = new List <TreeNode>();
                    int             i         = 0;
                    foreach (SubMesh subMesh in Node.SubMeshes)
                    {
                        GenericRenderedObject subMeshNode = new GenericRenderedObject();
                        subMeshNode.ImageKey         = "mesh";
                        subMeshNode.SelectedImageKey = "mesh";
                        subMeshNode.Checked          = true;
                        subMeshNode.Text             = $"{Node.Name} {i}";

                        subMeshNode.lodMeshes = new List <GenericRenderedObject.LOD_Mesh>();
                        var submsh = new GenericRenderedObject.LOD_Mesh();
                        submsh.PrimativeType = STPrimitiveType.Triangles;
                        submsh.FirstVertex   = 0;
                        submsh.faces         = subMesh.Faces;
                        subMeshNode.lodMeshes.Add(submsh);

                        subMeshNode.vertices = subMesh.Vertices;

                        //Check duplicate models being rendered
                        if (!AddedMeshes.Contains(subMesh))
                        {
                            DrawableRenderer.Meshes.Add(subMeshNode);
                        }

                        AddedMeshes.Add(subMesh);

                        if (i == 0)
                        {
                            parentNode.Nodes.Add(subMeshNode);
                        }
                        else
                        {
                            parentNode.Nodes[0].Nodes.Add(subMeshNode);
                        }

                        MeshNodes.Add(subMeshNode);
                        i++;
                    }

                    var FirstNode = MeshNodes[0];
                    MeshNodes.Clear();

                    return(FirstNode);
                }
                else
                {
                    var NewNode = new TreeNode(Node.Name);
                    parentNode.Nodes.Add(NewNode);
                    return(NewNode);
                }
            }
Пример #2
0
        private void ToGenericMeshes(bool isBigEndian)
        {
            foreach (SubMeshInfo meshInfo in SubMeshInfos)
            {
                GenericRenderedObject genericMesh = new GenericRenderedObject();
                genericMesh.Text = $"Mesh_{GenericMeshes.Count}";
                GenericMeshes.Add(genericMesh);

                STGenericPolygonGroup polyGroup = new STGenericPolygonGroup();
                genericMesh.PolygonGroups.Add(polyGroup);

                var mat = Materials[(int)meshInfo.TextureID];
                mat.Text = $"Material_{meshInfo.TextureID}";
                mat.Diffuse.TextureIndex = mat.TextureIndices[0][0];
                polyGroup.Material       = mat;

                Console.WriteLine($"TextureID {meshInfo.TextureID}");
                Console.WriteLine($"MaterialID {meshInfo.MaterialID}");

                //Set face type
                if (meshInfo.IndexBufferFormat == 3)
                {
                    polyGroup.PrimativeType = STPrimitiveType.Triangles;
                }
                else if (meshInfo.IndexBufferFormat == 4)
                {
                    polyGroup.PrimativeType = STPrimitiveType.TrangleStrips;
                }

                //Get faces
                var buffer  = IndexBuffers[(int)meshInfo.IndexBufferID];
                var indcies = buffer.GetIndices(isBigEndian,
                                                meshInfo.IndexBufferOffset,
                                                meshInfo.IndexBufferCount).ToArray();

                for (int f = 0; f < indcies.Length; f++)
                {
                    polyGroup.faces.Add((int)indcies[f]);
                }

                //Get vertices
                genericMesh.vertices.AddRange(GetVertices((int)meshInfo.VertexBufferID,
                                                          (int)meshInfo.IndexIntoJointMap, meshInfo.VertexBufferOffset, isBigEndian));
            }
        }
Пример #3
0
        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;
                    }
                }
            }
        }
Пример #4
0
        public void Load(System.IO.Stream stream)
        {
            CanSave = true;

            //Set renderer
            Renderer = new GMX_Renderer();
            DrawableContainer.Name = FileName;
            DrawableContainer.Drawables.Add(Renderer);

            //Read file
            GMXHeader = new Header();
            GMXHeader.Read(new FileReader(stream));

            int MeshIndex = 0;

            for (int i = 0; i < GMXHeader.Meshes.Count; i++)
            {
                var renderedMesh = new GenericRenderedObject();
                renderedMesh.ImageKey         = "mesh";
                renderedMesh.SelectedImageKey = "mesh";
                renderedMesh.Checked          = true;

                if (GMXHeader.Meshes[i].VertexGroup != null)
                {
                    renderedMesh.vertices = GMXHeader.Meshes[i].VertexGroup.Vertices;
                }

                if (GMXHeader.Meshes[i].IndexGroup != null)
                {
                    renderedMesh.lodMeshes = new List <STGenericObject.LOD_Mesh>();
                    var msh = new STGenericObject.LOD_Mesh();
                    msh.PrimitiveType = STPolygonType.Triangle;
                    msh.FirstVertex   = 0;

                    /*  int VertexID = 0;
                     * for (int f = 0; f < GMXHeader.Meshes[i].VertexCount; f+= 3)
                     * {
                     *    msh.faces.AddRange(new List<int>() { VertexID + 2, VertexID + 1, VertexID });
                     *    VertexID++;
                     * }*/

                    for (int f = 0; f < GMXHeader.Meshes[i].IndexGroup.Indices.Length; f++)
                    {
                        msh.faces.AddRange(new int[3]
                        {
                            GMXHeader.Meshes[i].IndexGroup.Indices[f++],
                            GMXHeader.Meshes[i].IndexGroup.Indices[f++],
                            GMXHeader.Meshes[i].IndexGroup.Indices[f]
                        });
                    }

                    renderedMesh.lodMeshes.Add(msh);
                }

                renderedMesh.Tag = GMXHeader.Meshes[i];

                if (GMXHeader.Meshes[i].VertexGroup != null)
                {
                    renderedMesh.Text = $"Mesh ({MeshIndex++})";
                    Nodes.Add(renderedMesh);
                    Renderer.Meshes.Add(renderedMesh);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Computes mesh and bone cloth drivers
        /// </summary>
        public void ComputeClothDrivers()
        {
            var boneList = G1MSkeleton.GenericSkeleton.bones;

            var  nunProps   = new List <NUNO.NUNOType0303Struct>();
            uint nunoOffset = 0;

            if (NUNO != null)
            {
                nunoOffset = (uint)NUNO.NUNO0303StructList.Count;
                foreach (var nuno0303 in NUNO.NUNO0303StructList)
                {
                    nunProps.Add(nuno0303);
                }
            }
            if (NUNV != null)
            {
                foreach (var nuno0303 in NUNV.NUNV0303StructList)
                {
                    nunProps.Add(nuno0303);
                }
            }

            foreach (var prop in nunProps)
            {
                int boneStart  = boneList.Count;
                var parentBone = Model.JointInfos[prop.BoneParentID - 1].JointIndices[0];

                GenericRenderedObject mesh = new GenericRenderedObject();
                mesh.Text    = $"driver_{boneList.Count}";
                mesh.Checked = true;
                Renderer.Meshes.Add(mesh);
                meshNode.Nodes.Add(mesh);

                var polyGroup = new STGenericPolygonGroup();
                polyGroup.Material      = new STGenericMaterial();
                polyGroup.Material.Text = "driver_cloth";
                polyGroup.PrimativeType = STPrimitiveType.Triangles;
                mesh.PolygonGroups.Add(polyGroup);

                for (int p = 0; p < prop.Points.Length; p++)
                {
                    var point = prop.Points[p];
                    var link  = prop.Influences[p];

                    STBone b = new STBone(G1MSkeleton.GenericSkeleton);
                    b.Text = $"CP_{boneList.Count}";
                    b.FromTransform(OpenTK.Matrix4.Identity);
                    b.Position    = point.Xyz;
                    b.parentIndex = link.P3;
                    if (b.parentIndex == -1)
                    {
                        b.parentIndex = (int)parentBone;
                    }
                    else
                    {
                        b.parentIndex += boneStart;
                        b.Position     = OpenTK.Vector3.TransformPosition(
                            point.Xyz, G1MSkeleton.GenericSkeleton.GetBoneTransform((int)parentBone) *
                            G1MSkeleton.GenericSkeleton.GetBoneTransform(b.parentIndex).Inverted());
                    }

                    boneList.Add(b);

                    G1MSkeleton.GenericSkeleton.reset();
                    G1MSkeleton.GenericSkeleton.update();

                    mesh.vertices.Add(new Vertex()
                    {
                        pos = Vector3.TransformPosition(Vector3.Zero,
                                                        G1MSkeleton.GenericSkeleton.GetBoneTransform(boneList.Count - 1)),
                        boneWeights = new List <float>()
                        {
                            1
                        },
                        boneIds = new List <int>()
                        {
                            boneList.Count - 1
                        },
                    });

                    if (link.P1 > 0 && link.P3 > 0)
                    {
                        polyGroup.faces.Add(p);
                        polyGroup.faces.Add(link.P1);
                        polyGroup.faces.Add(link.P3);
                    }
                    if (link.P2 > 0 && link.P4 > 0)
                    {
                        polyGroup.faces.Add(p);
                        polyGroup.faces.Add(link.P2);
                        polyGroup.faces.Add(link.P4);
                    }
                }

                mesh.CalculateNormals();
            }
        }
Пример #6
0
        private void ReadMeshChunk(FileReader reader)
        {
            int meshCount = reader.ReadInt32();

            SkipPadding(reader, 0x20);

            for (int mIdx = 0; mIdx < meshCount; mIdx++)
            {
                //Create a renderable object for our mesh
                var renderedMesh = new GenericRenderedObject
                {
                    Checked          = true,
                    ImageKey         = "mesh",
                    SelectedImageKey = "mesh",
                    Text             = $"Mesh {mIdx}"
                };
                Nodes.Add(renderedMesh);
                Renderer.Meshes.Add(renderedMesh);

                STGenericPolygonGroup polyGroup = new STGenericPolygonGroup();
                renderedMesh.PolygonGroups.Add(polyGroup);

                renderedMesh.BoneIndex = reader.ReadInt32();

                int vtxDescriptor = reader.ReadInt32();
                int mtxGroupCount = reader.ReadInt32();
                for (int mgIdx = 0; mgIdx < mtxGroupCount; mgIdx++)
                {
                    int dependencyCount = reader.ReadInt32();
                    for (int ll = 0; ll < dependencyCount; ll++)
                    {
                        reader.ReadInt16();
                    }

                    int dListCount = reader.ReadInt32();
                    for (int dlIdx = 0; dlIdx < dListCount; dlIdx++)
                    {
                        int flags    = reader.ReadInt32();
                        int unk1     = reader.ReadInt32();
                        int dataSize = reader.ReadInt32();
                        SkipPadding(reader, 0x20);
                        long endPosition = reader.Position + dataSize;
                        while (reader.Position < endPosition)
                        {
                            byte faceType = reader.ReadByte();
                            if (faceType == 0x98 || faceType == 0xA0)
                            {
                                short faceCount = reader.ReadInt16();
                                int[] polygons  = new int[faceCount];

                                for (int fIdx = 0; fIdx < faceCount; fIdx++)
                                {
                                    if ((vtxDescriptor & 1) == 1)
                                    {
                                        reader.ReadByte(); // posmat index
                                    }
                                    if ((vtxDescriptor & 2) == 2)
                                    {
                                        reader.ReadByte(); // tex1 index
                                    }
                                    ushort vtxIdx = reader.ReadUInt16();

                                    ushort nrmIdx = 0;
                                    if (VertexNormals.Length > 0)
                                    {
                                        nrmIdx = reader.ReadUInt16();
                                    }

                                    ushort colIdx = 0;
                                    if ((vtxDescriptor & 4) == 4)
                                    {
                                        colIdx = reader.ReadUInt16();
                                    }

                                    int txCoordIdx        = 0;
                                    int txCoordDescriptor = vtxDescriptor >> 3;
                                    for (int tcoordIdx = 0; tcoordIdx < 8; tcoordIdx++)
                                    {
                                        if ((txCoordDescriptor & 1) == 0x1)
                                        {
                                            // Only read for the first texcoord
                                            txCoordIdx          = reader.ReadInt16();
                                            txCoordDescriptor >>= 1;
                                        }
                                    }

                                    Vertex newVertex = new Vertex
                                    {
                                        pos = Vertices[vtxIdx]
                                    };

                                    int envIdx = 0;
                                    if (Envelopes.Length > envIdx)
                                    {
                                        for (int i = 0; i < Envelopes[envIdx].Indices?.Length; i++)
                                        {
                                            newVertex.boneIds.Add(Envelopes[envIdx].Indices[i]);
                                            newVertex.boneWeights.Add(Envelopes[envIdx].Weights[i]);
                                        }
                                    }

                                    if (VertexNormals != null)
                                    {
                                        newVertex.nrm = VertexNormals[nrmIdx];
                                    }
                                    if (Colors != null)
                                    {
                                        newVertex.col = Colors[colIdx];
                                    }

                                    polygons[fIdx] = renderedMesh.vertices.Count;
                                    renderedMesh.vertices.Add(newVertex);
                                }

                                List <Triangle> currentPolygons = ToTris(polygons, faceType);

                                Console.WriteLine($"faceType {faceType} polygons {polygons.Length} ");
                                foreach (Triangle triangle in currentPolygons)
                                {
                                    if (faceType == 0x98)
                                    {
                                        polyGroup.faces.Add(triangle.B);
                                        polyGroup.faces.Add(triangle.C);
                                        polyGroup.faces.Add(triangle.A);
                                    }
                                    else
                                    {
                                        polyGroup.faces.Add(triangle.C);
                                        polyGroup.faces.Add(triangle.B);
                                        polyGroup.faces.Add(triangle.A);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #7
0
        public void Load(System.IO.Stream stream)
        {
            fileSize = stream.Length;
            using (var reader = new FileReader(stream))
            {
                pmdlCount = 0;
                ptexCount = 0;
                ptexList.Clear();
                ddsList.Clear();
                // Read header for data locations
                files.Clear();
                reader.Position  = 4;
                reader.ByteOrder = byteOrder;
                if (reader.ReadUInt32() != 2001)
                {
                    byteOrder = ByteOrder.BigEndian;
                }
                reader.ByteOrder            = byteOrder;
                reader.Position             = 0;
                header.version              = reader.ReadUInt32(4);
                reader.Position            += 4;
                header.flag1                = reader.ReadUInt16();
                header.flag2                = reader.ReadUInt16();
                header.dataInfoCount        = reader.ReadUInt32();
                header.dataInfoSize         = reader.ReadUInt32();
                header.tagCount             = reader.ReadUInt32();
                header.tagSize              = reader.ReadUInt32();
                header.relocationDataOffset = reader.ReadUInt32();
                header.relocationDataSize   = reader.ReadInt32();
                reader.Position            += 92;
                // Create arrays for multiple data and tag info objects
                DataInfo[] dataInfos = new DataInfo[header.dataInfoCount];
                TagInfo[]  tagInfos  = new TagInfo[header.tagCount];

                for (int i = 0; i < header.dataInfoCount; i++)
                {
                    // Create and assign properties to a new DataInfo until the count specified in the header is reached
                    dataInfos[i] = new DataInfo()
                    {
                        unknown1   = reader.ReadUInt32(),
                        textOffset = reader.ReadUInt32(),
                        unknown2   = reader.ReadUInt32(),
                        unknown3   = reader.ReadUInt32(),
                        dataSize   = reader.ReadInt32(),
                        dataSize2  = reader.ReadUInt32(),
                        dataOffset = reader.ReadInt32(),
                        unknown4   = reader.ReadUInt32(),
                        zero1      = reader.ReadUInt32(),
                        zero2      = reader.ReadUInt32(),
                        zero3      = reader.ReadUInt32(),
                        zero4      = reader.ReadUInt32()
                    };
                }
                saveData = dataInfos;

                for (int i = 0; i < header.tagCount; i++)
                {
                    // Get tags for file extensions, data, and names
                    tagInfos[i] = new TagInfo()
                    {
                        magic      = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(4)),
                        dataOffset = reader.ReadInt32(),
                        flag       = reader.ReadUInt32(),
                        textOffset = reader.ReadInt32(),
                        name       = "default"
                    };
                }


                // Get extra data, currently unused except for saving the file
                if (header.dataInfoCount > 2)
                {
                    reader.Position = dataInfos[2].dataOffset;
                    extraData       = reader.ReadBytes(dataInfos[2].dataSize);
                }

                // Get relocation data and write to byte array
                reader.Position = header.relocationDataOffset;
                relocationData  = reader.ReadBytes(header.relocationDataSize);

                // Compile filenames and add as files
                for (long i = 0; i < header.tagCount - 1; i++)
                {
                    reader.Position = dataInfos[0].dataOffset + tagInfos[i].textOffset;
                    string filename = reader.ReadZeroTerminatedString();
                    tagInfos[i].name = filename;
                    saveTag          = tagInfos;
                    if (!tagInfos[i].magic.StartsWith("\0"))
                    {
                        filename = filename + "." + tagInfos[i].magic.ToLower();
                    }
                    reader.Position = dataInfos[1].dataOffset + tagInfos[i].dataOffset;
                    FileEntry file = new FileEntry()
                    {
                        FileName = filename,
                        FileData = reader.ReadBytes(tagInfos[i + 1].dataOffset - tagInfos[i].dataOffset)
                    };
                    reader.Position = dataInfos[1].dataOffset + tagInfos[i].dataOffset;

                    // Load textures as a dds using the PTEX pointer
                    if (tagInfos[i].magic == "PTEX")
                    {
                        reader.Position += 88;
                        Ptex ptex = new Ptex()
                        {
                            ptexOffset = reader.Position,
                            width      = reader.ReadUInt32(),
                            height     = reader.ReadUInt32(),
                            unknown    = reader.ReadUInt32(),
                            ddsOffset  = reader.ReadUInt32(),
                            ddsSize    = reader.ReadInt32()
                        };
                        reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                        reader.Position += ptex.ddsOffset;
                        DDS dds = new DDS(reader.ReadBytes(ptex.ddsSize))
                        {
                            WiiUSwizzle = false,
                            FileType    = FileType.Image,
                            Text        = filename + ".dds",
                            FileName    = filename,
                            CanReplace  = true
                        };
                        reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                        reader.Position += ptex.ddsOffset;
                        ptexList.Add(ptex);
                        Nodes.Add(dds);
                        ddsList.Add(dds);
                        FileType = FileType.Image;
                        ptexCount++;
                    }

                    if (tagInfos[i].magic == "PMDL")
                    {
                        reader.Position += 8;
                        Pmdl pmdl = new Pmdl()
                        {
                            relocationDataCount = reader.ReadInt16(),
                            pmdlSize            = reader.ReadInt16()
                        };
                        reader.Position             += 4;
                        pmdl.modelTextOffset         = reader.ReadInt32();
                        reader.Position             += 36;
                        pmdl.sumVertCount            = reader.ReadInt32();
                        pmdl.faceStartOffsetRelative = reader.ReadInt32();
                        pmdl.vertexStartOffset       = reader.ReadInt32();
                        reader.Position             += 4;
                        pmdl.sumFaceCount            = reader.ReadInt32();
                        pmdl.faceStartOffset         = reader.ReadInt32();
                        reader.Position             += 48;
                        pmdl.subInfoCount            = reader.ReadInt32();
                        pmdl.offsetToSubInfosStart   = reader.ReadInt32();
                        pmdl.endOfSubInfos           = reader.ReadInt32();
                        reader.Position              = pmdl.offsetToSubInfosStart + dataInfos[1].dataOffset;
                        int[] subInfoStarts = new int[pmdl.subInfoCount];
                        subInfoStarts = reader.ReadInt32s(pmdl.subInfoCount);
                        SubInfoData[] subInfoDatas = new SubInfoData[pmdl.subInfoCount];
                        for (int t = 0; t < pmdl.subInfoCount; t++)
                        {
                            reader.Position = subInfoStarts[t] + dataInfos[1].dataOffset;
                            SubInfoData subInfoData = new SubInfoData()
                            {
                                unknown1             = reader.ReadInt32(),
                                unknown2             = reader.ReadInt32(),
                                unknown3             = reader.ReadInt32(),
                                unknown4             = reader.ReadInt32(),
                                unknown5             = reader.ReadInt32(),
                                unknown6             = reader.ReadInt32(),
                                vertexCount          = reader.ReadInt32(),
                                unknown8             = reader.ReadInt32(),
                                previousFaceCount    = reader.ReadInt32(),
                                faceCount            = reader.ReadInt32(),
                                unknown11            = reader.ReadInt32(),
                                unknown12            = reader.ReadInt32(),
                                vertexOffsetRelative = reader.ReadInt32(),
                                normalUVOffset       = reader.ReadInt32(),
                                faceOffset           = reader.ReadInt32(),
                                sameSizeorOffset     = reader.ReadInt32(),
                                sameSizeorOffset2    = reader.ReadInt32(),
                                sameSizeorOffset3    = reader.ReadInt32(),
                                sameSizeorOffset4    = reader.ReadInt32(),
                                sameSizeorOffset5    = reader.ReadInt32()
                            };

                            pmdl.verticesCount = subInfoData.vertexCount;
                            pmdl.facesCount    = subInfoData.faceCount;
                            subInfoDatas[t]    = subInfoData;
                        }
                        var renderedMesh = new GenericRenderedObject();
                        var renderer     = new GenericModelRenderer();
                        renderedMesh.ImageKey         = "mesh";
                        renderedMesh.SelectedImageKey = "mesh";
                        renderedMesh.Checked          = true;
                        int[] normalUVSize = new int[pmdl.subInfoCount];
                        if (pmdl.subInfoCount > 1)
                        {
                            int remember = 0;
                            for (int a = 0; a + 1 < pmdl.subInfoCount; a++)
                            {
                                pmdl.normalUVStart = subInfoDatas[a].normalUVOffset;
                                pmdl.normalUVEnd   = subInfoDatas[a + 1].normalUVOffset;
                                normalUVSize[a]    = (int)(pmdl.normalUVEnd - pmdl.normalUVStart);
                                remember           = a;
                            }
                            pmdl.normalUVStart = subInfoDatas[remember + 1].normalUVOffset;
                            pmdl.normalUVEnd   = subInfoDatas[remember + 1].normalUVOffset;
                        }
                        else if (pmdl.subInfoCount >= 1)
                        {
                            for (int x = 0; x < pmdl.subInfoCount; x++)
                            {
                                int stride = (int)(normalUVSize[x] / subInfoDatas[x].vertexCount);
                                reader.Position = pmdl.vertexStartOffset + subInfoDatas[x].vertexOffsetRelative;
                                for (int j = 0; j < subInfoDatas[x].vertexCount; j++)
                                {
                                    Vertex vert = new Vertex();
                                    vert.pos = new OpenTK.Vector3(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                                }
                            }
                        }
                    }
                    files.Add(file);
                }

                // For the last file, read until the end of the raw data section
                TagInfo lastTag = tagInfos[header.tagCount - 1];
                reader.Position = dataInfos[0].dataOffset + lastTag.textOffset;
                string filename2 = reader.ReadZeroTerminatedString();
                tagInfos[header.tagCount - 1].name = filename2;
                saveTag = tagInfos;
                if (!lastTag.magic.StartsWith("\0"))
                {
                    filename2 = filename2 + "." + lastTag.magic.ToLower();
                }
                reader.Position = dataInfos[1].dataOffset + lastTag.dataOffset;
                FileEntry file2 = new FileEntry()
                {
                    FileName = filename2,
                    FileData = reader.ReadBytes(dataInfos[1].dataSize - lastTag.dataOffset)
                };
                if (tagInfos[header.tagCount - 1].magic == "PTEX")
                {
                    reader.Position = dataInfos[1].dataOffset + tagInfos[header.tagCount - 1].dataOffset + 88;
                    Ptex ptex = new Ptex()
                    {
                        ptexOffset = reader.Position,
                        width      = reader.ReadUInt32(),
                        height     = reader.ReadUInt32(),
                        unknown    = reader.ReadUInt32(),
                        ddsOffset  = reader.ReadUInt32(),
                        ddsSize    = reader.ReadInt32()
                    };
                    reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                    reader.Position += ptex.ddsOffset;
                    DDS dds = new DDS(reader.ReadBytes(ptex.ddsSize))
                    {
                        WiiUSwizzle = false,
                        FileType    = FileType.Image,
                        Text        = filename2 + ".dds",
                        FileName    = filename2,
                        CanReplace  = true,
                    };
                    reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                    reader.Position += ptex.ddsOffset;
                    ptexList.Add(ptex);
                    Nodes.Add(dds);
                    ddsList.Add(dds);
                    FileType = FileType.Image;
                    ptexCount++;
                }
                if (tagInfos[0].magic == "enti")
                {
                    reader.Position = dataInfos[1].dataOffset + tagInfos[0].dataOffset;
                    var position     = reader.Position;
                    var entityHeader = new Entity.EntityHeader()
                    {
                        entitiesOffset = reader.ReadUInt32(),
                        entitiesCount  = reader.ReadUInt32(),
                        unknown1       = reader.ReadUInt32(),
                        unknown2       = reader.ReadUInt32()
                    };
                    reader.Position = position + entityHeader.entitiesOffset;
                    var properties = new Entity.Property[entityHeader.entitiesCount];
                    //var entities = new Entity.Entity[entityHeader.entitiesCount];
                    //for (int i = 0; i < entityHeader.entitiesCount; i++)
                    //{
                    //    entities[i].entityNameOffset = reader.ReadUInt32();
                    //    entities[i].propertiesCount = reader.ReadUInt16();
                    //    entities[i].propertiesCount2 = reader.ReadUInt16();
                    //    entities[i].propertiesOffset = reader.ReadUInt32();
                    //    entities[i].matrixOffset = reader.ReadUInt32();
                    //    entities[i].positionOffset = reader.ReadUInt32();
                    //    entities[i].unknown = reader.ReadUInt32();
                    //    entities[i].flag = reader.ReadUInt32();
                    //    entities[i].valuesOffset = reader.ReadUInt32();
                    //}

                    var entities = new Entity.Entity[entityHeader.entitiesCount];


                    for (int i = 0; i < entityHeader.entitiesCount; i++)
                    {
                        reader.Position = position + entities[i].propertiesOffset;
                    }
                }

                files.Add(file2);
            }
        }