Beispiel #1
0
            public void Read(FileReader reader, LM2_ARCADE_Model root)
            {
                Skeleton         = new STSkeleton();
                DrawableRenderer = new GenericModelRenderer();
                root.DrawableContainer.Drawables.Add(Skeleton);
                root.DrawableContainer.Drawables.Add(DrawableRenderer);

                reader.ReadSignature(4, "VM61");
                ushort Type    = reader.ReadUInt16();
                ushort Unknown = reader.ReadUInt16();

                if (Type == 0)
                {
                }
                else if ((Type == 1))
                {
                    throw new Exception("Animation files not supported yet!");
                }
                else
                {
                    throw new Exception("Unknown type found! " + Type);
                }

                Alignment = reader.ReadUInt32();
                uint  Padding       = reader.ReadUInt32();
                ulong MaterialCount = reader.ReadUInt64();

                HeaderSize = reader.ReadUInt64();
                ulong TextureMapsCount  = reader.ReadUInt64();
                ulong TextureMapsOffset = reader.ReadUInt64();

                ulong BoneCount       = reader.ReadUInt64();
                ulong BoneOffset      = reader.ReadUInt64();
                ulong FirstNodeOffset = reader.ReadUInt64(); //Either an offset or the total size of section up to the node
                ulong LinkNodeCount   = reader.ReadUInt64();
                ulong LinkNodeOffset  = reader.ReadUInt64();
                ulong TotalNodeCount  = reader.ReadUInt64();
                ulong TotalNodeOffset = reader.ReadUInt64();
                ulong Padding2        = reader.ReadUInt64();

                root.Nodes.Add("Materials");
                root.Nodes.Add("Root");
                root.Nodes.Add("All Nodes");

                long pos = reader.Position;

                if (TextureMapsOffset != 0)
                {
                    reader.SeekBegin(TextureMapsOffset);
                    for (int i = 0; i < (int)TextureMapsCount; i++)
                    {
                        TextureMaps.Add(reader.ReadNameOffset(false, typeof(ulong)));
                    }
                }

                reader.SeekBegin(pos);
                for (int i = 0; i < (int)MaterialCount; i++)
                {
                    Material mat = new Material();
                    mat.Read(reader);
                    Materials.Add(mat);

                    var genericMat = new STGenericMaterial();
                    genericMat.Text = mat.Name;

                    for (int t = 0; t < mat.TextureIndices.Length; t++)
                    {
                        if (mat.TextureIndices[t] != -1)
                        {
                            Console.WriteLine("TextureIndices " + mat.TextureIndices[t]);
                            string Texture = TextureMaps[mat.TextureIndices[t]];

                            var textureMap = new STGenericMatTexture();
                            textureMap.Name = Texture;
                            genericMat.TextureMaps.Add(textureMap);

                            if (Texture.EndsWith("col.dds"))
                            {
                                textureMap.Type = STGenericMatTexture.TextureType.Diffuse;
                            }
                            if (Texture.EndsWith("col.mot"))
                            {
                                textureMap.Type = STGenericMatTexture.TextureType.Diffuse;
                            }
                        }
                    }

                    root.Nodes[0].Nodes.Add(genericMat);
                }

                if (TotalNodeCount != 0)
                {
                    for (int i = 0; i < (int)TotalNodeCount; i++)
                    {
                        reader.SeekBegin((int)TotalNodeOffset + (i * 16));

                        string NodeName = reader.ReadNameOffset(false, typeof(ulong));
                        var    Offset   = reader.ReadUInt64();

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

                        if (Offset != 0)
                        {
                            reader.SeekBegin(Offset);
                            Node node = new Node();
                            node.Name = NodeName;
                            node.Read(reader);
                            TotalNodes.Add(node);
                        }
                    }
                }

                if (BoneCount != 0)
                {
                    for (int i = 0; i < (int)BoneCount; i++)
                    {
                        reader.SeekBegin((int)BoneOffset + (i * 16));

                        string NodeName = reader.ReadNameOffset(false, typeof(ulong));
                        ulong  Offset   = reader.ReadUInt64();

                        if (Offset != 0)
                        {
                            reader.SeekBegin(Offset);
                            Node node = new Node();
                            node.Name = NodeName;
                            node.Read(reader);
                            BoneList.Add(node); //This list is for mapping to meshes
                        }
                    }
                }

                foreach (var node in TotalNodes)
                {
                    // TreeNode lowerWrapper = new TreeNode($"{node.Name}");
                    // root.Nodes[3].Nodes.Add(lowerWrapper);

                    LoadChildern(TotalNodes, node, root.Nodes[2]);
                }

                if (FirstNodeOffset != 0)
                {
                    reader.SeekBegin(FirstNodeOffset);
                    ulong NodeOffset = reader.ReadUInt64();
                    reader.SeekBegin(NodeOffset);
                    Node node = new Node();
                    node.Name = GetNodeName(TotalNodes, node);
                    node.Read(reader);

                    LoadBones(TotalNodes, node, root.Nodes[1]);
                }



                if (LinkNodeCount != 0)
                {
                    root.Nodes.Add("Links");

                    for (int i = 0; i < (int)LinkNodeCount; i++)
                    {
                        TreeNode linkWrapper = new TreeNode($"Link {i}");
                        root.Nodes[3].Nodes.Add(linkWrapper);

                        reader.SeekBegin((int)LinkNodeOffset + (i * 16));

                        ulong NodeOffset1 = reader.ReadUInt64();
                        ulong NodeOffset2 = reader.ReadUInt64();

                        reader.SeekBegin(NodeOffset1);
                        Node node1 = new Node();
                        node1.Name = GetNodeName(TotalNodes, node1);
                        node1.Read(reader);

                        reader.SeekBegin(NodeOffset2);
                        Node node2 = new Node();
                        node2.Name = GetNodeName(TotalNodes, node1);
                        node2.Read(reader);

                        //  LoadChildern(TotalNodes, node1, linkWrapper);
                        // LoadChildern(TotalNodes, node2, linkWrapper);

                        LinkNodes.Add(Tuple.Create(node1, node2));
                    }
                }

                Skeleton.update();
                Skeleton.reset();
            }
Beispiel #2
0
        public void Read(string fname)
        {
            StreamReader reader = File.OpenText(fname);
            string       line;

            string current = "";

            Bones = new STSkeleton();
            Dictionary <int, STBone> BoneList = new Dictionary <int, STBone>();

            int time = 0;

            while ((line = reader.ReadLine()) != null)
            {
                line = Regex.Replace(line, @"\s+", " ");
                string[] args = line.Replace(";", "").TrimStart().Split(' ');

                if (args[0].Equals("triangles") || args[0].Equals("end") || args[0].Equals("skeleton") || args[0].Equals("nodes"))
                {
                    current = args[0];
                    continue;
                }

                if (current.Equals("nodes"))
                {
                    int    id = int.Parse(args[0]);
                    STBone b  = new STBone(Bones);
                    b.Text = args[1].Replace('"', ' ').Trim();
                    int s = 2;
                    while (args[s].Contains("\""))
                    {
                        b.Text += args[s++];
                    }
                    b.parentIndex = int.Parse(args[s]);
                    BoneList.Add(id, b);
                }

                if (current.Equals("skeleton"))
                {
                    if (args[0].Contains("time"))
                    {
                        time = int.Parse(args[1]);
                    }
                    else
                    {
                        if (time == 0)
                        {
                            STBone b = BoneList[int.Parse(args[0])];
                            b.Position = new Vector3(
                                float.Parse(args[1]),
                                float.Parse(args[2]),
                                float.Parse(args[3]));
                            b.EulerRotation = new Vector3(
                                float.Parse(args[4]),
                                float.Parse(args[5]),
                                float.Parse(args[6]));
                            b.Scale = Vector3.One;

                            b.pos = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
                            b.rot = STSkeleton.FromEulerAngles(float.Parse(args[6]), float.Parse(args[5]), float.Parse(args[4]));

                            Bones.bones.Add(b);

                            if (b.parentIndex != -1)
                            {
                                b.parentIndex = Bones.bones.IndexOf(BoneList[b.parentIndex]);
                            }
                        }
                    }
                }
            }
            Bones.reset();
        }
Beispiel #3
0
        public void NextFrame(STSkeleton skeleton, bool isChild = false, bool AdancedNextFrame = false, string bn = "")
        {
            if (Frame > FrameCount)
            {
                return;
            }

            if (Frame == 0 && !isChild)
            {
                skeleton.reset();
            }

            foreach (object child in Children)
            {
                if (child is Animation)
                {
                    ((Animation)child).SetFrame(Frame);
                    ((Animation)child).NextFrame(skeleton, isChild, AdancedNextFrame);
                }
            }

            bool Updated = false; // no need to update skeleton of animations that didn't change

            foreach (KeyNode node in Bones)
            {
                // Get Skeleton Node
                STBone b = null;
                b = skeleton.GetBone(node.Text);
                if (b == null)
                {
                    continue;
                }

                if (bn != "" && bn != node.Text)
                {
                    continue;                              //If a bone name is provided, skip any bones that aren't that bone.
                }
                b.UseSegmentScaleCompensate = node.UseSegmentScaleCompensate;

                Updated = true;

                if (node.XPOS.HasAnimation())
                {
                    b.pos.X = node.XPOS.GetValue(Frame);
                }
                if (node.YPOS.HasAnimation())
                {
                    b.pos.Y = node.YPOS.GetValue(Frame);
                }
                if (node.ZPOS.HasAnimation())
                {
                    b.pos.Z = node.ZPOS.GetValue(Frame);
                }

                if (node.XSCA.HasAnimation())
                {
                    b.sca.X = node.XSCA.GetValue(Frame);
                }
                else
                {
                    b.sca.X = 1;
                }
                if (node.YSCA.HasAnimation())
                {
                    b.sca.Y = node.YSCA.GetValue(Frame);
                }
                else
                {
                    b.sca.Y = 1;
                }
                if (node.ZSCA.HasAnimation())
                {
                    b.sca.Z = node.ZSCA.GetValue(Frame);
                }
                else
                {
                    b.sca.Z = 1;
                }


                if (node.XROT.HasAnimation() || node.YROT.HasAnimation() || node.ZROT.HasAnimation())
                {
                    if (node.RotType == RotationType.QUATERNION)
                    {
                        KeyFrame[] x  = node.XROT.GetFrame(Frame);
                        KeyFrame[] y  = node.YROT.GetFrame(Frame);
                        KeyFrame[] z  = node.ZROT.GetFrame(Frame);
                        KeyFrame[] w  = node.WROT.GetFrame(Frame);
                        Quaternion q1 = new Quaternion(x[0].Value, y[0].Value, z[0].Value, w[0].Value);
                        Quaternion q2 = new Quaternion(x[1].Value, y[1].Value, z[1].Value, w[1].Value);
                        if (x[0].Frame == Frame)
                        {
                            b.rot = q1;
                        }
                        else
                        if (x[1].Frame == Frame)
                        {
                            b.rot = q2;
                        }
                        else
                        {
                            b.rot = Quaternion.Slerp(q1, q2, (Frame - x[0].Frame) / (x[1].Frame - x[0].Frame));
                        }
                    }
                    else
                    if (node.RotType == RotationType.EULER)
                    {
                        float x = node.XROT.HasAnimation() ? node.XROT.GetValue(Frame) : b.EulerRotation.X;
                        float y = node.YROT.HasAnimation() ? node.YROT.GetValue(Frame) : b.EulerRotation.Y;
                        float z = node.ZROT.HasAnimation() ? node.ZROT.GetValue(Frame) : b.EulerRotation.Z;
                        b.rot = EulerToQuat(z, y, x);
                    }
                }
            }

            if (AdancedNextFrame)
            {
                Frame++;
                if (Frame > FrameCount)
                {
                    Frame = 0;
                }
            }

            if (!isChild && Updated)
            {
                skeleton.update();
            }
        }
Beispiel #4
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);
                        }
                    }
                }
            }
        }
Beispiel #5
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]);
                    }
                }
            }
        }
Beispiel #6
0
        public void Load(System.IO.Stream stream)
        {
            CanSave = true;

            Text = FileName;

            //Set renderer
            //Load it to a drawables list
            Renderer = new MDL_Renderer();
            Skeleton = new STSkeleton();
            DrawableContainer.Name = FileName;
            DrawableContainer.Drawables.Add(Renderer);
            DrawableContainer.Drawables.Add(Skeleton);

            using (var reader = new FileReader(stream))
            {
                reader.SetByteOrder(true);

                string[] JointNames = new string[0];
                Joint[]  Joints     = new Joint[0];
                Envelopes = new Envelope[0];
                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 ((ChunkNames)opcode)
                    {
                    case ChunkNames.VertexPosition:
                        Vertices = ReadVector3Array(reader);
                        break;

                    case ChunkNames.VertexNormal:
                        VertexNormals = ReadVector3Array(reader);
                        break;

                    case ChunkNames.VertexColor:
                        Colors = ReadVertexColors(reader);
                        break;

                    case ChunkNames.Mesh:
                        ReadMeshChunk(reader);
                        break;

                    case ChunkNames.Envelope:
                        Envelopes = ParseArray <Envelope>(reader);
                        break;

                    case ChunkNames.JointName:
                        JointNames = ReadStrings(reader);
                        break;

                    case ChunkNames.Joint:
                        Joints = ParseArray <Joint>(reader);
                        break;

                    default:
                        reader.Seek(lengthOfStruct, System.IO.SeekOrigin.Current);
                        break;
                    }
                }

                for (int i = 0; i < Joints.Length; i++)
                {
                    STBone bone = new STBone(Skeleton);
                    bone.parentIndex   = Joints[i].ParentIndex;
                    bone.Position      = Joints[i].Position;
                    bone.EulerRotation = Joints[i].Rotation;
                    bone.Scale         = Joints[i].Scale;
                    Skeleton.bones.Add(bone);
                }
                Skeleton.reset();
                Skeleton.update();

                foreach (var mesh in Renderer.Meshes)
                {
                    for (int v = 0; v < mesh.vertices.Count; v++)
                    {
                        var vertex = mesh.vertices[v];
                        if (vertex.boneIds.Count == 1)
                        {
                            var transform = Skeleton.bones[vertex.boneIds[0]].Transform;
                            vertex.pos = Vector3.TransformPosition(vertex.pos, transform);
                        }
                    }
                }
            }
        }
Beispiel #7
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);
                }
            }
        }
Beispiel #8
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;
                            }
                        }
                    }
                }
            }
        }