Ejemplo n.º 1
0
 private static void DrawModelWireframe(STGenericPolygonGroup p, ShaderProgram shader)
 {
     // use vertex color for wireframe color
     shader.SetInt("colorOverride", 1);
     GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
     GL.Enable(EnableCap.LineSmooth);
     GL.LineWidth(1.5f);
     GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
     GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
     shader.SetInt("colorOverride", 0);
 }
Ejemplo n.º 2
0
        private static void DrawModelSelection(STGenericPolygonGroup p, ShaderProgram shader)
        {
            GL.Uniform1(shader["colorOverride"], 1);
            GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
            GL.Enable(EnableCap.LineSmooth);
            GL.LineWidth(1.3f);
            GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            GL.Uniform1(shader["colorOverride"], 0);

            GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
        }
Ejemplo n.º 3
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));
            }
        }
        private static PrimitiveType GetPrimitiveType(STGenericPolygonGroup p)
        {
            switch (p.PrimativeType)
            {
            case STPrimitiveType.Triangles: return(PrimitiveType.Triangles);

            case STPrimitiveType.TrangleStrips: return(PrimitiveType.TriangleStrip);

            case STPrimitiveType.Quads: return(PrimitiveType.Quads);

            case STPrimitiveType.Points: return(PrimitiveType.Points);

            case STPrimitiveType.LineStrips: return(PrimitiveType.LineStrip);

            case STPrimitiveType.Lines: return(PrimitiveType.Lines);

            default: return(PrimitiveType.Triangles);
            }
        }
Ejemplo n.º 5
0
        public void ReadVertexBuffers()
        {
            Nodes.Clear();

            TreeNode skeletonNode = new TreeNode("Skeleton");

            for (int t = 0; t < Skeleton?.bones.Count; t++)
            {
                if (Skeleton.bones[t].Parent == null)
                {
                    skeletonNode.Nodes.Add(Skeleton.bones[t]);
                }
            }

            if (skeletonNode.Nodes.Count > 0)
            {
                Nodes.Add(skeletonNode);
            }

            using (var reader = new FileReader(DataDictionary.GetFile003Data()))
            {
                for (int i = 0; i < VertexBufferPointers.Count; i++)
                {
                    LM2_Mesh mesh = Meshes[i];

                    RenderableMeshWrapper genericObj = new RenderableMeshWrapper();
                    genericObj.Mesh = mesh;
                    genericObj.Text = $"Mesh {i}";
                    genericObj.SetMaterial(mesh.Material);
                    RenderedMeshes.Add(genericObj);

                    Nodes.Add(genericObj);
                    DataDictionary.Renderer.Meshes.Add(genericObj);

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

                    using (reader.TemporarySeek(BufferStart + VertexBufferPointers[i], System.IO.SeekOrigin.Begin))
                    {
                        var bufferNodeDebug = new DebugVisualBytes(reader.ReadBytes((int)80 * mesh.VertexCount));
                        bufferNodeDebug.Text = $"Buffer {mesh.DataFormat.ToString("x")}";
                        genericObj.Nodes.Add(bufferNodeDebug);
                    }

                    if (!LM2_Mesh.FormatInfos.ContainsKey(mesh.DataFormat))
                    {
                        Console.WriteLine($"Unsupported data format! " + mesh.DataFormat.ToString("x"));
                        continue;
                    }
                    else
                    {
                        var formatInfo = LM2_Mesh.FormatInfos[mesh.DataFormat];
                        if (formatInfo.BufferLength > 0)
                        {
                            reader.BaseStream.Position = BufferStart + mesh.IndexStartOffset;
                            switch (mesh.IndexFormat)
                            {
                            case IndexFormat.Index_8:
                                for (int f = 0; f < mesh.IndexCount; f++)
                                {
                                    polyGroup.faces.Add(reader.ReadByte());
                                }
                                break;

                            case IndexFormat.Index_16:
                                for (int f = 0; f < mesh.IndexCount; f++)
                                {
                                    polyGroup.faces.Add(reader.ReadUInt16());
                                }
                                break;
                            }

                            Console.WriteLine($"Mesh {genericObj.Text} Format {formatInfo.Format} BufferLength {formatInfo.BufferLength}");

                            uint bufferOffet = BufferStart + VertexBufferPointers[i];

                            /*       for (int v = 0; v < mesh.VertexCount; v++)
                             *     {
                             *         reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));
                             *
                             *     }*/

                            switch (formatInfo.Format)
                            {
                            case VertexDataFormat.Float16:
                                for (int v = 0; v < mesh.VertexCount; v++)
                                {
                                    reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                    Vertex vert = new Vertex();
                                    genericObj.vertices.Add(vert);
                                    vert.pos = new Vector3(
                                        UShortToFloatDecode(reader.ReadInt16()),
                                        UShortToFloatDecode(reader.ReadInt16()),
                                        UShortToFloatDecode(reader.ReadInt16()));

                                    Vector4 nrm = Read_8_8_8_8_Snorm(reader);
                                    vert.nrm = nrm.Xyz.Normalized();

                                    vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);
                                    vert.uv0 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());

                                    if (formatInfo.BufferLength == 22)
                                    {
                                        Console.WriteLine("unk 1 " + reader.ReadUInt16());
                                        Console.WriteLine("unk 2 " + reader.ReadUInt16());
                                        Console.WriteLine("unk 3 " + reader.ReadUInt16());
                                        Console.WriteLine("unk 4 " + reader.ReadUInt16());
                                    }
                                }
                                break;

                            case VertexDataFormat.Float32:
                                for (int v = 0; v < mesh.VertexCount; v++)
                                {
                                    reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                    Vertex vert = new Vertex();
                                    genericObj.vertices.Add(vert);

                                    vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                    vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);
                                }
                                break;

                            case VertexDataFormat.Float32_32:
                                reader.BaseStream.Position = BufferStart + VertexBufferPointers[i] + 0x08;
                                for (int v = 0; v < mesh.VertexCount; v++)
                                {
                                    reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                    Vertex vert = new Vertex();
                                    genericObj.vertices.Add(vert);

                                    vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                    vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);
                                    vert.uv0 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());
                                    vert.uv1 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());
                                    vert.col = Read_8_8_8_8_Unorm(reader);
                                }
                                break;

                            case VertexDataFormat.Float32_32_32:
                                for (int v = 0; v < mesh.VertexCount; v++)
                                {
                                    reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                    Vertex vert = new Vertex();
                                    genericObj.vertices.Add(vert);

                                    vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                    vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);
                                    Vector4 nrm = Read_8_8_8_8_Snorm(reader);
                                    vert.nrm = nrm.Xyz.Normalized();
                                    vert.uv0 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());
                                    vert.uv1 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());

                                    if (formatInfo.BufferLength >= 0x1C)
                                    {
                                        vert.col = Read_8_8_8_8_Unorm(reader);
                                    }
                                }
                                break;
                            }

                            genericObj.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1));
                        }
                    }

                    genericObj.RemoveDuplicateVertices();
                }
            }
        }
Ejemplo n.º 6
0
        private void LoadBMD(Model model)
        {
            Nodes.Clear();

            ShapeFolder    = new TreeNode("Shapes");
            SkeletonFolder = new TreeNode("Skeleton");
            MaterialFolder = new TreeNode("Materials");
            TextureFolder  = new BMDTextureFolder("Textures");
            Nodes.Add(ShapeFolder);
            Nodes.Add(MaterialFolder);
            Nodes.Add(SkeletonFolder);
            Nodes.Add(TextureFolder);

            BMDFile = model;

            FillSkeleton(BMDFile.Scenegraph, Skeleton, BMDFile.Joints.FlatSkeleton);

            foreach (var bone in Skeleton.bones)
            {
                if (bone.Parent == null)
                {
                    SkeletonFolder.Nodes.Add(bone);
                }
            }

            for (int i = 0; i < BMDFile.Shapes.Shapes.Count; i++)
            {
                var curShape = BMDFile.Shapes.Shapes[i];

                var mat = new BMDMaterialWrapper(BMDFile.Materials.GetMaterial(i), BMDFile);
                MaterialFolder.Nodes.Add(mat);

                var shpWrapper = new BMDShapeWrapper(curShape, BMDFile, mat);
                shpWrapper.Text = $"Shape {i}";
                ShapeFolder.Nodes.Add(shpWrapper);
                Renderer.Meshes.Add(shpWrapper);

                var polyGroup = new STGenericPolygonGroup();
                shpWrapper.PolygonGroups.Add(polyGroup);

                var VertexAttributes = BMDFile.VertexData.Attributes;

                int vertexID = 0;
                int packetID = 0;

                foreach (var att in curShape.Descriptor.Attributes)
                {
                    shpWrapper.Nodes.Add($"Attribute {att.Key} {att.Value.Item1}");
                }

                foreach (SuperBMDLib.Geometry.Packet pack in curShape.Packets)
                {
                    int primID = 0;
                    foreach (SuperBMDLib.Geometry.Primitive prim in pack.Primitives)
                    {
                        List <SuperBMDLib.Geometry.Vertex> triVertices = J3DUtility.PrimitiveToTriangles(prim);
                        for (int triIndex = 0; triIndex < triVertices.Count; triIndex += 3)
                        {
                            polyGroup.faces.AddRange(new int[] { vertexID + 2, vertexID + 1, vertexID });

                            for (int triVertIndex = 0; triVertIndex < 3; triVertIndex++)
                            {
                                SuperBMDLib.Geometry.Vertex vert = triVertices[triIndex + triVertIndex];

                                Vertex vertex = new Vertex();
                                vertex.pos = VertexAttributes.Positions[(int)vert.GetAttributeIndex(GXVertexAttribute.Position)];
                                shpWrapper.vertices.Add(vertex);

                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Normal))
                                {
                                    vertex.nrm = VertexAttributes.Normals[(int)vert.NormalIndex];
                                }
                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Color0))
                                {
                                    var color0 = VertexAttributes.Color_0[(int)vert.Color0Index];
                                    vertex.col = new OpenTK.Vector4(color0.R, color0.G, color0.B, color0.A);
                                }

                                for (int j = 0; j < vert.VertexWeight.WeightCount; j++)
                                {
                                    vertex.boneWeights.Add(vert.VertexWeight.Weights[j]);
                                    vertex.boneIds.Add(vert.VertexWeight.BoneIndices[j]);
                                }

                                if (vert.VertexWeight.WeightCount == 1)
                                {
                                    if (BMDFile.SkinningEnvelopes.InverseBindMatrices.Count > vert.VertexWeight.BoneIndices[0])
                                    {
                                        Matrix4 test = BMDFile.SkinningEnvelopes.InverseBindMatrices[vert.VertexWeight.BoneIndices[0]].Inverted();
                                        test.Transpose();
                                        vertex.pos = OpenTK.Vector3.TransformPosition(vertex.pos, test);
                                        vertex.nrm = OpenTK.Vector3.TransformNormal(vertex.nrm, test);
                                    }
                                    else
                                    {
                                        vertex.pos = OpenTK.Vector3.TransformPosition(vertex.pos, BMDFile.Joints.FlatSkeleton[vert.VertexWeight.BoneIndices[0]].TransformationMatrix);
                                        vertex.nrm = OpenTK.Vector3.TransformNormal(vertex.nrm, BMDFile.Joints.FlatSkeleton[vert.VertexWeight.BoneIndices[0]].TransformationMatrix);
                                    }
                                }

                                for (int texCoordNum = 0; texCoordNum < 8; texCoordNum++)
                                {
                                    if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Tex0 + texCoordNum))
                                    {
                                        switch (texCoordNum)
                                        {
                                        case 0:
                                            vertex.uv0 = VertexAttributes.TexCoord_0[(int)vert.TexCoord0Index];
                                            break;

                                        case 1:
                                            vertex.uv1 = VertexAttributes.TexCoord_0[(int)vert.TexCoord0Index];
                                            break;

                                        case 2:
                                            vertex.uv2 = VertexAttributes.TexCoord_0[(int)vert.TexCoord0Index];
                                            break;
                                        }
                                    }
                                }

                                vertexID++;
                            }
                        }

                        primID++;
                    }

                    packetID++;
                }
            }

            CorrectMaterialIndices(Renderer.Meshes, BMDFile.Scenegraph, BMDFile.Materials);

            for (int i = 0; i < BMDFile.Textures.Textures.Count; i++)
            {
                var texWrapper = new BMDTextureWrapper(BMDFile.Textures.Textures[i]);
                TextureFolder.Nodes.Add(texWrapper);
                Renderer.TextureList.Add(texWrapper);
            }
        }
Ejemplo n.º 7
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;
                    }
                }
            }
        }
Ejemplo n.º 8
0
 public GFBMaterial GetMaterial(STGenericPolygonGroup polygroup)
 {
     return(ParentModel.header.GenericMaterials[polygroup.MaterialIndex]);
 }
Ejemplo n.º 9
0
        public void Load(System.IO.Stream stream)
        {
            DrawableContainer.Name = FileName;
            Renderer = new PunchOutWii_Renderer();
            DrawableContainer.Drawables.Add(Renderer);

            Text = FileName;

            HeaderFile = new DictionaryFile();
            HeaderFile.Read(new FileReader(stream), FilePath);

            var HashList = NLG_Common.HashNames;

            string DataFile = $"{FilePath.Replace(".dict", ".data")}";

            if (System.IO.File.Exists(DataFile))
            {
                using (var reader = new FileReader(DataFile, true))
                {
                    reader.SetByteOrder(true);

                    TreeNode blocks      = new TreeNode("Blocks");
                    TreeNode chunks      = new TreeNode("Chunks");
                    TreeNode modelFolder = new TreeNode("Models");

                    foreach (var blockInfo in HeaderFile.Blocks)
                    {
                        ChunkViewer chunkNode = new ChunkViewer("block");
                        if (blockInfo.Size > 0)
                        {
                            blocks.Nodes.Add(chunkNode);
                        }

                        chunkNode.FileData = new SubStream(reader.BaseStream, blockInfo.Offset, blockInfo.Size);
                    }

                    List <PO_Texture> currentTextures = new List <PO_Texture>();

                    List <ModelFileData> modelData = new List <ModelFileData>();

                    ModelFileData currentModel = null;

                    STTextureFolder textureFolder = new STTextureFolder("Textures");
                    Nodes.Add(blocks);
                    Nodes.Add(chunks);

                    Nodes.Add(textureFolder);
                    Nodes.Add(modelFolder);

                    foreach (var chunk in HeaderFile.DataChunks)
                    {
                        if (chunk.BlockIndex == -1)
                        {
                            continue;
                        }

                        ChunkViewer chunkNode = new ChunkViewer(chunk.Type.ToString("") + " " + chunk.Type.ToString("X"));
                        chunks.Nodes.Add(chunkNode);

                        var blockInfo = HeaderFile.Blocks[chunk.BlockIndex];
                        if (blockInfo.Offset + chunk.Offset + chunk.Size > reader.BaseStream.Length)
                        {
                            continue;
                        }

                        chunkNode.FileData = new SubStream(reader.BaseStream, blockInfo.Offset + chunk.Offset, chunk.Size);

                        uint chunkPos = blockInfo.Offset + chunk.Offset;

                        reader.SeekBegin(chunkPos);
                        switch (chunk.Type)
                        {
                        case SectionMagic.MaterialData:
                            currentModel = new ModelFileData();
                            currentModel.MaterialOffset = chunkPos;
                            modelData.Add(currentModel);
                            break;

                        case SectionMagic.TextureHeaders:
                            uint numTextures = chunk.Size / 96;
                            for (int i = 0; i < numTextures; i++)
                            {
                                var tex = new PO_Texture();
                                tex.ImageKey         = "texture";
                                tex.SelectedImageKey = "texture";

                                tex.Read(reader);
                                tex.Text = tex.HashID.ToString("X");
                                if (HashList.ContainsKey(tex.HashID))
                                {
                                    tex.Text = HashList[tex.HashID];
                                }

                                currentTextures.Add(tex);
                                Renderer.TextureList.Add(tex.Text, tex);

                                textureFolder.Nodes.Add(tex);
                            }
                            break;

                        case SectionMagic.TextureData:
                            for (int i = 0; i < currentTextures.Count; i++)
                            {
                                reader.SeekBegin(chunkPos + currentTextures[i].DataOffset);
                                currentTextures[i].ImageData = reader.ReadBytes((int)currentTextures[i].ImageSize);
                            }
                            break;

                        case SectionMagic.IndexData:
                            currentModel.indexBufferOffset = chunkPos;
                            break;

                        case SectionMagic.VertexData:
                            currentModel.vertexBufferOffset = chunkPos;
                            break;

                        case SectionMagic.MeshData:
                            uint numMeshes = chunk.Size / 52;
                            for (int i = 0; i < numMeshes; i++)
                            {
                                reader.SeekBegin(chunkPos + (i * 52));
                                PO_Mesh mesh = new PO_Mesh(reader);
                                currentModel.meshes.Add(mesh);
                            }
                            break;

                        case SectionMagic.VertexAttributePointerData:
                            uint numAttributes = chunk.Size / 8;
                            for (int i = 0; i < numAttributes; i++)
                            {
                                PO_VertexAttribute att = new PO_VertexAttribute();
                                att.Offset = reader.ReadUInt32();
                                att.Type   = reader.ReadByte();
                                att.Stride = reader.ReadByte();
                                reader.ReadUInt16();
                                currentModel.attributes.Add(att);
                            }
                            break;

                        case SectionMagic.ModelData:
                            uint numModels = chunk.Size / 12;
                            Console.WriteLine($"numModels {numModels}");
                            for (int i = 0; i < numModels; i++)
                            {
                                PO_Model mdl = new PO_Model();
                                mdl.ParentDictionary = this;
                                mdl.HashID           = reader.ReadUInt32();
                                mdl.NumMeshes        = reader.ReadUInt32();
                                reader.ReadUInt32();     //0
                                currentModel.models.Add(mdl);
                            }
                            break;

                        case SectionMagic.BoneData:
                            STSkeleton Skeleton = new STSkeleton();
                            DrawableContainer.Drawables.Add(Skeleton);

                            uint numBones = chunk.Size / 68;
                            for (int i = 0; i < numBones; i++)
                            {
                                reader.SeekBegin(chunkPos + (i * 68));

                                uint HashID = reader.ReadUInt32();
                                reader.ReadUInt32();     //unk
                                reader.ReadUInt32();     //unk
                                reader.ReadUInt32();     //unk
                                reader.ReadSingle();     //0

                                STBone bone  = new STBone(Skeleton);
                                var    Scale = new OpenTK.Vector3(
                                    reader.ReadSingle(),
                                    reader.ReadSingle(),
                                    reader.ReadSingle());
                                reader.ReadSingle();     //0
                                bone.EulerRotation = new OpenTK.Vector3(
                                    reader.ReadSingle(),
                                    reader.ReadSingle(),
                                    reader.ReadSingle());
                                reader.ReadSingle();     //0
                                bone.Position = new OpenTK.Vector3(
                                    reader.ReadSingle(),
                                    reader.ReadSingle(),
                                    reader.ReadSingle());
                                reader.ReadSingle();     //1

                                bone.Text = HashID.ToString("X");
                                if (NLG_Common.HashNames.ContainsKey(HashID))
                                {
                                    bone.Text = NLG_Common.HashNames[HashID];
                                }
                                else
                                {
                                    Console.WriteLine($"bone hash {HashID}");
                                }

                                bone.Scale = new Vector3(0.2f, 0.2f, 0.2f);

                                bone.RotationType = STBone.BoneRotationType.Euler;
                                Skeleton.bones.Add(bone);
                            }

                            Skeleton.reset();
                            Skeleton.update();
                            break;
                        }
                    }

                    foreach (var modelFile in modelData)
                    {
                        int pointerIndex = 0;
                        foreach (var model in modelFile.models)
                        {
                            model.Text = model.HashID.ToString("X");
                            if (HashList.ContainsKey(model.HashID))
                            {
                                model.Text = HashList[model.HashID];
                            }

                            modelFolder.Nodes.Add(model);
                            for (int i = 0; i < model.NumMeshes; i++)
                            {
                                var mesh = modelFile.meshes[i];

                                RenderableMeshWrapper genericMesh = new RenderableMeshWrapper();
                                model.Nodes.Add(genericMesh);
                                model.RenderedMeshes.Add(genericMesh);
                                Renderer.Meshes.Add(genericMesh);

                                genericMesh.Text = mesh.HashID.ToString("X");
                                if (HashList.ContainsKey(mesh.HashID))
                                {
                                    genericMesh.Text = HashList[mesh.HashID];
                                }

                                string material = mesh.MaterialHashID.ToString("X");
                                if (HashList.ContainsKey(mesh.MaterialHashID))
                                {
                                    material = HashList[mesh.MaterialHashID];
                                }
                                genericMesh.Nodes.Add(material);


                                genericMesh.Material = new STGenericMaterial();

                                reader.SeekBegin(modelFile.MaterialOffset + mesh.MaterialOffset);
                                switch (mesh.MaterailPreset)
                                {
                                case MaterailPresets.EnvDiffuseDamage:
                                {
                                    uint diffuseMapHashID    = reader.ReadUInt32();
                                    uint diffuseMapParam     = reader.ReadUInt32();
                                    uint envSpecMapHashID    = reader.ReadUInt32();
                                    uint envSpecMapParam     = reader.ReadUInt32();
                                    uint specMapHashID       = reader.ReadUInt32();
                                    uint specMapParam        = reader.ReadUInt32();
                                    uint megaStrikeMapHashID = reader.ReadUInt32();
                                    uint megaStrikeMapParam  = reader.ReadUInt32();
                                    uint dirtMapHashID       = reader.ReadUInt32();
                                    uint dirtMapParam        = reader.ReadUInt32();
                                    uint iceMapHashID        = reader.ReadUInt32();
                                    uint iceMapParam         = reader.ReadUInt32();

                                    string diffuseName = diffuseMapHashID.ToString("X");
                                    if (HashList.ContainsKey(diffuseMapHashID))
                                    {
                                        diffuseName = HashList[diffuseMapHashID];
                                    }

                                    var texUnit = 1;
                                    genericMesh.Material.TextureMaps.Add(new STGenericMatTexture()
                                        {
                                            textureUnit = texUnit++,
                                            Type        = STGenericMatTexture.TextureType.Diffuse,
                                            Name        = diffuseName,
                                        });
                                }
                                break;

                                default:
                                {
                                    uint   diffuseMapHashID = reader.ReadUInt32();
                                    string diffuseName      = diffuseMapHashID.ToString("X");
                                    if (HashList.ContainsKey(diffuseMapHashID))
                                    {
                                        diffuseName = HashList[diffuseMapHashID];
                                    }

                                    Console.WriteLine($"diffuseName {diffuseName}");

                                    var texUnit = 1;
                                    genericMesh.Material.TextureMaps.Add(new STGenericMatTexture()
                                        {
                                            textureUnit = texUnit++,
                                            Type        = STGenericMatTexture.TextureType.Diffuse,
                                            Name        = diffuseName,
                                        });
                                }
                                break;
                                }

                                Console.WriteLine($"mesh {i}");

                                STGenericPolygonGroup polyGroup = new STGenericPolygonGroup();
                                genericMesh.PolygonGroups.Add(polyGroup);
                                reader.SeekBegin(modelFile.indexBufferOffset + mesh.IndexStartOffset);

                                List <int> faces = new List <int>();
                                for (int f = 0; f < mesh.IndexCount; f++)
                                {
                                    if (mesh.IndexFormat == 0)
                                    {
                                        polyGroup.faces.Add(reader.ReadUInt16());
                                    }
                                    else
                                    {
                                        polyGroup.faces.Add(reader.ReadByte());
                                    }
                                }

                                if (mesh.FaceType == PO_Mesh.PolygonType.TriangleStrips)
                                {
                                    polyGroup.PrimativeType = STPrimitiveType.TrangleStrips;
                                }
                                else
                                {
                                    polyGroup.PrimativeType = STPrimitiveType.Triangles;
                                }


                                for (int a = 0; a < mesh.NumAttributePointers; a++)
                                {
                                    Console.WriteLine($"pointer {genericMesh.Text} { modelFile.vertexBufferOffset + modelFile.attributes[pointerIndex + a].Offset}");
                                }

                                for (int v = 0; v < mesh.VertexCount; v++)
                                {
                                    Vertex vert = new Vertex();
                                    genericMesh.vertices.Add(vert);

                                    int attributeIndex = 0;
                                    for (int a = 0; a < mesh.NumAttributePointers; a++)
                                    {
                                        var pointer = modelFile.attributes[pointerIndex + a];
                                        reader.SeekBegin(modelFile.vertexBufferOffset + pointer.Offset + (pointer.Stride * v));

                                        if (attributeIndex == 0)
                                        {
                                            if (pointer.Stride == 12)
                                            {
                                                vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                            }
                                        }
                                        if (attributeIndex == 1)
                                        {
                                            if (pointer.Stride == 12)
                                            {
                                                vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                            }
                                        }
                                        if (attributeIndex == 2)
                                        {
                                            if (pointer.Stride == 4)
                                            {
                                                vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
                                            }
                                        }

                                        /*     if (pointer.Type == 0xD4)
                                         *   {
                                         *       vert.boneIds = new List<int>() { reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte() };
                                         *   }
                                         *   if (pointer.Type == 0xB0)
                                         *   {
                                         *       vert.boneWeights = new List<float>() { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() };
                                         *   }*/

                                        attributeIndex++;
                                    }
                                }

                                genericMesh.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1));

                                pointerIndex += mesh.NumAttributePointers;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 10
0
        public void ReadVertexBuffers()
        {
            Nodes.Clear();

            using (var reader = new FileReader(DataDictionary.GetFileBufferData(), true))
            {
                TreeNode texturesList = new TreeNode("Texture Maps");
                TreeNode skeletonNode = new TreeNode("Skeleton");
                for (int t = 0; t < Skeleton?.bones.Count; t++)
                {
                    skeletonNode.Nodes.Add(Skeleton.bones[t]);
                }

                for (int t = 0; t < TextureHashes.Count; t++)
                {
                    if (DataDictionary.Renderer.TextureList.ContainsKey(TextureHashes[t].ToString("x")))
                    {
                        var tex = DataDictionary.Renderer.TextureList[TextureHashes[t].ToString("x")];
                        texturesList.Nodes.Add(new TreeNode(tex.Text)
                        {
                            ImageKey         = tex.ImageKey,
                            SelectedImageKey = tex.ImageKey,
                            Tag = tex
                        });
                    }
                    else
                    {
                        Nodes.Add(TextureHashes[t].ToString("x"));
                    }
                }

                if (skeletonNode.Nodes.Count > 0)
                {
                    Nodes.Add(skeletonNode);
                }

                if (texturesList.Nodes.Count > 0)
                {
                    Nodes.Add(texturesList);
                }

                for (int i = 0; i < Meshes.Count; i++)
                {
                    LM3_Mesh mesh = Meshes[i];

                    RenderableMeshWrapper genericObj = new RenderableMeshWrapper();
                    genericObj.Mesh    = mesh;
                    genericObj.Checked = true;
                    genericObj.Text    = $"Mesh {i} {mesh.HashID.ToString("X")}";
                    if (NLG_Common.HashNames.ContainsKey(mesh.HashID))
                    {
                        genericObj.Text = NLG_Common.HashNames[mesh.HashID];
                    }

                    genericObj.SetMaterial(mesh.Material);
                    RenderedMeshes.Add(genericObj);

                    Nodes.Add(genericObj);

                    DataDictionary.Renderer.Meshes.Add(genericObj);

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

                    uint vertexBufferPointer = VertexBufferPointers[i].VertexBufferPointer;
                    uint weightTablePointer  = VertexBufferPointers[i].WeightTablePointer;

                    using (reader.TemporarySeek(BufferStart + vertexBufferPointer, System.IO.SeekOrigin.Begin))
                    {
                        var bufferNodeDebug = new DebugVisualBytes(reader.ReadBytes((int)80 * (int)mesh.VertexCount));
                        bufferNodeDebug.Text = $"Buffer {mesh.DataFormat.ToString("x")}";
                        genericObj.Nodes.Add(bufferNodeDebug);
                    }

                    LM3_Mesh.FormatInfo formatInfo;
                    if (!LM3_Mesh.FormatInfos.ContainsKey(mesh.DataFormat))
                    {
                        Console.WriteLine($"Unsupported data format! " + mesh.DataFormat.ToString("x"));
                        formatInfo = new LM3_Mesh.FormatInfo(VertexDataFormat.Float32_32_32, 0x30);
                        //  continue;
                    }
                    else
                    {
                        formatInfo = LM3_Mesh.FormatInfos[mesh.DataFormat];
                    }

                    if (formatInfo.BufferLength > 0)
                    {
                        Console.WriteLine($"BufferStart {BufferStart} IndexStartOffset {mesh.IndexStartOffset}");

                        reader.BaseStream.Position = BufferStart + mesh.IndexStartOffset;
                        switch (mesh.IndexFormat)
                        {
                        case IndexFormat.Index_8:
                            for (int f = 0; f < mesh.IndexCount; f++)
                            {
                                polyGroup.faces.Add(reader.ReadByte());
                            }
                            break;

                        case IndexFormat.Index_16:
                            for (int f = 0; f < mesh.IndexCount; f++)
                            {
                                polyGroup.faces.Add(reader.ReadUInt16());
                            }
                            break;

                            /*   case IndexFormat.Index_32:
                             *     for (int f = 0; f < mesh.IndexCount; f++)
                             *         polyGroup.faces.Add((int)reader.ReadUInt32());
                             *     break;*/
                        }

                        Console.WriteLine($"Mesh {genericObj.Text} Format {formatInfo.Format} BufferLength {formatInfo.BufferLength}");

                        Console.WriteLine($"BufferStart {BufferStart} VertexBufferPointers {vertexBufferPointer}");

                        uint bufferOffet = BufferStart + vertexBufferPointer;

                        /*       for (int v = 0; v < mesh.VertexCount; v++)
                         *     {
                         *         reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));
                         *
                         *     }*/


                        switch (formatInfo.Format)
                        {
                        case VertexDataFormat.Float16:
                            for (int v = 0; v < mesh.VertexCount; v++)
                            {
                                reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                Vertex vert = new Vertex();
                                genericObj.vertices.Add(vert);
                                vert.pos = new Vector3(
                                    UShortToFloatDecode(reader.ReadInt16()),
                                    UShortToFloatDecode(reader.ReadInt16()),
                                    UShortToFloatDecode(reader.ReadInt16()));

                                Vector4 nrm = Read_8_8_8_8_Snorm(reader);
                                vert.nrm = nrm.Xyz.Normalized();

                                vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);
                                vert.uv0 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());

                                if (formatInfo.BufferLength == 22)
                                {
                                    Console.WriteLine("unk 1 " + reader.ReadUInt16());
                                    Console.WriteLine("unk 2 " + reader.ReadUInt16());
                                    Console.WriteLine("unk 3 " + reader.ReadUInt16());
                                    Console.WriteLine("unk 4 " + reader.ReadUInt16());
                                }
                            }
                            break;

                        case VertexDataFormat.Float32:
                            for (int v = 0; v < mesh.VertexCount; v++)
                            {
                                reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                Vertex vert = new Vertex();
                                genericObj.vertices.Add(vert);

                                vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);
                            }
                            break;

                        case VertexDataFormat.Float32_32:
                            reader.BaseStream.Position = BufferStart + vertexBufferPointer + 0x08;
                            for (int v = 0; v < mesh.VertexCount; v++)
                            {
                                reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                Vertex vert = new Vertex();
                                genericObj.vertices.Add(vert);

                                vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);
                                vert.uv0 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());
                                vert.uv1 = NormalizeUvCoordsToFloat(reader.ReadUInt16(), reader.ReadUInt16());
                                vert.col = Read_8_8_8_8_Unorm(reader);
                            }
                            break;

                        case VertexDataFormat.Float32_32_32:
                            for (int v = 0; v < mesh.VertexCount; v++)
                            {
                                reader.SeekBegin(bufferOffet + (v * formatInfo.BufferLength));

                                Vertex vert = new Vertex();
                                genericObj.vertices.Add(vert);

                                vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                vert.pos = Vector3.TransformPosition(vert.pos, mesh.Transform);

                                //Texture coordinates are stored between normals, WHY NLG
                                var texCoordU = reader.ReadSingle();
                                vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                var texCoordV = reader.ReadSingle();
                                vert.tan = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                vert.uv0 = new Vector2(texCoordU, texCoordV);
                            }
                            break;
                        }

                        genericObj.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1));
                    }

                    if (weightTablePointer != uint.MaxValue)
                    {
                        using (reader.TemporarySeek(BufferStart + weightTablePointer, System.IO.SeekOrigin.Begin))
                        {
                            byte maxIndex = 0;
                            for (int v = 0; v < genericObj.vertices.Count; v++)
                            {
                                byte[]  boneIndices = reader.ReadBytes(4);
                                float[] boneWeights = reader.ReadSingles(4);

                                for (int j = 0; j < 4; j++)
                                {
                                    maxIndex = Math.Max(maxIndex, boneIndices[j]);
                                    //    genericObj.vertices[v].boneIds.Add(boneIndices[j]);
                                    //     genericObj.vertices[v].boneWeights.Add(boneWeights[j]);
                                }
                            }

                            Console.WriteLine("maxIndex " + maxIndex);
                        }
                    }

                    genericObj.RemoveDuplicateVertices();
                }
            }
        }
Ejemplo n.º 11
0
 public GFLXMaterialData GetMaterial(STGenericPolygonGroup polygroup)
 {
     return(ParentModel.GenericMaterials[polygroup.MaterialIndex]);
 }
Ejemplo n.º 12
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();
            }
        }
Ejemplo n.º 13
0
        public void LoadFile(Model model, GFBMDL file, GFBMDL_Render Renderer)
        {
            Model      = model;
            ParentFile = file;

            Renderer.Meshes.Clear();

            for (int m = 0; m < Model.Materials?.Count; m++)
            {
                GenericMaterials.Add(new GFLXMaterialData(this, Model.Materials[m]));
            }

            List <int> SkinningIndices = new List <int>();

            for (int b = 0; b < Model.Bones?.Count; b++)
            {
                var bone = Model.Bones[b];
                Skeleton.bones.Add(new GFLXBone(this, bone));

                if (bone.RigidCheck == null)
                {
                    SkinningIndices.Add(b);
                }
            }

            Skeleton.reset();
            Skeleton.update();

            for (int g = 0; g < Model.Groups?.Count; g++)
            {
                var group = Model.Groups[g];
                var mesh  = Model.Meshes[g];

                OpenTK.Matrix4 transform = OpenTK.Matrix4.Identity;

                GFLXMesh genericMesh = new GFLXMesh(this, group, mesh);
                genericMesh.Checked          = true;
                genericMesh.ImageKey         = "model";
                genericMesh.SelectedImageKey = "model";

                int boneIndex = (int)group.BoneIndex;
                if (boneIndex < Skeleton.bones.Count && boneIndex > 0)
                {
                    genericMesh.BoneIndex = boneIndex;
                    transform             = Skeleton.bones[boneIndex].Transform;

                    genericMesh.Text = Skeleton.bones[boneIndex].Text;
                }

                //   if (group.MeshID < Skeleton.bones.Count && group.MeshID > 0)
                //       genericMesh.Text = Skeleton.bones[(int)group.MeshID].Text;

                Renderer.Meshes.Add(genericMesh);
                GenericMeshes.Add(genericMesh);

                //Load the vertex data
                genericMesh.Transform = transform;
                genericMesh.vertices  = GFLXMeshBufferHelper.LoadVertexData(mesh, transform, SkinningIndices);
                genericMesh.FlipUvsVertical();

                //Load faces
                for (int p = 0; p < mesh.Polygons?.Count; p++)
                {
                    var poly = mesh.Polygons[p];

                    var polygonGroup = new STGenericPolygonGroup();
                    polygonGroup.MaterialIndex = (int)poly.MaterialIndex;
                    genericMesh.PolygonGroups.Add(polygonGroup);

                    if (GenericMaterials.Count > poly.MaterialIndex)
                    {
                        polygonGroup.Material = GenericMaterials[(int)poly.MaterialIndex];
                    }

                    for (int f = 0; f < poly.Faces?.Count; f++)
                    {
                        polygonGroup.faces.Add((int)poly.Faces[f]);
                    }
                }
            }
        }
Ejemplo n.º 14
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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 15
0
        public void Load(System.IO.Stream stream)
        {
            CanSave = false;

            Renderer = new CMB_Renderer();
            DrawableContainer.Drawables.Add(Renderer);


            Skeleton = new STSkeleton();
            //These models/skeletons come out massive so scale them with an overridden scale
            Skeleton.PreviewScale   = Renderer.PreviewScale;
            Skeleton.BonePointScale = 40;
            Renderer.Skeleton       = Skeleton;

            DrawableContainer.Drawables.Add(Skeleton);


            cmb.ReadCMB(stream);

            Text = cmb.Header.Name;

            DrawableContainer.Name = Text;

            //Load textures
            if (cmb.TexturesChunk != null)
            {
                texFolder = new TextureFolder("Texture");
                TreeNode meshFolder     = new TreeNode("Meshes");
                TreeNode materialFolder = new TreeNode("Materials");
                TreeNode skeletonFolder = new TreeNode("Skeleton");

                bool HasTextures = cmb.TexturesChunk.Textures != null &&
                                   cmb.TexturesChunk.Textures.Count != 0;

                bool HasMeshes = cmb.MeshesChunk.SHP.SEPDs != null &&
                                 cmb.MeshesChunk.SHP.SEPDs.Count != 0;

                bool HasSkeleton = cmb.SkeletonChunk != null &&
                                   cmb.SkeletonChunk.Bones.Count != 0;

                bool HasMaterials = cmb.MaterialsChunk != null &&
                                    cmb.MaterialsChunk.Materials.Count != 0;

                if (HasSkeleton)
                {
                    var bonesOrdered = cmb.SkeletonChunk.Bones.OrderBy(x => x.ID).ToList();
                    foreach (var bone in bonesOrdered)
                    {
                        STBone genericBone = new STBone(Skeleton);
                        genericBone.parentIndex = bone.ParentID;
                        genericBone.Checked     = true;

                        genericBone.Text         = $"Bone {bone.ID}";
                        genericBone.RotationType = STBone.BoneRotationType.Euler;

                        genericBone.Position = new OpenTK.Vector3(
                            bone.Translation.X,
                            bone.Translation.Y,
                            bone.Translation.Z
                            );
                        genericBone.EulerRotation = new OpenTK.Vector3(
                            bone.Rotation.X,
                            bone.Rotation.Y,
                            bone.Rotation.Z
                            );
                        genericBone.Scale = new OpenTK.Vector3(
                            bone.Scale.X,
                            bone.Scale.Y,
                            bone.Scale.Z
                            );
                        Skeleton.bones.Add(genericBone);
                    }

                    foreach (var bone in Skeleton.bones)
                    {
                        if (bone.Parent == null)
                        {
                            skeletonFolder.Nodes.Add(bone);
                        }
                    }

                    Skeleton.reset();
                    Skeleton.update();
                }

                if (HasTextures)
                {
                    int texIndex = 0;
                    foreach (var tex in cmb.TexturesChunk.Textures)
                    {
                        var texWrapper = new CTXB.TextureWrapper(new CTXB.Texture());
                        texWrapper.Text             = $"Texture {texIndex++}";
                        texWrapper.ImageKey         = "texture";
                        texWrapper.SelectedImageKey = texWrapper.ImageKey;

                        if (tex.Name != string.Empty)
                        {
                            texWrapper.Text = tex.Name;
                        }

                        texWrapper.Width  = tex.Width;
                        texWrapper.Height = tex.Height;
                        CTXB.Texture.TextureFormat Format = (CTXB.Texture.TextureFormat)((tex.DataType << 16) | tex.ImageFormat);

                        texWrapper.Format    = CTR_3DS.ConvertPICAToGenericFormat(CTXB.Texture.FormatList[Format]);
                        texWrapper.ImageData = tex.ImageData;
                        texFolder.Nodes.Add(texWrapper);

                        Renderer.TextureList.Add(texWrapper);
                    }
                }

                if (HasMaterials)
                {
                    int materialIndex = 0;
                    foreach (var mat in cmb.MaterialsChunk.Materials)
                    {
                        H3DMaterial H3D = ToH3DMaterial(mat);

                        CMBMaterialWrapper material = new CMBMaterialWrapper(mat, this, H3D);
                        material.Text = $"Material {materialIndex++}";
                        materialFolder.Nodes.Add(material);
                        Materials.Add(material);

                        bool HasDiffuse = false;
                        foreach (var tex in mat.TextureMappers)
                        {
                            if (tex.TextureID != -1)
                            {
                                CMBTextureMapWrapper matTexture = new CMBTextureMapWrapper(tex, this);
                                matTexture.TextureIndex = tex.TextureID;
                                material.TextureMaps.Add(matTexture);

                                if (tex.TextureID < Renderer.TextureList.Count && tex.TextureID >= 0)
                                {
                                    matTexture.Name = Renderer.TextureList[tex.TextureID].Text;
                                    material.Nodes.Add(matTexture.Name);
                                }

                                if (!HasDiffuse && matTexture.Name != "bg_syadowmap") //Quick hack till i do texture env stuff
                                {
                                    matTexture.Type = STGenericMatTexture.TextureType.Diffuse;
                                    HasDiffuse      = true;
                                }
                            }
                        }
                    }
                }

                if (HasMeshes)
                {
                    int MeshIndex = 0;
                    foreach (var mesh in cmb.MeshesChunk.MSHS.Meshes)
                    {
                        STGenericMaterial mat = Materials[mesh.MaterialIndex];

                        CmbMeshWrapper genericMesh = new CmbMeshWrapper(mat);
                        genericMesh.Text          = $"Mesh_{MeshIndex++}_ID_{mesh.VisIndex}";
                        genericMesh.MaterialIndex = mesh.MaterialIndex;

                        var shape = cmb.MeshesChunk.SHP.SEPDs[mesh.SEPDIndex];
                        genericMesh.Mesh = shape;

                        List <ushort> SkinnedBoneTable = new List <ushort>();
                        foreach (var prim in shape.PRMS)
                        {
                            if (prim.BoneIndices != null)
                            {
                                SkinnedBoneTable.AddRange(prim.BoneIndices);
                            }
                        }

                        //Now load the vertex and face data

                        foreach (var prm in shape.PRMS)
                        {
                            if (shape.HasPosition)
                            {
                                int VertexCount = prm.VertexCount;
                                for (int v = 0; v < VertexCount; v++)
                                {
                                    Vertex vert = new Vertex();
                                    vert.pos = new OpenTK.Vector3(
                                        prm.Vertices.Position[v].X,
                                        prm.Vertices.Position[v].Y,
                                        prm.Vertices.Position[v].Z);
                                    if (shape.HasNormal)
                                    {
                                        vert.nrm = new OpenTK.Vector3(
                                            prm.Vertices.Normal[v].X,
                                            prm.Vertices.Normal[v].Y,
                                            prm.Vertices.Normal[v].Z).Normalized();
                                    }

                                    if (shape.HasColor)
                                    {
                                        vert.col = new OpenTK.Vector4(
                                            prm.Vertices.Color[v].X,
                                            prm.Vertices.Color[v].Y,
                                            prm.Vertices.Color[v].Z,
                                            prm.Vertices.Color[v].W).Normalized();
                                    }

                                    if (shape.HasUV0)
                                    {
                                        vert.uv0 = new OpenTK.Vector2(prm.Vertices.UV0[v].X, -prm.Vertices.UV0[v].Y + 1);
                                    }

                                    if (shape.HasUV1)
                                    {
                                        vert.uv1 = new OpenTK.Vector2(prm.Vertices.UV1[v].X, -prm.Vertices.UV1[v].Y + 1);
                                    }

                                    if (shape.HasUV2)
                                    {
                                        vert.uv2 = new OpenTK.Vector2(prm.Vertices.UV2[v].X, -prm.Vertices.UV2[v].Y + 1);
                                    }

                                    if (prm.SkinningMode == SkinningMode.Smooth)
                                    {
                                        //Indices
                                        if (shape.HasIndices)
                                        {
                                            if (shape.BoneDimensionCount >= 1)
                                            {
                                                vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].X);
                                            }
                                            if (shape.BoneDimensionCount >= 2)
                                            {
                                                vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].Y);
                                            }
                                            if (shape.BoneDimensionCount >= 3)
                                            {
                                                vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].Z);
                                            }
                                            if (shape.BoneDimensionCount >= 4)
                                            {
                                                vert.boneIds.Add((int)prm.Vertices.BoneIndices[v].W);
                                            }
                                        }

                                        //Weights
                                        if (shape.HasWeights)
                                        {
                                            if (shape.BoneDimensionCount >= 1)
                                            {
                                                vert.boneWeights.Add(prm.Vertices.BoneWeights[v].X);
                                            }
                                            if (shape.BoneDimensionCount >= 2)
                                            {
                                                vert.boneWeights.Add(prm.Vertices.BoneWeights[v].Y);
                                            }
                                            if (shape.BoneDimensionCount >= 3)
                                            {
                                                vert.boneWeights.Add(prm.Vertices.BoneWeights[v].Z);
                                            }
                                            if (shape.BoneDimensionCount >= 4)
                                            {
                                                vert.boneWeights.Add(prm.Vertices.BoneWeights[v].W);
                                            }
                                        }
                                    }

                                    if (prm.SkinningMode == SkinningMode.Rigid)
                                    {
                                        int boneId = (int)prm.Vertices.BoneIndices[v].X;
                                        vert.boneIds.Add(boneId);
                                        vert.boneWeights.Add(1);

                                        vert.pos = OpenTK.Vector3.TransformPosition(vert.pos, Skeleton.bones[boneId].Transform);
                                        if (shape.HasNormal)
                                        {
                                            vert.nrm = OpenTK.Vector3.TransformNormal(vert.nrm, Skeleton.bones[boneId].Transform);
                                        }
                                    }

                                    if (prm.SkinningMode == SkinningMode.Mixed)
                                    {
                                        int boneId = prm.BoneIndices[0];
                                        vert.boneIds.Add(boneId);
                                        vert.boneWeights.Add(1);

                                        vert.pos = OpenTK.Vector3.TransformPosition(vert.pos, Skeleton.bones[boneId].Transform);
                                        if (shape.HasNormal)
                                        {
                                            vert.nrm = OpenTK.Vector3.TransformNormal(vert.nrm, Skeleton.bones[boneId].Transform);
                                        }
                                    }

                                    genericMesh.vertices.Add(vert);
                                }
                            }

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

                            for (int i = 0; i < prm.FaceIndices.Count; i++)
                            {
                                group.faces.Add((int)prm.FaceIndices[i].X);
                                group.faces.Add((int)prm.FaceIndices[i].Y);
                                group.faces.Add((int)prm.FaceIndices[i].Z);
                            }
                        }

                        Renderer.Meshes.Add(genericMesh);
                        meshFolder.Nodes.Add(genericMesh);
                    }
                }

                if (meshFolder.Nodes.Count > 0)
                {
                    Nodes.Add(meshFolder);
                }

                if (skeletonFolder.Nodes.Count > 0)
                {
                    Nodes.Add(skeletonFolder);
                }

                if (materialFolder.Nodes.Count > 0)
                {
                    Nodes.Add(materialFolder);
                }

                if (texFolder.Nodes.Count > 0)
                {
                    Nodes.Add(texFolder);
                }
            }
        }
Ejemplo n.º 16
0
        public H3DMeshWrapper(BCH bch, H3DModelWrapper parentModel, H3DMesh mesh) : base()
        {
            ParentBCH   = bch;
            ParentModel = parentModel;
            Mesh        = mesh;

            ImageKey         = "mesh";
            SelectedImageKey = "mesh";

            MaterialIndex = Mesh.MaterialIndex;

            foreach (var subMesh in mesh.SubMeshes)
            {
                STGenericPolygonGroup group = new STGenericPolygonGroup();
                for (int i = 0; i < subMesh.Indices.Length; i++)
                {
                    group.faces.Add(subMesh.Indices[i]);
                }

                group.PrimativeType = STPrimitiveType.Triangles;

                /*     switch (subMesh.PrimitiveMode)
                 *   {
                 *       case SPICA.PICA.Commands.PICAPrimitiveMode.Triangles:
                 *           group.PrimativeType = STPrimitiveType.Triangles;
                 *           break;
                 *       case SPICA.PICA.Commands.PICAPrimitiveMode.TriangleStrip:
                 *           group.PrimativeType = STPrimitiveType.TrangleStrips;
                 *           break;
                 *   }*/

                PolygonGroups.Add(group);
            }

            var vertices = mesh.GetVertices();

            List <ushort> boneIndices = new List <ushort>();

            foreach (var subMesh in mesh.SubMeshes)
            {
                if (subMesh.BoneIndicesCount > 0)
                {
                    boneIndices.AddRange(subMesh.BoneIndices.ToArray());
                }
            }

            for (int v = 0; v < vertices.Length; v++)
            {
                Vertex vertex = new Vertex();
                vertex.pos = ConvertVector3(vertices[v].Position);
                vertex.nrm = ConvertVector3(vertices[v].Normal);
                vertex.tan = ConvertVector4(vertices[v].Tangent);
                vertex.uv0 = ConvertVector2(vertices[v].TexCoord0);
                vertex.uv1 = ConvertVector2(vertices[v].TexCoord1);
                vertex.uv2 = ConvertVector2(vertices[v].TexCoord2);
                vertex.col = ConvertVector4(vertices[v].Color);

                //Flip UVs
                vertex.uv0 = new Vector2(vertex.uv0.X, 1 - vertex.uv0.Y);
                if (boneIndices.Count > 0)
                {
                    /*  if (vertices[v].Indices.b0 != -1) vertex.boneIds.Add(boneIndices[vertices[v].Indices.b0]);
                     * if (vertices[v].Indices.b1 != -1) vertex.boneIds.Add(boneIndices[vertices[v].Indices.b1]);
                     * if (vertices[v].Indices.b2 != -1) vertex.boneIds.Add(boneIndices[vertices[v].Indices.b2]);
                     * if (vertices[v].Indices.b3 != -1) vertex.boneIds.Add(boneIndices[vertices[v].Indices.b3]);*/

                    if (mesh.Skinning == H3DMeshSkinning.Rigid)
                    {
                        int index = boneIndices[vertices[v].Indices.b0];
                        vertex.pos = Vector3.TransformPosition(vertex.pos, parentModel.Skeleton.Renderable.bones[index].Transform);
                        // vertex.nrm = Vector3.TransformNormal(vertex.nrm, parentModel.Skeleton.Renderable.bones[index].Transform);
                    }

                    /*    vertex.boneWeights.Add(vertices[v].Weights.w0);
                     *  vertex.boneWeights.Add(vertices[v].Weights.w1);
                     *  vertex.boneWeights.Add(vertices[v].Weights.w2);
                     *  vertex.boneWeights.Add(vertices[v].Weights.w3);*/
                }

                this.vertices.Add(vertex);
            }
        }
Ejemplo n.º 17
0
        public void Load(System.IO.Stream stream)
        {
            Renderer = new Strikers_Renderer();
            DrawableContainer.Name = FileName;
            DrawableContainer.Drawables.Add(Renderer);

            IsGamecube = Utils.GetExtension(FileName) == ".glg";

            Text = FileName;

            using (var reader = new FileReader(stream))
            {
                reader.SetByteOrder(true);
                reader.ReadUInt32(); //magic
                reader.ReadUInt32(); //fileSize

                //Create a list of all the major sections
                //The sections are not in order, so we must order them while parsing
                Dictionary <SectionMagic, SectionHeader> SectionLookup = new Dictionary <SectionMagic, SectionHeader>();

                while (!reader.EndOfStream)
                {
                    uint magic       = reader.ReadUInt32();
                    uint sectionSize = reader.ReadUInt32();

                    long pos = reader.Position;
                    Console.WriteLine($"Magic {(SectionMagic)magic} sectionSize {sectionSize}");

                    if (!SectionLookup.ContainsKey((SectionMagic)magic))
                    {
                        SectionLookup.Add((SectionMagic)magic, new SectionHeader(sectionSize, pos));
                    }

                    //This section will skip sub sections so don't do that
                    if (magic != 0x8001B000)
                    {
                        reader.SeekBegin(pos + sectionSize);
                    }

                    if (!IsGamecube)
                    {
                        reader.Align(4);
                    }
                }

                var HashList = NLG_Common.HashNames;

                //Now read our model properly
                //First get our model info

                Matrix4 TransformMatrix = Matrix4.Identity;

                uint totalNumMeshes = 0;

                uint modelSize = 12;
                if (IsGamecube)
                {
                    modelSize = 16;
                }
                if (SectionLookup.ContainsKey(SectionMagic.ModelData))
                {
                    var modelHeader = SectionLookup[SectionMagic.ModelData];
                    for (int m = 0; m < modelHeader.Size / modelSize; m++)
                    {
                        reader.SeekBegin(modelHeader.Position + (m * modelSize));
                        if (IsGamecube)
                        {
                            totalNumMeshes += reader.ReadUInt32();
                            reader.ReadUInt32();
                        }
                        else
                        {
                            reader.ReadUInt32();
                            totalNumMeshes += reader.ReadUInt32();
                        }
                    }
                }

                uint meshIndex = 0;
                if (SectionLookup.ContainsKey(SectionMagic.ModelData))
                {
                    var modelHeader = SectionLookup[SectionMagic.ModelData];
                    reader.SeekBegin(modelHeader.Position);
                    uint numModels = modelHeader.Size / modelSize;
                    uint hashId    = 0;

                    for (int m = 0; m < numModels; m++)
                    {
                        Model model = new Model();
                        Nodes.Add(model);
                        Models.Add(model);

                        uint numMeshes = 0;
                        reader.SeekBegin(modelHeader.Position + (m * modelSize));
                        if (IsGamecube)
                        {
                            numMeshes = reader.ReadUInt32();
                            hashId    = reader.ReadUInt32();
                        }
                        else
                        {
                            hashId    = reader.ReadUInt32();
                            numMeshes = reader.ReadUInt32();
                        }

                        model.Text = hashId.ToString("X");
                        if (HashList.ContainsKey(hashId))
                        {
                            model.Text = HashList[hashId];
                        }



                        if (SectionLookup.ContainsKey(SectionMagic.MeshData))
                        {
                            var meshHeader = SectionLookup[SectionMagic.MeshData];
                            reader.SeekBegin(meshHeader.Position);
                            for (int i = 0; i < numMeshes; i++)
                            {
                                if (IsGamecube)
                                {
                                    uint meshSize = meshHeader.Size / totalNumMeshes;
                                    reader.SeekBegin(meshHeader.Position + ((meshIndex + i) * meshSize));
                                }
                                else
                                {
                                    reader.SeekBegin(meshHeader.Position + ((meshIndex + i) * 48));
                                }

                                var mesh = new MeshData(reader, IsGamecube);
                                model.Meshes.Add(mesh);
                            }

                            meshIndex += numMeshes;
                        }
                    }

                    if (SectionLookup.ContainsKey(SectionMagic.MatrixData))
                    {
                        var matSection = SectionLookup[SectionMagic.MatrixData];
                        reader.SeekBegin(matSection.Position);
                        TransformMatrix = reader.ReadMatrix4(true);
                    }

                    List <VertexAttribute> Pointers = new List <VertexAttribute>();
                    if (SectionLookup.ContainsKey(SectionMagic.VertexAttributePointerData))
                    {
                        var pointerSection = SectionLookup[SectionMagic.VertexAttributePointerData];
                        reader.SeekBegin(pointerSection.Position);
                        int attributeSize = 8;
                        if (IsGamecube)
                        {
                            attributeSize = 6;
                        }

                        for (int i = 0; i < pointerSection.Size / attributeSize; i++)
                        {
                            VertexAttribute pointer = new VertexAttribute();
                            if (IsGamecube)
                            {
                                pointer.Offset = reader.ReadUInt32();
                                pointer.Type   = reader.ReadByte();
                                pointer.Stride = reader.ReadByte();
                            }
                            else
                            {
                                pointer.Offset = reader.ReadUInt32();
                                pointer.Type   = reader.ReadByte();
                                pointer.Stride = reader.ReadByte();
                                reader.ReadUInt16();
                            }

                            Pointers.Add(pointer);
                        }
                    }

                    int pointerIndex = 0;
                    foreach (var model in Models)
                    {
                        for (int i = 0; i < model.Meshes.Count; i++)
                        {
                            RenderableMeshWrapper mesh = new RenderableMeshWrapper();
                            model.Nodes.Add(mesh);
                            Renderer.Meshes.Add(mesh);

                            mesh.Text = model.Meshes[i].HashID.ToString("X");
                            if (HashList.ContainsKey(model.Meshes[i].HashID))
                            {
                                mesh.Text = HashList[model.Meshes[i].HashID];
                            }

                            string material = model.Meshes[i].MaterialHashID.ToString("X");
                            if (HashList.ContainsKey(model.Meshes[i].MaterialHashID))
                            {
                                material = HashList[model.Meshes[i].MaterialHashID];
                            }
                            mesh.Nodes.Add(material);

                            var faceSecton   = SectionLookup[SectionMagic.IndexData];
                            var vertexSecton = SectionLookup[SectionMagic.VertexData];

                            STGenericPolygonGroup polyGroup = new STGenericPolygonGroup();
                            mesh.PolygonGroups.Add(polyGroup);
                            reader.SeekBegin(faceSecton.Position + model.Meshes[i].IndexStartOffset);


                            List <int> faces = new List <int>();
                            for (int f = 0; f < model.Meshes[i].IndexCount; f++)
                            {
                                if (model.Meshes[i].IndexFormat == 0)
                                {
                                    polyGroup.faces.Add(reader.ReadUInt16());
                                }
                                else
                                {
                                    polyGroup.faces.Add(reader.ReadByte());
                                }
                            }

                            if (model.Meshes[i].FaceType == MeshData.PolygonType.TriangleStrips)
                            {
                                polyGroup.PrimativeType = STPrimitiveType.TrangleStrips;
                            }
                            else
                            {
                                polyGroup.PrimativeType = STPrimitiveType.Triangles;
                            }

                            if (IsGamecube)
                            {
                                uint size = Pointers[pointerIndex + 1].Offset - Pointers[pointerIndex].Offset;
                                model.Meshes[i].VertexCount = (ushort)(size / Pointers[pointerIndex].Stride);
                            }

                            Console.WriteLine($"mesh {mesh.Text} {model.Meshes[i].VertexCount}");

                            for (int v = 0; v < model.Meshes[i].VertexCount; v++)
                            {
                                Vertex vert = new Vertex();
                                mesh.vertices.Add(vert);

                                for (int a = 0; a < model.Meshes[i].NumAttributePointers; a++)
                                {
                                    var pointer = Pointers[pointerIndex + a];
                                    reader.SeekBegin(vertexSecton.Position + pointer.Offset + (pointer.Stride * v));

                                    if (pointer.Type == 0)
                                    {
                                        if (pointer.Stride == 6)
                                        {
                                            vert.pos = new Vector3(reader.ReadInt16() / 1024f, reader.ReadInt16() / 1024f, reader.ReadInt16() / 1024f);
                                        }
                                        else if (pointer.Stride == 12)
                                        {
                                            vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                        }

                                        //       vert.pos = Vector3.TransformPosition(vert.pos, TransformMatrix);
                                    }

                                    if (pointer.Type == 1)
                                    {
                                        if (pointer.Stride == 3)
                                        {
                                            vert.nrm = Read_8_8_8_Snorm(reader).Normalized();
                                        }
                                        else if (pointer.Stride == 12)
                                        {
                                            vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                        }
                                    }
                                    if (pointer.Type == 3)
                                    {
                                        vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
                                    }


                                    if (pointer.Type == 0x67)
                                    {
                                        vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                    }
                                    if (pointer.Type == 0xFE)
                                    {
                                        vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                    }
                                    if (pointer.Type == 0x26)
                                    {
                                        vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
                                    }
                                    if (pointer.Type == 0xCC)
                                    {
                                        vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
                                    }
                                    if (pointer.Type == 0x17)
                                    {
                                        vert.uv1 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f);
                                    }
                                    if (pointer.Type == 0xD4)
                                    {
                                        vert.boneIds = new List <int>()
                                        {
                                            reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()
                                        };
                                    }
                                    if (pointer.Type == 0xB0)
                                    {
                                        vert.boneWeights = new List <float>()
                                        {
                                            reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()
                                        };
                                    }
                                }
                            }

                            mesh.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1));

                            pointerIndex += model.Meshes[i].NumAttributePointers;
                        }


                        for (int i = 0; i < model.Meshes.Count; i++)
                        {
                            if (IsGamecube)
                            {
                                var renderedMesh = (RenderableMeshWrapper)Renderer.Meshes[i];
                                renderedMesh.Material = new STGenericMaterial();

                                string diffuseName = model.Meshes[i].TexturHashID.ToString("X");
                                if (HashList.ContainsKey(model.Meshes[i].TexturHashID))
                                {
                                    diffuseName = HashList[model.Meshes[i].TexturHashID];
                                }

                                var texUnit = 1;
                                renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture()
                                {
                                    textureUnit = texUnit++,
                                    Type        = STGenericMatTexture.TextureType.Diffuse,
                                    Name        = diffuseName,
                                });
                            }

                            if (SectionLookup.ContainsKey(SectionMagic.MaterialData))
                            {
                                var materialSecton = SectionLookup[SectionMagic.MaterialData];
                                reader.SeekBegin(materialSecton.Position + model.Meshes[i].MaterialOffset);

                                var renderedMesh = (RenderableMeshWrapper)Renderer.Meshes[i];
                                renderedMesh.Material = new STGenericMaterial();

                                switch (model.Meshes[i].MaterailPreset)
                                {
                                case MaterailPresets.EnvDiffuseDamage:
                                {
                                    uint diffuseMapHashID = reader.ReadUInt32();
                                    uint diffuseMapParam  = reader.ReadUInt32();

                                    string diffuseName = diffuseMapHashID.ToString("X");
                                    if (HashList.ContainsKey(diffuseMapHashID))
                                    {
                                        diffuseName = HashList[diffuseMapHashID];
                                    }

                                    var texUnit = 1;
                                    renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture()
                                        {
                                            textureUnit = texUnit++,
                                            Type        = STGenericMatTexture.TextureType.Diffuse,
                                            Name        = diffuseName,
                                        });
                                }
                                break;

                                default:
                                {
                                    uint   diffuseMapHashID = reader.ReadUInt32();
                                    string diffuseName      = diffuseMapHashID.ToString("X");
                                    if (HashList.ContainsKey(diffuseMapHashID))
                                    {
                                        diffuseName = HashList[diffuseMapHashID];
                                    }

                                    var texUnit = 1;
                                    renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture()
                                        {
                                            textureUnit = texUnit++,
                                            Type        = STGenericMatTexture.TextureType.Diffuse,
                                            Name        = diffuseName,
                                        });
                                }
                                break;
                                }
                            }
                        }
                    }


                    List <BoneListEntry> BoneLists = new List <BoneListEntry>();

                    List <uint> boneHashOrder = new List <uint>();

                    TreeNode parentBoneList = new TreeNode("Bone List");
                    Nodes.Add(parentBoneList);

                    if (SectionLookup.ContainsKey(SectionMagic.SkeletonData))
                    {
                        var skeletonSection = SectionLookup[SectionMagic.SkeletonData];
                        reader.SeekBegin(skeletonSection.Position);

                        //Read all sub sections
                        while (reader.Position < skeletonSection.Position + skeletonSection.Size)
                        {
                            uint magic       = reader.ReadUInt32();
                            uint sectionSize = reader.ReadUInt32();

                            long          pos   = reader.Position;
                            BoneListEntry entry = new BoneListEntry();
                            BoneLists.Add(entry);

                            //Bone hashes appear for each mesh if it uses rigging
                            //Meshes index these lists for rigging
                            if ((SectionMagic)magic == SectionMagic.BoneHashes)
                            {
                                TreeNode boneListNode = new TreeNode("Mesh Bone List");
                                parentBoneList.Nodes.Add(boneListNode);

                                uint numHashes = sectionSize / 4;
                                for (int i = 0; i < numHashes; i++)
                                {
                                    entry.Hashes.Add(reader.ReadUInt32());
                                    if (IsGamecube)
                                    {
                                        reader.ReadUInt32();
                                    }

                                    string hashName = entry.Hashes[i].ToString("X");
                                    if (HashList.ContainsKey(entry.Hashes[i]))
                                    {
                                        hashName = HashList[entry.Hashes[i]];
                                    }

                                    boneListNode.Nodes.Add(hashName);
                                }
                            }
                            if ((SectionMagic)magic == SectionMagic.BoneData)
                            {
                                uint numBones = sectionSize / 68;
                                for (int i = 0; i < numBones; i++)
                                {
                                    reader.SeekBegin(pos + i * 68);
                                    BoneEntry bone = new BoneEntry();
                                    bone.HashID = reader.ReadUInt32();
                                    reader.ReadUInt32(); //unk
                                    reader.ReadUInt32(); //unk
                                    reader.ReadUInt32(); //unk
                                    reader.ReadSingle(); //0
                                    bone.Scale = new Vector3(
                                        reader.ReadSingle(),
                                        reader.ReadSingle(),
                                        reader.ReadSingle());
                                    reader.ReadSingle(); //0
                                    bone.Rotate = new Vector3(
                                        reader.ReadSingle(),
                                        reader.ReadSingle(),
                                        reader.ReadSingle());
                                    reader.ReadSingle(); //0
                                    bone.Translate = new Vector3(
                                        reader.ReadSingle(),
                                        reader.ReadSingle(),
                                        reader.ReadSingle());
                                    reader.ReadSingle(); //1

                                    //      bone.Translate = Vector3.TransformPosition(bone.Translate, TransformMatrix);

                                    entry.Bones.Add(bone);
                                }
                            }

                            reader.SeekBegin(pos + sectionSize);
                        }
                    }

                    List <BoneEntry> BoneListSorted = new List <BoneEntry>();
                    foreach (var hash in boneHashOrder)
                    {
                        foreach (var boneList in BoneLists)
                        {
                            foreach (var bone in boneList.Bones)
                            {
                                if (bone.HashID == hash)
                                {
                                    BoneListSorted.Add(bone);
                                }
                            }
                        }
                    }

                    STSkeleton skeleton = new STSkeleton();
                    DrawableContainer.Drawables.Add(skeleton);

                    foreach (var boneList in BoneLists)
                    {
                        foreach (var bone in boneList.Bones)
                        {
                            STBone stBone = new STBone(skeleton);
                            skeleton.bones.Add(stBone);
                            stBone.Text = bone.HashID.ToString("X");
                            if (HashList.ContainsKey(bone.HashID))
                            {
                                stBone.Text = HashList[bone.HashID];
                            }

                            stBone.Position      = bone.Translate;
                            stBone.EulerRotation = bone.Rotate;
                            stBone.Scale         = new Vector3(0.2f, 0.2f, 0.2f);

                            stBone.RotationType = STBone.BoneRotationType.Euler;
                        }
                    }


                    skeleton.reset();
                    skeleton.update();

                    TreeNode skeletonNode = new TreeNode("Skeleton");
                    Nodes.Add(skeletonNode);
                    foreach (var bone in skeleton.bones)
                    {
                        if (bone.Parent == null)
                        {
                            skeletonNode.Nodes.Add(bone);
                        }
                    }
                }
            }
        }