示例#1
0
        public GenericMesh DisplayListToGenericMesh(N64DisplayList DL)
        {
            GenericMesh mesh = new GenericMesh();

            mesh.Name = "Mesh" + DL.faces.Count;

            foreach (int f in DL.faces)
            {
                mesh.Triangles.Add((uint)f);
            }

            foreach (N64Vertex_Normal nv in DL.verts)
            {
                mesh.Vertices.Add(new GenericVertex()
                {
                    Pos     = nv.pos,
                    Nrm     = nv.color.Xyz,
                    UV0     = nv.uv,
                    Bones   = new Vector4(nv.bone, 0, 0, 0),
                    Weights = new Vector4(1, 0, 0, 0)
                });
            }

            return(mesh);
        }
示例#2
0
        private static GenericMesh ReadMesh(DataReader r, uint infoOffset, uint bufferOffset)
        {
            GenericMesh mesh = new GenericMesh();

            var meshEntry = r.ReadStruct <Entry>();

            if (meshEntry.ID == 4)
            {
                r.Seek(infoOffset + meshEntry.Offset);
                var lodCount = r.ReadInt32();

                r.Seek(infoOffset + meshEntry.Offset + 0x10);
                r.PrintPosition();
                var indexEntryIndex = r.ReadUInt32();

                r.Seek(0x30 + indexEntryIndex * 0x10);
                var indexInfoEntry = r.ReadStruct <Entry>();

                r.Seek(infoOffset + indexInfoEntry.Offset + 4);
                var indexBufferEntryIndex = r.ReadUInt32();

                r.Seek(0x30 + indexBufferEntryIndex * 0x10);
                var indexBufferEntry = r.ReadStruct <Entry>();

                r.Seek(infoOffset + indexBufferEntry.Offset);
                r.PrintPosition();
                var indexDataBufferEntry = r.ReadStruct <Entry>();

                if (indexBufferEntry.Flags == 0x010A || lodCount > 1)
                {
                    return(null);
                }

                r.Seek(bufferOffset + indexDataBufferEntry.Offset);
                for (uint j = 0; j < indexDataBufferEntry.Size / 0x20; j++)
                {
                    GenericVertex v = new GenericVertex();
                    v.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                    r.Skip(0x14);
                    mesh.Vertices.Add(v);
                    mesh.Triangles.Add(j);
                }

                Console.WriteLine(meshEntry.Hash.ToString("X") + " " + meshEntry.ID);
                Console.WriteLine("\t" + lodCount + " " + indexBufferEntry.Flags.ToString("X") + " " + (bufferOffset + indexDataBufferEntry.Offset).ToString("X"));


                /*r.Seek(infoOffset + meshEntry.Offset + 0x30);
                 * var vertexEntryIndex = r.ReadUInt32();
                 *
                 * r.Seek(0x30 + vertexEntryIndex * 0x10 + 0x08);
                 * var vertexBufferEntryIndex = r.ReadUInt32();
                 *
                 * r.Seek(0x30 + indexBufferEntryIndex * 0x10);
                 * r.Seek(0x30 + indexBufferEntryIndex * 0x10);*/
                return(mesh);
            }

            return(null);
        }
示例#3
0
        public GenericModel ToGenericModel()
        {
            var model = new GenericModel();

            var verts = GetVertexData();

            int indexOffset  = 0;
            int vertexOffset = 0;

            foreach (var m in Mesh.SubMesh)
            {
                var mesh = new GenericMesh();
                mesh.Name = m.FirstVertex + "_Mesh";
                model.Meshes.Add(mesh);

                for (int f = 0; f < m.IndexCount; f++)
                {
                    mesh.Triangles.Add(Mesh.IndexBuffer[indexOffset + f]);
                }

                for (int v = 0; v < m.VertexCount; v++)
                {
                    mesh.Vertices.Add(verts[v + vertexOffset]);
                }

                indexOffset  += m.IndexCount;
                vertexOffset += m.VertexCount;
            }



            return(model);
        }
示例#4
0
文件: MES.cs 项目: ST3RmY/Metanoia
        public void Open(FileItem file)
        {
            model.Skeleton = new GenericSkeleton();
            using (DataReader r = new DataReader(file))
            {
                r.BigEndian = false;

                r.Seek(0xCC);

                var somecount    = r.ReadInt32();
                var section1Size = r.ReadInt32();
                var section2Size = r.ReadInt32();
                r.ReadInt16();
                var section3Size = r.ReadInt32();
                r.Skip(0x0A);
                var section4Size = r.ReadInt32();
                var section5Size = r.ReadInt32();
                r.Skip(0x18);
                r.Skip((uint)section1Size);

                var mesh = new GenericMesh();
                mesh.Name = "mesh1";
                model.Meshes.Add(mesh);
                for (int i = 0; i < section2Size / 4; i++)
                {
                    var v1 = r.ReadSByte();
                    var v2 = r.ReadSByte();
                    var v3 = r.ReadSByte();
                    var v4 = (float)r.ReadByte() / 255f;

                    var v = new GenericVertex()
                    {
                        Pos = new OpenTK.Vector3(v1, v2, v3) * v4,
                        Clr = new OpenTK.Vector4(1, 1, 1, 1)
                    };
                    if (float.IsNaN(v.Pos.X) || float.IsInfinity(v.Pos.Y))
                    {
                        v.Pos = new OpenTK.Vector3();
                    }
                    mesh.Vertices.Add(v);
                    Console.WriteLine(v.Pos.ToString());
                }
                mesh.PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip;
                for (uint i = 0; i < mesh.Vertices.Count; i++)
                {
                    mesh.Triangles.Add(i);
                }

                for (int i = 0; i < section3Size / 12; i++)
                {
                    Console.WriteLine(r.ReadHalfSingle() + " " + r.ReadHalfSingle() + " " + r.ReadHalfSingle()
                                      + " " + r.ReadInt16().ToString("X") + " " + r.ReadHalfSingle() + " " + r.ReadHalfSingle());
                }
            }
        }
 /// <summary>
 ///     Draws the mesh while forcing a primitive type instead of using the mesh type.
 /// </summary>
 /// <param name="modelType">The type, as what the object should be rendered.</param>
 /// <param name="mesh">The mesh.</param>
 /// <param name="amount">The amounts for instancing.</param>
 public static void DrawObject(PrimitiveType modelType, GenericMesh mesh, int amount = 1)
 {
     if (mesh.Indices != null)
     {
         GL.DrawElementsInstanced(modelType, 0, DrawElementsType.UnsignedInt, mesh.Indices, amount);
     }
     else
     {
         GL.DrawArraysInstanced(modelType, 0, mesh.Vertex.Count, amount);
     }
 }
示例#6
0
        public GenericMesh ToGenericMesh()
        {
            GenericMesh mesh = new GenericMesh();

            mesh.Name         = Name;
            mesh.MaterialName = MaterialName;

            mesh.Triangles = ParseIndexBuffer(PolygonVertexIndexBuffer);
            mesh.Vertices  = ParseBuffer(PolygonVertexBuffer);

            return(mesh);
        }
示例#7
0
        public GenericModel ToGenericModel()
        {
            var model = new GenericModel();

            model.Skeleton = skeleton;

            var mesh = new GenericMesh();

            for (int i = 0; i < PositionBuffer.Length; i++)
            {
                var vertex = new GenericVertex()
                {
                    Pos = PositionBuffer[i].Xyz
                };
                if (UV0Buffer.Length == PositionBuffer.Length)
                {
                    vertex.UV0 = UV0Buffer[i];
                }
                if (UV1Buffer.Length == PositionBuffer.Length)
                {
                    vertex.UV1 = UV1Buffer[i];
                }
                if (UV2Buffer.Length == PositionBuffer.Length)
                {
                    vertex.UV2 = UV2Buffer[i];
                }
                mesh.Vertices.Add(vertex);
            }

            List <short> tris = new List <short>();

            tris.AddRange(IndexBuffer);
            TriangleConverter.StripToList(tris, out tris);

            short max = 0;

            foreach (var t in tris)
            {
                if (t > mesh.VertexCount)
                {
                    break;
                }
                max = Math.Max(max, t);
                mesh.Triangles.Add((uint)t);
            }

            Console.WriteLine(max.ToString("X") + " " + mesh.VertexCount.ToString("X"));

            model.Meshes.Add(mesh);

            return(model);
        }
示例#8
0
文件: PTE.cs 项目: ST3RmY/Metanoia
        private void ReadPolygons(DataReader reader)
        {
            uint polyStartOffset = reader.Position;

            reader.Position += 0x14;
            uint uvOffset           = polyStartOffset + reader.ReadUInt32();
            uint triangleOffset     = polyStartOffset + reader.ReadUInt32();
            uint uvTriangledataSize = polyStartOffset + reader.ReadUInt32();
            int  polyCount          = reader.ReadInt16();

            reader.ReadInt16();
            uint polyOffset = polyStartOffset + reader.ReadUInt32();

            reader.Seek(polyOffset);
            for (int i = 0; i < polyCount; i++)
            {
                reader.PrintPosition();
                var polyStruct = reader.ReadStruct <PolyStruct>();

                var mesh = new GenericMesh();
                Meshes.Add(mesh);
                mesh.Name = "Mesh_" + i;

                var temp = reader.Position;
                reader.Position = (uint)(triangleOffset + 3);
                Console.WriteLine(mesh.Name);

                for (int j = 0; j < polyStruct.FCount; j++)
                {
                    var v   = new GenericVertex();
                    var pos = Vertices[reader.ReadInt16()];
                    v.Pos     = pos.Pos;
                    v.Nrm     = pos.Nrm;
                    v.Bones   = pos.Bones;
                    v.Weights = pos.Weights;

                    //TODO: uv and ?color?
                    reader.ReadInt16(); // uv
                    reader.ReadInt16(); // color

                    mesh.Vertices.Add(v);
                }

                mesh.Optimize();

                reader.Position = temp;

                triangleOffset += polyStruct.SectionSize;
            }
        }
示例#9
0
文件: HSD.cs 项目: ST3RmY/Metanoia
        private void ParseDOBJs(IHSDNode node, HSD_JOBJ parent, List <HSD_JOBJ> BoneList)
        {
            if (node is HSD_JOBJ jobj)
            {
                if (jobj.DOBJ != null)
                {
                    foreach (var child in jobj.DOBJ.List)
                    {
                        ParseDOBJs(child, jobj, BoneList);
                    }
                }
                foreach (var child in jobj.Children)
                {
                    ParseDOBJs(child, child, BoneList);
                }
            }
            if (node is HSD_DOBJ dobj)
            {
                Console.WriteLine("DOBJ found");
                GenericMesh mesh = new GenericMesh();
                mesh.Name = "Mesh_" + outModel.Meshes.Count;

                GenericMaterial mat = new GenericMaterial();
                mesh.MaterialName = "material_" + outModel.MaterialBank.Count;
                outModel.MaterialBank.Add(mesh.MaterialName, mat);

                var Xscale = 1;
                var Yscale = 1;

                if (dobj.MOBJ != null)
                {
                    if (dobj.MOBJ.Textures != null)
                    {
                        var tobj = dobj.MOBJ.Textures;

                        mat.SWrap = GXTranslator.toWrapMode(tobj.WrapS);
                        mat.TWrap = GXTranslator.toWrapMode(tobj.WrapT);

                        Xscale = tobj.WScale;
                        Yscale = tobj.HScale;

                        if (!tobjToIndex.ContainsKey(tobj.ImageData.Data))
                        {
                            Bitmap B = null;
                            if (tobj.ImageData != null)
                            {
                                if (tobj.Tlut != null)
                                {
                                    B = TPL.ConvertFromTextureMelee(tobj.ImageData.Data, tobj.ImageData.Width, tobj.ImageData.Height, (int)tobj.ImageData.Format, tobj.Tlut.Data, tobj.Tlut.ColorCount, (int)tobj.Tlut.Format);
                                }
                                else
                                {
                                    B = TPL.ConvertFromTextureMelee(tobj.ImageData.Data, tobj.ImageData.Width, tobj.ImageData.Height, (int)tobj.ImageData.Format, null, 0, 0);
                                }
                            }
                            GenericTexture t = new GenericTexture();
                            t.FromBitmap(B);
                            B.Dispose();

                            tobjToIndex.Add(tobj.ImageData.Data, outModel.TextureBank.Count);
                            outModel.TextureBank.Add("texture_" + outModel.TextureBank.Count, t);
                        }

                        mat.TextureDiffuse = outModel.TextureBank.Keys.ToArray()[tobjToIndex[tobj.ImageData.Data]];
                    }
                }

                outModel.Meshes.Add(mesh);
                if (dobj.POBJ != null)
                {
                    foreach (HSD_POBJ pobj in dobj.POBJ.List)
                    {
                        // Decode the Display List Data
                        GXDisplayList DisplayList  = new GXDisplayList(pobj.DisplayListBuffer, pobj.VertexAttributes);
                        var           Vertices     = ToGenericVertex(VertexAccessor.GetDecodedVertices(pobj), BoneList, pobj.BindGroups != null ? new List <HSD_JOBJWeight>(pobj.BindGroups.Elements) : null, parent);
                        int           bufferOffset = 0;
                        foreach (GXPrimitiveGroup g in DisplayList.Primitives)
                        {
                            var primitiveType = GXTranslator.toPrimitiveType(g.PrimitiveType);

                            var strip = new List <GenericVertex>();
                            for (int i = bufferOffset; i < bufferOffset + g.Count; i++)
                            {
                                strip.Add(Vertices[i]);
                            }
                            bufferOffset += g.Count;

                            switch (primitiveType)
                            {
                            case OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip:
                                Tools.TriangleConverter.StripToList(strip, out strip);
                                break;

                            case OpenTK.Graphics.OpenGL.PrimitiveType.Quads:
                                Tools.TriangleConverter.QuadToList(strip, out strip);
                                break;

                            case OpenTK.Graphics.OpenGL.PrimitiveType.Triangles:
                                break;

                            default:
                                Debug.WriteLine("Error converting primitive type " + primitiveType);
                                break;
                            }

                            mesh.Vertices.AddRange(strip);
                        }
                    }
                }

                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    var vert = mesh.Vertices[i];
                    vert.UV0         = new Vector2(vert.UV0.X * Xscale, vert.UV0.Y * Yscale);
                    mesh.Vertices[i] = vert;
                }
                mesh.Optimize();
                Tools.TriangleConverter.ReverseFaces(mesh.Triangles, out mesh.Triangles);
            }
        }
示例#10
0
        public void Open(FileItem File)
        {
            using (DataReader r = new DataReader(File))
            {
                r.BigEndian = false;
                r.Seek(0x34);
                var skelTableOffset = r.Position + r.ReadUInt32();

                Model          = new GenericModel();
                Model.Skeleton = new GenericSkeleton();
                r.Seek(skelTableOffset + 8);
                var boneCount = r.ReadInt32();
                for (int i = 0; i < boneCount; i++)
                {
                    var temp = r.Position + 4;
                    r.Seek(r.Position + r.ReadUInt32());
                    //r.PrintPosition();
                    var unk1 = r.ReadInt32();
                    var unk2 = r.ReadInt32();

                    GenericBone bone = new GenericBone();
                    bone.Transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                        r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                        r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                        r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                    var boneInfoOffset = r.Position + r.ReadUInt32();
                    var boneFlag       = r.ReadInt32();
                    var parentCount    = r.ReadInt32();
                    var childCount     = r.ReadUInt32();
                    r.Skip(4 * childCount); // parent count intofmration

                    r.Seek(boneInfoOffset);
                    var parentName = r.ReadString(r.ReadInt32());
                    r.Skip(1); r.Align(4);
                    bone.Name = r.ReadString(r.ReadInt32());
                    r.Skip(1); r.Align(4);

                    if (parentName != "")
                    {
                        bone.ParentIndex = Model.Skeleton.IndexOf(Model.Skeleton.Bones.Find(e => e.Name == parentName));
                    }

                    Model.Skeleton.Bones.Add(bone);

                    r.Seek(temp);
                }

                r.Seek(0x48);
                var objectCount = r.ReadInt32();
                var unkOffset   = r.Position + r.ReadUInt32();
                var vcount      = 0;
                for (int i = 0; i < objectCount - 1; i++)
                {
                    GenericMesh mesh = new GenericMesh();
                    Model.Meshes.Add(mesh);

                    var temp = r.Position + 4;
                    r.Seek(r.Position + r.ReadUInt32());
                    r.Skip(8);
                    mesh.Name = r.ReadString(r.Position + r.ReadUInt32() + 4, -1);
                    var nameOff2      = r.Position + r.ReadUInt32();
                    var parentBoneOff = r.Position + r.ReadUInt32();
                    mesh.MaterialName = r.ReadString(r.Position + r.ReadUInt32() + 12, -1);
                    var transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                       r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                       r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                       r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                    var boneTableOffset = r.Position + r.ReadUInt32(); // bonetable offset
                    r.ReadInt32();                                     // some matrix table?

                    r.Skip(0x18);                                      // floats

                    var somecount        = r.ReadInt32();
                    var indexTableOffset = r.Position + r.ReadUInt32();
                    var attributeBuffer  = r.Position + r.ReadUInt32();
                    var vertCount        = r.ReadInt32();
                    var primType         = r.ReadInt32();
                    var unkownOffset2    = r.ReadUInt32();

                    if (unkownOffset2 > 0xFFFF)
                    {
                        r.ReadInt32();
                    }
                    else
                    {
                        r.ReadInt16();
                    }

                    var t = r.Position;
                    r.Seek(attributeBuffer);
                    var attributes = r.ReadStructArray <AttributeBuffer>(r.ReadInt32());
                    foreach (var a in attributes)
                    {
                        Console.WriteLine(a.Format + " " + a.Type + " " + a.Size);
                    }
                    r.Seek(t);

                    for (int v = 0; v < vertCount; v++)
                    {
                        var vert = new GenericVertex();

                        foreach (var a in attributes)
                        {
                            float[] values = new float[a.Size];
                            for (int vi = 0; vi < values.Length; vi++)
                            {
                                switch (a.Format)
                                {
                                case 0x00:
                                    values[vi] = r.ReadSingle();
                                    break;

                                case 0x07:
                                    values[vi] = r.ReadInt16() / (float)short.MaxValue;
                                    break;

                                case 0x06:
                                    values[vi] = r.ReadSByte();
                                    break;

                                case 0x0B:
                                    values[vi] = r.ReadUInt16() / (float)ushort.MaxValue;
                                    break;

                                case 0x0E:
                                    values[vi] = r.ReadByte() / (float)255;
                                    break;

                                default:
                                    throw new NotSupportedException("Unknown Attribute Format " + a.Format);
                                }
                            }

                            switch (a.Type)
                            {
                            case 0:
                                vert.Pos = new OpenTK.Vector3(values[0], values[1], values[2]);
                                break;

                            case 1:
                                vert.Clr = new OpenTK.Vector4(values[0], values[1], values[2], values[3]);
                                break;

                            case 3:
                                vert.UV0 = new OpenTK.Vector2(values[0], values[1]);
                                break;

                            case 15:
                                vert.Bones = new OpenTK.Vector4(values[0], values[1], values[2], values[3]);
                                break;

                            case 16:
                                vert.Weights = new OpenTK.Vector4(values[0], values[1], values[2], values[3]);
                                break;
                                //default:
                                //    throw new NotSupportedException("Unknown vertex attribute " + a.Type);
                            }
                        }

                        mesh.Vertices.Add(vert);
                    }

                    r.Seek(indexTableOffset);
                    var indexBufferSize = r.ReadInt32();
                    var indexCount      = (indexBufferSize - 6) / 2;
                    if (indexBufferSize > 0xFFFF)
                    {
                        r.ReadInt32();
                    }
                    else
                    {
                        r.ReadInt16();
                    }

                    for (int j = 0; j < indexCount; j++)
                    {
                        var v = r.ReadUInt16();
                        mesh.Triangles.Add(mesh.VertexCount < 0xFF ? (uint)(v & 0xFF) : v);
                    }

                    //r.PrintPosition();
                    Console.WriteLine(mesh.Name + " " + mesh.VertexCount.ToString("X") + " " + mesh.Triangles.Min().ToString("X") + " " + mesh.Triangles.Max().ToString("X"));
                    //mesh.PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip;

                    r.Seek(temp);
                }
            }
        }
示例#11
0
        public void Open(FileItem File)
        {
            var igb = new IGBFile(File.GetFileBinary());

            var igbSkel = new IGSkeleton(igb);

            Matrix4[] transforms = new Matrix4[igbSkel.Bones.Count];
            Matrix4[] inverts = new Matrix4[igbSkel.Bones.Count];
            int boneIndex = 0;
            foreach (var v in igbSkel.Bones)
            {
                if (v == null)
                    continue;
                GenericBone b = new GenericBone();
                b.Name = v.Name;
                b.ParentIndex = v.ParentIndex;
                transforms[boneIndex] = new Matrix4(
                    v.WorldInverseMatrix.M11, v.WorldInverseMatrix.M12, v.WorldInverseMatrix.M13, v.WorldInverseMatrix.M14,
                    v.WorldInverseMatrix.M21, v.WorldInverseMatrix.M22, v.WorldInverseMatrix.M23, v.WorldInverseMatrix.M24,
                    v.WorldInverseMatrix.M31, v.WorldInverseMatrix.M32, v.WorldInverseMatrix.M33, v.WorldInverseMatrix.M34,
                    v.WorldInverseMatrix.M41, v.WorldInverseMatrix.M42, v.WorldInverseMatrix.M43, v.WorldInverseMatrix.M44);
                inverts[boneIndex] = transforms[boneIndex].Inverted();
                b.Transform = inverts[boneIndex];

                boneIndex++;
                Skeleton.Bones.Add(b);
            }
            
            foreach (var b in Skeleton.Bones)
            {
                if (b.ParentIndex != -1)
                {
                    b.Transform = inverts[b.ParentIndex] * transforms[Skeleton.Bones.IndexOf(b)];
                    b.Transform = b.Transform.Inverted();
                    var position = igbSkel.Bones[Skeleton.Bones.IndexOf(b)].Position;
                    b.Position = new Vector3(position.X, position.Y, position.Z);
                }
            }

            var vertexBuffers = IGVertexAccessor.ToDivaModels(igb);

            Model.Skeleton = Skeleton;

            Console.WriteLine(vertexBuffers.Count);
            foreach (var model in vertexBuffers)
            {
                GenericMesh m = new GenericMesh();
                m.Name = model.Name;
                if (m.Name.Equals(""))
                    m.Name = "Mesh_" + vertexBuffers.IndexOf(model);
                Console.WriteLine(m.Name + " " + !(model.Texture==null));

                if(model.Texture != null)
                {
                    GenericTexture t = new GenericTexture();
                    t.Name = System.IO.Path.GetFileNameWithoutExtension(model.Texture.Name);
                    t.Width = (uint)model.Texture.Width;
                    t.Height = (uint)model.Texture.Height;
                    t.Mipmaps.Add(model.Texture.RGBA);

                    if(!Model.MaterialBank.ContainsKey(t.Name))
                        Model.TextureBank.Add(t.Name, t);

                    GenericMaterial mat = new GenericMaterial();
                    mat.TextureDiffuse = t.Name;

                    if (!Model.MaterialBank.ContainsKey(t.Name))
                        Model.MaterialBank.Add(t.Name, mat);

                    m.MaterialName = t.Name;
                }
                
                foreach (var mesh in model.Mesh)
                {
                    var vertices = ToGenericVertices(mesh.Vertices);
                    foreach (var dl in mesh.DisplayList)
                    {
                        if (dl.PrimitiveType == PrimType.Triangles)
                        {
                            foreach(var f in dl.Indices)
                                m.Vertices.Add(vertices[f]);
                        }
                        if (dl.PrimitiveType == PrimType.TriangleStrip)
                        {
                            var tempList = new List<GenericVertex>();
                            foreach (var f in dl.Indices)
                                tempList.Add(vertices[f]);
                            Tools.TriangleConverter.StripToList(tempList, out tempList);
                            m.Vertices.AddRange(tempList);
                        }
                    }
                }
                

                if(model.SingleBindBone != null && model.SingleBindBone != "")
                {
                    var singleBone = Skeleton.Bones.Find(e => e.Name.Equals(model.SingleBindBone));
                    var singleBindTransform = Skeleton.GetWorldTransform(singleBone);
                    var singleBindIndex = Skeleton.Bones.IndexOf(singleBone);
                    for (int i = 0; i < m.VertexCount;i++)
                    {
                        var vert = m.Vertices[i];
                        vert.Pos = Vector3.TransformPosition(vert.Pos, singleBindTransform);
                        vert.Nrm = Vector3.TransformNormal(vert.Nrm, singleBindTransform);
                        vert.Bones = new Vector4(singleBindIndex, 0, 0, 0);
                        vert.Weights = new Vector4(1, 0, 0, 0);
                        m.Vertices[i] = vert;
                    }
                }

                m.Optimize();

                Model.Meshes.Add(m);
            }
        }
示例#12
0
        public void Open(FileItem file)
        {
            using (DataReader r = new DataReader(file))
            {
                r.BigEndian = true;

                r.Skip(0xC); // magic

                var faceOffset      = r.ReadUInt32();
                var faceLength      = r.ReadInt32();
                var vertexLength    = r.ReadInt32();
                var boneTableOffset = r.ReadUInt32();
                r.ReadInt32(); // some flag usually 1

                var vertOffset  = r.ReadUInt32();
                var faceOffset2 = r.ReadUInt32();
                r.ReadInt32(); // some flag usually 1
                var nameCount = r.ReadInt32();

                var boneCount      = r.ReadInt32();
                var polyCount      = r.ReadInt32();
                var matLength      = r.ReadInt32();
                var polyNameCount2 = r.ReadInt32();

                var polyNameCount3  = r.ReadInt32();
                var boneTableCount  = r.ReadInt32();
                var boneTableCount2 = r.ReadInt32();
                var stringCount     = r.ReadInt32();

                var UnkOffset      = r.ReadInt32();
                var unk            = r.ReadInt32();
                var boneOffset     = r.ReadUInt32();
                var polyInfoOffset = r.ReadUInt32();

                var materialOffset  = r.ReadUInt32();
                var unkOffset2      = r.ReadUInt32();
                var materialOffset2 = r.ReadUInt32();
                var matrixOffset    = r.ReadUInt32();

                r.ReadInt32(); //  same matrix offset
                var stringOffset = r.ReadInt32();

                r.Seek(boneOffset);
                for (int i = 0; i < boneCount; i++)
                {
                    GenericBone bone = new GenericBone();
                    bone.Name = r.ReadString(r.ReadUInt32(), -1);
                    r.ReadInt32(); // hash
                    var parentName = r.ReadString(r.ReadUInt32(), -1);
                    r.ReadInt32(); // hash

                    r.Skip(0x14);  // various unimportant stuff

                    var pos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                    var sca = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                    r.Skip(0x14); // various unimportant stuff

                    var inverseMatrix = new Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                    r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                    r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                                    r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                    var matrix = new Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                             r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                             r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(),
                                             r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                    r.Skip(0xC); // various unimportant stuff

                    bone.Transform = inverseMatrix.Inverted();
                    bone.Position  = pos;

                    bone.ParentIndex = Skeleton.Bones.FindIndex(e => e.Name == parentName);

                    Skeleton.Bones.Add(bone);
                }

                r.Seek(materialOffset);
                for (int i = 0; i < matLength / 6; i++)
                {
                    GenericMaterial mat = new GenericMaterial();

                    r.PrintPosition();

                    var name = r.ReadString(r.ReadUInt32(), -1);
                    if (name == "")
                    {
                        name = "null";
                    }
                    r.Skip(0x110);
                    mat.TextureDiffuse = r.ReadString(r.ReadUInt32(), -1);
                    r.Skip(0x110);

                    if (Generic.MaterialBank.ContainsKey(name))
                    {
                        name += "_" + i;
                    }

                    if (!Generic.TextureBank.ContainsKey(mat.TextureDiffuse))
                    {
                        Generic.TextureBank.Add(mat.TextureDiffuse, new GenericTexture()
                        {
                            Name = mat.TextureDiffuse
                        });
                    }

                    Generic.MaterialBank.Add(name, mat);
                }

                r.Seek(faceOffset);
                var Indices = new ushort[faceLength / 2];
                for (int i = 0; i < Indices.Length; i++)
                {
                    Indices[i] = r.ReadUInt16();
                }

                r.Seek(vertOffset);
                var Vertices = new GenericVertex[vertexLength / 44];
                for (int i = 0; i < Vertices.Length; i++)
                {
                    Vertices[i] = new GenericVertex()
                    {
                        Pos     = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()),
                        Nrm     = new Vector3(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f),
                        Extra   = new Vector4(r.ReadByte()),
                        Clr     = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f),
                        UV0     = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()),
                        UV1     = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()),
                        Bones   = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()),
                        Weights = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f),
                        Extra2  = new Vector4(r.ReadSingle(), r.ReadSingle(), 0, 0)
                    };
                }

                var indexOffset  = 0;
                var vertexOffset = 0;
                r.Seek(polyInfoOffset);
                for (int i = 0; i < polyCount; i++)
                {
                    GenericMesh mesh = new GenericMesh();

                    mesh.Name = r.ReadString(r.ReadUInt32(), -1);
                    r.ReadInt32();//hash
                    var myboneTableOffset = r.ReadUInt32();
                    var myPolyOffset      = r.ReadInt32();

                    r.Skip(8);
                    var indexCount = r.ReadInt32();
                    var vertCount  = r.ReadInt32();

                    var boneIDCount = r.ReadInt32();
                    var materialID  = r.ReadInt32();
                    r.Skip(8);

                    mesh.MaterialName = Generic.MaterialBank.Keys.ToList()[materialID];

                    // read bone table
                    var temp      = r.Position;
                    var boneTable = new int[boneIDCount];
                    r.Seek(myboneTableOffset);
                    for (int j = 0; j < boneIDCount; j++)
                    {
                        boneTable[j] = r.ReadInt32();
                    }

                    // get indices

                    for (int j = 0; j < indexCount; j++)
                    {
                        mesh.Triangles.Add(Indices[indexOffset + j]);
                    }
                    indexOffset += indexCount;

                    // get vertices

                    for (int j = 0; j < vertCount; j++)
                    {
                        var vert = Vertices[vertexOffset + j];
                        if (boneIDCount == 1)
                        {
                            vert.Weights = new Vector4(1, 0, 0, 0);
                            vert.Bones   = new Vector4(0, 0, 0, 0);
                        }
                        if (boneIDCount != 0)
                        {
                            for (int k = 0; k < 4; k++)
                            {
                                if (vert.Weights[k] > 0)
                                {
                                    vert.Bones[k] = boneTable[(int)vert.Bones[k]];
                                }
                            }
                        }
                        if (vert.Weights[0] == 1 && boneIDCount == 1)
                        {
                            vert.Pos = Vector3.TransformPosition(vert.Pos, Skeleton.GetWorldTransform(Skeleton.Bones[(int)vert.Bones[0]]));
                            vert.Nrm = Vector3.TransformNormal(vert.Nrm, Skeleton.GetWorldTransform(Skeleton.Bones[(int)vert.Bones[0]]));
                        }
                        vert.Nrm.Normalize();
                        mesh.Vertices.Add(vert);
                    }
                    vertexOffset += vertCount;

                    r.Seek(temp);

                    //Console.WriteLine(mesh.Name + " " + (myPolyOffset / 2).ToString("X") + " " + myboneTableOffset.ToString("X"));

                    Generic.Meshes.Add(mesh);
                }
            }
        }
示例#13
0
        public GenericModel GetGenericModel()
        {
            var ml           = new List <GenericMesh>();
            int offset       = 0;
            int MaxBoneIndex = 0;

            foreach (var gr in meshGroups)
            {
                foreach (var mo in gr)
                {
                    var mesh = new GenericMesh();
                    mesh.Name         = "mesh" + ml.Count.ToString("X");
                    mesh.MaterialName = "material";

                    mesh.Vertices  = new List <GenericVertex>();
                    mesh.Triangles = new List <uint>();

                    var stringToMorph = new Dictionary <string, GenericMorph>();

                    for (int i = offset; i < offset + mo.VertexCount; i++)
                    {
                        mesh.Vertices.Add(vertices[i]);
                        mesh.Triangles.Add((uint)(i - offset));

                        // Morphs
                        foreach (var m in _morphs)
                        {
                            //contains vertex
                            if (m.Value.ContainsKey(i))
                            {
                                if (!stringToMorph.ContainsKey(m.Key))
                                {
                                    GenericMorph morph = new GenericMorph()
                                    {
                                        Name = m.Key
                                    };
                                    mesh.Morphs.Add(morph);
                                    stringToMorph.Add(m.Key, morph);
                                }

                                var morp = stringToMorph[m.Key];
                                morp.Vertices.Add(new MorphVertex()
                                {
                                    VertexIndex = mesh.Vertices.Count - 1,
                                    Vertex      = m.Value[i]
                                });
                            }
                        }
                    }
                    offset += mo.VertexCount;

                    if (mo.PrimitiveType == 4)
                    {
                        mesh.PrimitiveType = PrimitiveType.Triangles;
                        ml.Add(mesh);
                    }
                    if (mo.PrimitiveType == 5)
                    {
                        mesh.PrimitiveType = PrimitiveType.TriangleStrip;
                        ml.Add(mesh);
                    }
                    foreach (var boneindex in mo.BoneIndices)
                    {
                        MaxBoneIndex = Math.Max(boneindex, MaxBoneIndex);
                    }
                }
            }

            Console.WriteLine("Bones: " + MaxBoneIndex + " " + Skeleton.Bones.Count);
            Console.WriteLine("Vertices: " + offset + " " + vertices.Count);

            var model = new GenericModel()
            {
                Skeleton = Skeleton, Meshes = ml
            };

            model.MaterialBank.Add("material", new GenericMaterial());

            return(model);
        }
示例#14
0
        private void ParseSubMesh(DataReader r)
        {
            GenericMesh mesh = new GenericMesh();

            Model.Meshes.Add(mesh);

            Console.WriteLine(r.Position.ToString("X"));

            //0x3C size
            // 5 floats
            r.Position += 4 * 5;
            int index1 = r.ReadInt32();
            int index2 = r.ReadInt32();

            r.ReadInt32();                    // 0
            r.ReadInt32();                    // 1
            var someOffset1 = r.ReadUInt32(); // 0x38 structure
            var someOffset2 = r.ReadUInt32(); // 0x8 structure flag->offset to 0x60 structure

            r.ReadInt32();                    // 0
            var skinDataOffset = r.ReadUInt32();

            mesh.Name = r.ReadString(r.ReadUInt32() + 4, -1);
            r.ReadInt32(); // 0x1C structure

            Console.WriteLine("\t\t" + mesh.Name + " " + someOffset1.ToString("X") + " " + someOffset2.ToString("X") + " " + skinDataOffset.ToString("X"));


            r.Seek(someOffset2);

            r.ReadInt32(); // flag or count
            r.Seek(r.ReadUInt32());

            var vectorSize   = r.ReadInt16();
            var vectorCount  = r.ReadInt16();
            var vectorOffset = r.ReadUInt32();

            Console.WriteLine(vectorOffset.ToString("x") + " " + vectorCount.ToString("X"));

            r.Seek(vectorOffset);
            for (int i = 0; i < vectorCount; i++)
            {
                var vert = new GenericVertex();
                vert.Pos = new Vector3(r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue) * 100;
                vert.Nrm = new Vector3(r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue, r.ReadInt16() / (float)short.MaxValue);
                mesh.Vertices.Add(vert);
            }

            r.Seek(someOffset1);
            r.Skip(0x1C);
            var dlCount = r.ReadInt16() + 1;

            r.Skip(0xE);
            var displayListPointerListOffset = r.ReadUInt32();

            r.Skip(0x8);

            //TODO: needs attributes to read properly
            r.Seek(displayListPointerListOffset);
            for (int j = 0; j < dlCount; j++)
            {
                var off = r.ReadUInt32();

                var temp = r.Position;
                r.Seek(off);
                var primType  = r.ReadByte();
                var primCount = r.ReadInt16();

                for (int k = 0; k < primCount; k++)
                {
                    //var index = r.ReadByte(); // TODO: not always bytes
                }

                r.Seek(temp);
            }

            mesh.Optimize();
        }
示例#15
0
文件: YO3MDL.cs 项目: ST3RmY/Metanoia
        public void Open(FileItem file)
        {
            Model          = new GenericModel();
            Model.Skeleton = new GenericSkeleton();

            using (DataReader r = new DataReader(file))
            {
                r.Seek(0x0A);

                while (r.Position < r.Length)
                {
                    var type = r.ReadByte();

                    switch (type)
                    {
                    case 0:     // nothing?
                        break;

                    case 1:     // SomeCount at beginning of file
                        r.ReadInt16();
                        break;

                    case 2:     // material
                        var materialName = r.ReadString(r.ReadByte());
                        r.Skip(0x0C);
                        break;

                    case 3:     // texture
                        var textureName = r.ReadString(r.ReadByte());
                        break;

                    case 0x0A:     // Bone
                        var boneName = r.ReadString(r.ReadByte());
                        Model.Skeleton.Bones.Add(new GenericBone()
                        {
                            Name = boneName
                        });
                        break;

                    case 0x0C:     // Appears After bone but before mesh
                        break;

                    case 0x14:     // mesh
                        GenericMesh mesh = new GenericMesh();
                        Model.Meshes.Add(mesh);

                        mesh.Name = r.ReadString(r.ReadByte());
                        var c1 = r.ReadByte();

                        var numOfPositions = r.ReadInt16();
                        for (uint i = 0; i < numOfPositions; i++)
                        {
                            mesh.Vertices.Add(new GenericVertex()
                            {
                                Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle())
                            });
                            mesh.Triangles.Add(i);
                        }
                        r.Skip(4);
                        break;

                    case 0x16:     // normal buffer
                        var numOfUVs = r.ReadByte();
                        r.ReadByte();

                        for (uint i = 0; i < numOfUVs; i++)
                        {
                            r.Skip(8);
                        }

                        r.Skip(4);
                        break;

                    case 0x19:     // mesh material entry
                        var meshMaterialName = r.ReadString(r.ReadByte());
                        r.Skip(8);
                        break;

                    default:
                        r.PrintPosition();
                        Console.WriteLine("Unknown Type 0x" + type.ToString("X2"));
                        r.Position = (uint)r.Length;
                        break;
                    }
                }
            }
        }
示例#16
0
        public void Open(FileItem File)
        {
            dynamic stuff = JObject.Parse(System.Text.Encoding.UTF8.GetString(File.GetFileBinary()));

            Model          = new GenericModel();
            Model.Skeleton = new GenericSkeleton();

            var skeletons = stuff.skeletons;

            foreach (var skel in skeletons)
            {
                if (((string)skel.name).Contains("carryable"))
                {
                    foreach (var bone in skel.bones)
                    {
                        var gBone = new GenericBone();
                        Model.Skeleton.Bones.Add(gBone);
                        gBone.Name               = "Bone_" + bone.index;
                        gBone.ParentIndex        = bone.parent;
                        gBone.Position           = new OpenTK.Vector3((float)bone.local.position[0], (float)bone.local.position[1], (float)bone.local.position[2]);
                        gBone.QuaternionRotation = new OpenTK.Quaternion((float)bone.local.rotation[0], (float)bone.local.rotation[1], (float)bone.local.rotation[2], (float)bone.local.rotation[3]).Inverted();
                        gBone.Scale              = new OpenTK.Vector3((float)bone.local.scale[0], (float)bone.local.scale[1], (float)bone.local.scale[2]);
                    }
                    break;
                }
            }

            var models = stuff.models;

            foreach (var modl in models)
            {
                foreach (var batch in modl.batches)
                {
                    GenericMesh mesh = new GenericMesh();
                    Model.Meshes.Add(mesh);
                    mesh.Name = batch.id;

                    foreach (int index in batch.indices)
                    {
                        var vertex = new GenericVertex();
                        if (((JArray)batch.positions).Count > 0)
                        {
                            vertex.Pos = new OpenTK.Vector3((float)batch.positions[index * 3 + 0], (float)batch.positions[index * 3 + 1], (float)batch.positions[index * 3 + 2]);
                        }

                        if (((JArray)batch.normals).Count > 0)
                        {
                            vertex.Nrm = new OpenTK.Vector3((float)batch.normals[index * 3 + 0], (float)batch.normals[index * 3 + 1], (float)batch.normals[index * 3 + 2]);
                        }

                        if (((JArray)batch.uvs).Count > 0)
                        {
                            vertex.UV0 = new OpenTK.Vector2((float)batch.uvs[index * 2 + 0], (float)batch.uvs[index * 2 + 1]);
                        }
                        if (((JArray)batch.uvs2).Count > 0)
                        {
                            vertex.UV1 = new OpenTK.Vector2((float)batch.uvs2[index * 2 + 0], (float)batch.uvs2[index * 2 + 1]);
                        }
                        if (((JArray)batch.uvs3).Count > 0)
                        {
                            vertex.UV2 = new OpenTK.Vector2((float)batch.uvs3[index * 2 + 0], (float)batch.uvs3[index * 2 + 1]);
                        }
                        if (((JArray)batch.colors).Count > 0)
                        {
                            vertex.Clr = new OpenTK.Vector4((float)batch.colors[index * 4 + 0] * 255, (float)batch.colors[index * 4 + 1] * 255, (float)batch.colors[index * 4 + 2] * 255, (float)batch.colors[index * 4 + 3] * 255);
                        }

                        if (((JArray)batch.bindings).Count > 0)
                        {
                            vertex.Bones = new OpenTK.Vector4((int)batch.bindings[index * 4 + 0], (int)batch.bindings[index * 4 + 1], (int)batch.bindings[index * 4 + 2], (int)batch.bindings[index * 4 + 3]);
                        }

                        if (((JArray)batch.weights).Count > 0)
                        {
                            vertex.Weights = new OpenTK.Vector4(((int)batch.weights[index * 4 + 0]) / 255f, ((int)batch.weights[index * 4 + 1]) / 255f, ((int)batch.weights[index * 4 + 2]) / 255f, ((int)batch.weights[index * 4 + 3]) / 255f);
                        }
                        mesh.Vertices.Add(vertex);
                    }

                    mesh.Optimize();
                }
            }
        }
示例#17
0
文件: HSF.cs 项目: ST3RmY/Metanoia
        public GenericModel ToGenericModel()
        {
            GenericSkeleton skel = new GenericSkeleton();

            foreach (var node in Nodes)
            {
                GenericBone bone = new GenericBone()
                {
                    Name        = node.Name,
                    Position    = node.Position,
                    Rotation    = node.Rotation,
                    Scale       = node.Scale,
                    ParentIndex = node.ParentIndex
                };
                skel.Bones.Add(bone);
            }

            GenericModel m = new GenericModel();

            m.Skeleton = skel;

            // Textures
            var tindex = 0;

            foreach (var tex in Textures)
            {
                if (m.TextureBank.ContainsKey(tex.Name))
                {
                    tex.Name += "_" + tindex++;
                }
                m.TextureBank.Add(tex.Name, tex);
            }

            int index = -1;

            foreach (var meshObject in MeshObjects)
            {
                index++;
                Dictionary <int, List <GenericVertex> > MaterialToVertexBank = new Dictionary <int, List <GenericVertex> >();
                //Console.WriteLine($"{meshObject.Key} {skel.Bones[meshObject.Value.SingleBind].Name}");
                foreach (var d in meshObject.Value.Primitives)
                {
                    if (!MaterialToVertexBank.ContainsKey(d.Material))
                    {
                        MaterialToVertexBank.Add(d.Material, new List <GenericVertex>());
                    }

                    var vertices = MaterialToVertexBank[d.Material];

                    switch (d.PrimitiveType)
                    {
                    case 0x02:     // Triangle
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[0], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel));
                        break;

                    case 0x03:     // Quad
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[0], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[3], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel));
                        break;

                    case 0x04:     // Triangle Strip
                        var verts = new List <GenericVertex>();

                        foreach (var dv in d.Vertices)
                        {
                            verts.Add(GetVertex(meshObject.Value, dv, skel));
                        }
                        Tools.TriangleConverter.StripToList(verts, out verts);

                        vertices.AddRange(verts);
                        break;

                    default:
                        throw new Exception("Unsupported Primitive Type " + d.PrimitiveType.ToString("X"));
                    }
                }

                foreach (var v in MaterialToVertexBank)
                {
                    GenericMesh mesh = new GenericMesh();
                    mesh.Name = meshObject.Key;
                    if (MaterialToVertexBank.Count > 1)
                    {
                        mesh.Name += "_" + m.Meshes.Count;// Textures[Materials[Materials1[v.Key].MaterialIndex].TextureIndex].Name;
                    }
                    GenericMaterial mat = new GenericMaterial();

                    mesh.MaterialName = "material_" + m.MaterialBank.Count;

                    m.MaterialBank.Add(mesh.MaterialName, mat);

                    var mat1Index = Materials1[v.Key].MaterialIndex;
                    mat1Index = Math.Min(mat1Index, Materials.Count - 1);
                    var textureIndex = Materials[mat1Index].TextureIndex;
                    mat.TextureDiffuse = Textures[textureIndex].Name;

                    m.Meshes.Add(mesh);

                    mesh.Vertices.AddRange(v.Value);

                    //Console.WriteLine(mesh.Name + " " + v.Key + " " + Materials[v.Key].TextureIndex + " " + Textures.Count + " " + Materials.Count);

                    mesh.Optimize();
                }
            }


            return(m);
        }
示例#18
0
        public void Open(FileItem File)
        {
            var skelPath    = File.FilePath.Replace(".mdg", ".anm");
            var skelAngPath = File.FilePath.Replace(".mdg", ".ang");
            var modelPath   = File.FilePath.Replace(".mdg", ".mdl");
            var texPath     = File.FilePath.Replace(".mdg", ".tex");

            if (!System.IO.File.Exists(skelPath))
            {
                System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelPath));
                return;
            }
            if (!System.IO.File.Exists(skelAngPath))
            {
                System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelAngPath));
                return;
            }
            if (!System.IO.File.Exists(modelPath))
            {
                System.Windows.Forms.MessageBox.Show("Missing Model File " + Path.GetFileName(modelPath));
                return;
            }

            Model          = new GenericModel();
            Model.Skeleton = new GenericSkeleton();

            if (System.IO.File.Exists(texPath))
            {
                using (DataReader r = new DataReader(new FileStream(texPath, FileMode.Open)))
                {
                    r.BigEndian = true;

                    var unk        = r.ReadInt32();
                    var width      = r.ReadInt32();
                    var height     = r.ReadInt32();
                    var dataLength = r.ReadInt32();
                    var padding    = r.ReadInt32();
                    var format     = r.ReadByte();
                    var data       = r.GetSection(0x20, (int)(r.BaseStream.Length - 0x20));

                    var bmp = HSDLib.Helpers.TPL.ConvertFromTextureMelee(data, width, height, (int)TPL_TextureFormat.CMP, null, 0, 0);

                    GenericTexture t = new GenericTexture();
                    t.FromBitmap(bmp);

                    bmp.Dispose();

                    Model.TextureBank.Add("texture", t);
                    Model.MaterialBank.Add("material", new GenericMaterial()
                    {
                        TextureDiffuse = "texture"
                    });
                }
            }

            using (DataReader r = new DataReader(new FileStream(skelPath, FileMode.Open)))
            {
                r.BigEndian = false;

                r.ReadInt32(); // magic
                r.ReadInt32(); // header
                var boneCount  = r.ReadInt32();
                var boneOffset = r.ReadUInt32();

                using (DataReader angr = new DataReader(new FileStream(skelAngPath, FileMode.Open)))
                {
                    angr.BigEndian = false;
                    for (int i = 0; i < boneCount; i++)
                    {
                        r.Seek(boneOffset + (uint)(i * 0x20));
                        var bone = new GenericBone();
                        bone.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                        r.ReadSingle();
                        //r.Skip(0x10); // inverted world position
                        bone.Name        = r.ReadString(r.ReadUInt32(), -1);
                        bone.ParentIndex = r.ReadInt32();
                        var flags     = r.ReadInt32();
                        var angOffset = r.ReadUInt32();

                        /*angr.Seek(angOffset);
                         * angr.Skip(4);
                         * var posOff = angr.ReadUInt32();
                         * var rotOff = angr.ReadUInt32();
                         * var scaOff = angr.ReadUInt32();
                         * angr.Seek(posOff);
                         * bone.Position = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());
                         * angr.Seek(rotOff);
                         * bone.Rotation = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());
                         * angr.Seek(scaOff);
                         * bone.Scale = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());*/

                        Model.Skeleton.Bones.Add(bone);
                    }
                }
            }

            Model.Skeleton.TransformWorldToRelative();

            using (DataReader r = new DataReader(new FileStream(modelPath, FileMode.Open)))
            {
                r.BigEndian = true;

                r.ReadInt32(); // magic
                int boneCount = r.ReadInt16();
                var meshCount = r.ReadInt16();
                boneCount = r.ReadInt32();
                var meshOffset = r.ReadUInt32();
                r.ReadUInt32();
                var boneOffset = r.ReadUInt32();

                for (int i = 0; i < meshCount; i++)
                {
                    r.Seek(meshOffset + (uint)(i * 80));
                    r.Skip(0x30); // bounding stuff
                    var mesh = new GenericMesh();
                    mesh.MaterialName = "material";
                    mesh.Name         = r.ReadString(r.ReadUInt32(), -1);
                    r.Skip(4 * 4);
                    var datInfoOffset = r.ReadUInt32();
                    Model.Meshes.Add(mesh);

                    r.Seek(datInfoOffset);
                    var flag         = r.ReadInt32();
                    var bufferOffset = r.ReadUInt32();
                    var someCount    = r.ReadInt32();
                    var primCount    = r.ReadInt32();

                    using (DataReader buffer = new DataReader(new FileStream(File.FilePath, FileMode.Open)))
                    {
                        buffer.BigEndian = true;
                        if (new string(buffer.ReadChars(4)) == "MDG5")
                        {
                            buffer.Seek(0x10);
                        }
                        else
                        {
                            buffer.Seek(0);
                        }
                        buffer.Skip(bufferOffset);
                        for (int p = 0; p < primCount; p++)
                        {
                            var primitiveType = buffer.ReadInt16();
                            var pcount        = buffer.ReadInt16();

                            if (primitiveType != 0x98)
                            {
                                throw new NotSupportedException("Unknown prim type " + primitiveType.ToString("X"));
                            }

                            var strip = new List <GenericVertex>();
                            for (int v = 0; v < pcount; v++)
                            {
                                var vert = new GenericVertex();
                                vert.Pos = new OpenTK.Vector3(buffer.ReadSingle(), buffer.ReadSingle(), buffer.ReadSingle());
                                vert.Nrm = new OpenTK.Vector3(buffer.ReadSByte(), buffer.ReadSByte(), buffer.ReadSByte());
                                vert.Nrm.Normalize();

                                // Color?
                                int col = buffer.ReadInt16();
                                var R   = (col >> 12) & 0xF;
                                var G   = (col >> 8) & 0xF;
                                var B   = (col >> 4) & 0xF;
                                var A   = (col) & 0xF;
                                vert.Clr = new OpenTK.Vector4(
                                    (R | R << 4) / (float)0xFF,
                                    (G | G << 4) / (float)0xFF,
                                    (B | B << 4) / (float)0xFF,
                                    (A | A << 4) / (float)0xFF);

                                vert.UV0 = new OpenTK.Vector2(buffer.ReadInt16() / (float)0xFFF, buffer.ReadInt16() / (float)0xFFF);

                                var   weight1 = buffer.ReadByte() / (float)0xFF;
                                float weight2 = 0;
                                if (weight1 != 1)
                                {
                                    weight2 = 1 - weight1;
                                }
                                var bone1 = buffer.ReadByte();
                                var bone2 = buffer.ReadByte();
                                vert.Bones   = new OpenTK.Vector4(bone1, bone2, 0, 0);
                                vert.Weights = new OpenTK.Vector4(weight1, weight2, 0, 0);

                                strip.Add(vert);
                            }

                            TriangleConverter.StripToList(strip, out strip);

                            mesh.Vertices.AddRange(strip);
                        }
                    }

                    mesh.Optimize();
                }
            }
        }
示例#19
0
        private void ParseMDLD(byte[] data)
        {
            using (DataReader r = new DataReader(data))
            {
                r.BigEndian = false;

                r.ReadInt32(); // magic
                var offset1        = r.ReadUInt32();
                var polyInfoOffset = r.ReadUInt32();
                var polyInfoCount  = r.ReadInt32();
                var boneOffset     = r.ReadUInt32();
                var boneCount      = r.ReadInt32();
                var bufferOffset   = r.ReadUInt32();
                var bufferLength   = r.ReadInt32();
                var vertexCount    = r.ReadInt32();

                var att = r.ReadString(0x68, -1).Split('_');

                r.Seek(boneOffset);
                model.Skeleton = new GenericSkeleton();
                for (int i = 0; i < boneCount; i++)
                {
                    var bone = new GenericBone();
                    bone.Name = r.ReadString(r.Position, -1);
                    r.Skip(0x20);
                    bone.Transform          = Matrix4.Identity;
                    bone.QuaternionRotation = new Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                    bone.Position           = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                    bone.Scale       = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                    bone.ParentIndex = r.ReadInt32();
                    model.Skeleton.Bones.Add(bone);
                }
                model.Skeleton.TransformWorldToRelative();

                List <GenericVertex> vertices = new List <GenericVertex>();
                for (uint i = 0; i < vertexCount; i++)
                {
                    r.Seek(bufferOffset + 60 * i);
                    var vert = new GenericVertex();
                    var stop = false;
                    foreach (var va in att)
                    {
                        switch (va)
                        {
                        case "vp3":
                            vert.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                            break;

                        case "vc":
                            vert.Clr = new OpenTK.Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f);
                            break;

                        case "vn":
                            vert.Nrm = new OpenTK.Vector3(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle());
                            r.ReadHalfSingle();
                            break;

                        case "vt":
                            vert.UV0 = new OpenTK.Vector2(r.ReadHalfSingle(), r.ReadHalfSingle());
                            break;

                        case "von":
                            r.Skip(8);
                            break;

                        case "vb4":
                            vert.Bones   = new OpenTK.Vector4(r.ReadInt16(), r.ReadInt16(), r.ReadInt16(), r.ReadInt16());
                            vert.Weights = new OpenTK.Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                            break;

                        case "vs":
                            break;

                        default:
                            stop = true;
                            break;
                        }
                        if (stop)
                        {
                            break;
                        }
                    }
                    vertices.Add(vert);
                }

                r.Seek(polyInfoOffset);
                for (int i = 0; i < polyInfoCount; i++)
                {
                    GenericMesh mesh = new GenericMesh();

                    model.Meshes.Add(mesh);

                    mesh.Name = r.ReadString(r.Position, -1);
                    r.Skip(0x40);
                    var polyBufferOffset = r.ReadUInt32();
                    var polyBufferLength = r.ReadUInt32();
                    var polyBufferCount  = r.ReadUInt32();
                    var primType         = r.ReadInt32();
                    r.Skip(0x60);

                    var temp = r.Position;
                    r.Seek(polyBufferOffset);
                    for (int j = 0; j < polyBufferCount; j++)
                    {
                        if (primType == 4)
                        {
                            mesh.Vertices.Add(vertices[r.ReadInt32()]);
                        }
                    }
                    mesh.Optimize();
                    r.Seek(temp);
                }
            }
        }
示例#20
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public GenericModel ToGenericModel()
        {
            var model = new GenericModel();

            model.Skeleton = Skeleton;

            var tindex = 0;

            foreach (var t in Textures)
            {
                model.TextureBank.Add("T" + tindex.ToString("X3"), t);

                tindex++;
            }

            foreach (var g1m in Models)
            {
                var mod = g1m.G1MG;

                var nuno = g1m.NUNO;
                var nunv = g1m.NUNV;

                model.Skeleton = g1m.Skeleton.Skeleton;

                var        idTonunoBoneToBone33 = new List <Dictionary <int, int> >();
                List <int> nunoParents          = new List <int>();

                //var idTonunoBoneToBone32 = new List<int>();

                var entries         = new List <NUNO.NUNOv33Entry>();
                var nunoIndexOffset = 0;
                if (nunv != null)
                {
                    nunoIndexOffset = nunv.V33Entries.Count;
                }
                if (nunv != null)
                {
                    entries.AddRange(nunv.V33Entries);
                }
                if (nuno != null)
                {
                    entries.AddRange(nuno.V33Entries);
                }

                foreach (var entry in entries)
                {
                    var boneStart  = model.Skeleton.Bones.Count;
                    var parentBone = mod.BindMatches[entry.ParentBoneID - 1][0];
                    nunoParents.Add(parentBone);

                    Dictionary <int, int> nunoBoneToBone = new Dictionary <int, int>();
                    idTonunoBoneToBone33.Add(nunoBoneToBone);

                    GenericMesh driverMesh = new GenericMesh();
                    driverMesh.Name = "driver_" + (idTonunoBoneToBone33.Count - 1) + "_" + model.Skeleton.Bones[parentBone].Name;
                    model.Meshes.Add(driverMesh);
                    driverMesh.Visible = false;

                    for (int pointIndex = 0; pointIndex < entry.Points.Count; pointIndex++)
                    {
                        // fake bone generation

                        var         p    = entry.Points[pointIndex];
                        var         link = entry.Influences[pointIndex];
                        GenericBone b    = new GenericBone();
                        b.Name      = $"CP_{idTonunoBoneToBone33.Count}_{model.Skeleton.Bones[parentBone].Name}_{pointIndex}";
                        b.Transform = Matrix4.Identity;

                        nunoBoneToBone.Add(pointIndex, model.Skeleton.Bones.Count);
                        model.Skeleton.Bones.Add(b);
                        b.Position    = p.Xyz;
                        b.ParentIndex = link.P3;
                        if (b.ParentIndex == -1)
                        {
                            b.ParentIndex = parentBone;
                        }
                        else
                        {
                            b.ParentIndex += boneStart;
                            b.Position     = Vector3.TransformPosition(p.Xyz, model.Skeleton.GetWorldTransform(parentBone) * model.Skeleton.GetWorldTransform(b.ParentIndex).Inverted());
                        }

                        // fake driver mesh generation

                        driverMesh.Vertices.Add(new GenericVertex()
                        {
                            Pos     = Vector3.TransformPosition(Vector3.Zero, model.Skeleton.GetWorldTransform(model.Skeleton.Bones.Count - 1)),
                            Weights = new Vector4(1, 0, 0, 0),
                            Bones   = new Vector4(model.Skeleton.Bones.Count - 1, 0, 0, 0)
                        });

                        if (link.P1 > 0 && link.P3 > 0)
                        {
                            driverMesh.Triangles.Add((uint)pointIndex);
                            driverMesh.Triangles.Add((uint)link.P1);
                            driverMesh.Triangles.Add((uint)link.P3);
                        }
                        if (link.P2 > 0 && link.P4 > 0)
                        {
                            driverMesh.Triangles.Add((uint)pointIndex);
                            driverMesh.Triangles.Add((uint)link.P2);
                            driverMesh.Triangles.Add((uint)link.P4);
                        }
                    }
                }

                foreach (var group in mod.Lods[0].Groups)
                {
                    var isCloth    = (group.ID & 0xF) == 1;
                    var isPoint    = (group.ID & 0xF) == 2;
                    var NunSection = (group.ID2 - (group.ID2 % 10000)) / 10000;
                    Console.WriteLine(group.Name + " " + group.ID + " " + group.ID2 + " " + NunSection);

                    foreach (var polyindex in group.Indices)
                    {
                        if (polyindex > mod.Polygons.Count)
                        {
                            continue;
                        }
                        var poly = mod.Polygons[polyindex];

                        GenericMesh mesh = new GenericMesh();
                        mesh.Name = System.Text.RegularExpressions.Regex.Replace(group.Name, @"\p{C}+", string.Empty) + model.Meshes.Count;//  + "_" + polyindex;

                        model.MaterialBank.Add("MP_" + polyindex,
                                               new GenericMaterial()
                        {
                            MaterialInfo   = mod.Materials[poly.MaterialIndex].ToString(),
                            TextureDiffuse = "T" + mod.TextureBanks[poly.TextureBankIndex].DiffuseTextureIndex.ToString("X3"),
                            EnableBlend    = false,
                        });
                        mesh.MaterialName = "MP_" + polyindex;

                        mesh.Vertices = mod.GetVertices(poly, out mesh.Triangles, !isCloth);

                        if (isPoint)
                        {
                            for (int i = 0; i < mesh.VertexCount; i++)
                            {
                                var vert = mesh.Vertices[i];
                                vert.Nrm         = Vector3.TransformNormal(vert.Nrm, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0]));
                                vert.Pos         = Vector3.TransformPosition(vert.Pos, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0]));
                                mesh.Vertices[i] = vert;
                            }
                        }
                        if (isCloth)
                        {
                            Dictionary <int, int> nunoBoneToBone = idTonunoBoneToBone33[group.ID2 & 0xF];
                            if (NunSection == 2 && nunv != null && nuno != null)
                            {
                                nunoBoneToBone = idTonunoBoneToBone33[(group.ID2 & 0xF) + nunoIndexOffset];
                            }
                            //mesh.Name += "_driver_" + (group.ID2 & 0xF);

                            for (int i = 0; i < mesh.VertexCount; i++)
                            {
                                var vert = mesh.Vertices[i];
                                if (vert.Bit == Vector4.Zero)
                                {
                                    //Console.WriteLine(vert.Weights.ToString() + " " + vert.Bones.ToString());
                                    vert.Pos = Vector3.TransformPosition(vert.Pos, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0]));
                                    vert.Nrm = Vector3.TransformNormal(vert.Nrm, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0]));
                                    //vert.Weights = new Vector4(1, 0, 0, 0);
                                    vert.Bones = new Vector4(mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.X / 3],
                                                             mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.Y / 3],
                                                             mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.Z / 3],
                                                             mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.W / 3]);
                                    mesh.Vertices[i] = vert;
                                    continue;
                                }

                                Vector3 finpos = Vector3.Zero;

                                //Console.WriteLine(vert.Nrm + " " + vert.Nrm.Normalized());

                                var tempb = new GenericBone();
                                tempb.Transform = Matrix4.Identity;
                                tempb.Rotation  = vert.Clr1.Xyz;

                                var weights1 = new Vector4(vert.Pos, vert.Extra3.X);

                                {
                                    var pos = Vector3.Zero;
                                    var d4  = Vector3.Zero;
                                    d4 += Weight(pos, model.Skeleton, weights1, vert.Bones, nunoBoneToBone) * vert.Weights.X;
                                    d4 += Weight(pos, model.Skeleton, weights1, vert.Extra, nunoBoneToBone) * vert.Weights.Y;
                                    d4 += Weight(pos, model.Skeleton, weights1, vert.Fog, nunoBoneToBone) * vert.Weights.Z;
                                    d4 += Weight(pos, model.Skeleton, weights1, vert.Extra2, nunoBoneToBone) * vert.Weights.W;

                                    var d5 = Vector3.Zero;
                                    d5 += Weight(pos, model.Skeleton, weights1, vert.Bones, nunoBoneToBone) * vert.Clr1.X;
                                    d5 += Weight(pos, model.Skeleton, weights1, vert.Extra, nunoBoneToBone) * vert.Clr1.Y;
                                    d5 += Weight(pos, model.Skeleton, weights1, vert.Fog, nunoBoneToBone) * vert.Clr1.Z;
                                    d5 += Weight(pos, model.Skeleton, weights1, vert.Extra2, nunoBoneToBone) * vert.Clr1.W;

                                    var d6 = Vector3.Zero;
                                    d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Bones, nunoBoneToBone) * vert.Weights.X;
                                    d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Extra, nunoBoneToBone) * vert.Weights.Y;
                                    d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Fog, nunoBoneToBone) * vert.Weights.Z;
                                    d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Extra2, nunoBoneToBone) * vert.Weights.W;

                                    vert.Pos = Vector3.Cross(d5, d6) * (vert.Extra3.Y) + d4;
                                }

                                vert.Weights = Vector4.Zero; // new Vector4(1, 0, 0, 0);
                                vert.Bones   = Vector4.Zero; // new Vector4(mod.BindMatches[poly.BoneTableIndex][0], 0, 0, 0);

                                //RigMe(vert.Pos, model.Skeleton, nunoBoneToBone, out vert.Bones, out vert.Weights);

                                mesh.Vertices[i] = vert;
                            }
                        }

                        mesh.PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip;

                        model.Meshes.Add(mesh);
                    }
                }
            }

            return(model);
        }
示例#21
0
        public void Open(FileItem File)
        {
            var Data = File.GetFileBinary();

            Model          = new GenericModel();
            Model.Skeleton = new GenericSkeleton();
            Model.Skeleton.RotationOrder = RotationOrder.ZYX;

            // decompress
            using (DataReader reader = new DataReader(new MemoryStream(Data)))
            {
                reader.BigEndian = true;

                if (reader.BaseStream.Length < 8 || !reader.ReadString(8).Equals("PERS-SZP"))
                {
                    // not compressed
                }
                else
                {
                    reader.BigEndian = true;
                    uint compressedoffset = reader.ReadUInt32();

                    reader.Seek(compressedoffset);
                    Data = Tools.Decompress.YAY0(reader.ReadBytes((int)(reader.BaseStream.Length - compressedoffset)));
                }
            }

            // decode file contents
            using (DataReader reader = new DataReader(new MemoryStream(Data)))
            {
                reader.BigEndian = true;
                reader.Seek(0x8);
                if (!reader.ReadString(8).Equals("FRAGMENT"))
                {
                    return;
                }
                reader.Seek(0x10);
                uint DataOffset            = reader.ReadUInt32();
                uint RelocationTableOffset = reader.ReadUInt32();
                reader.Skip(4); // filesize
                reader.Skip(4); // tableOffset again

                // Relocation Table
                reader.Seek(RelocationTableOffset);
                int   entryCount = reader.ReadInt32();
                int[] offsets    = new int[entryCount];
                for (int i = 0; i < entryCount; i++)
                {
                    int mask = 0xFFFF;
                    offsets[i] = reader.ReadInt32();
                    if (RelocationTableOffset > 0xFFFF)
                    {
                        mask = 0x1FFFF;                                 // hack
                    }
                    uint temp = reader.Position;
                    reader.Seek((uint)(offsets[i] & 0x1FFFF));
                    reader.WriteInt32At(reader.ReadInt32() & mask, offsets[i] & 0x1FFFF);
                    reader.Seek((uint)(offsets[i] & 0x1FFFF));
                    reader.Seek(temp);
                }

                // main data
                reader.Seek(DataOffset);
                reader.Skip(0x10);
                uint mainOffset = reader.ReadUInt32();

                // main stuff
                reader.Seek(mainOffset);
                reader.Skip(8); // i dunno
                uint offsetToTextureOffset = reader.ReadUInt32();

                reader.Seek(offsetToTextureOffset);
                uint textureOffset = reader.ReadUInt32();

                // may be objects instead of just textures
                reader.Seek(textureOffset);
                int  TextureCount  = reader.ReadInt32() & 0xFFFF; // should have 0x17 in front
                int  PaletteCount  = reader.ReadInt16();
                int  VertexCount   = reader.ReadInt16();
                uint TextureOffset = reader.ReadUInt32();
                uint PaletteOffset = reader.ReadUInt32();
                uint VertexOffset  = reader.ReadUInt32();
                reader.Skip(0x1C); //I dunno
                uint objectOffset = reader.ReadUInt32();


                // Textures-------------------------------------------------------
                List <GenericTexture> Textures = new List <GenericTexture>();
                List <byte[]>         Palettes = new List <byte[]>();

                //Read Palettes
                reader.Seek(PaletteOffset);
                for (int i = 0; i < PaletteCount; i++)
                {
                    int  colorcount      = reader.ReadInt32();
                    uint OffsetData      = reader.ReadUInt32();
                    int  OffsetSomething = reader.ReadInt32();
                    Palettes.Add(reader.GetSection(OffsetData, colorcount * 2));
                }

                // Read Textures?
                reader.Seek(TextureOffset);
                //Console.WriteLine(reader.pos().ToString("x"));
                for (int i = 0; i < TextureCount; i++)
                {
                    int  format        = reader.ReadByte();
                    int  bitsize       = reader.ReadByte();
                    uint width         = reader.ReadUInt16();
                    uint height        = reader.ReadUInt16();
                    uint size          = reader.ReadUInt16(); // sometimes 8 maybe an id? pointer?
                    uint texDataOffset = reader.ReadUInt32() & 0x1FFFF;

                    Console.WriteLine("Texture " + format + " " + bitsize + " " + size + " " + width + " " + height);

                    GenericTexture tex = new GenericTexture();
                    Textures.Add(tex);
                    tex.Name = "Texture_" + i;
                    byte[] data;
                    tex.Width  = width;
                    tex.Height = height;

                    tex.PixelFormat = PixelFormat.Rgba;
                    if (format == 4)
                    {
                        // Raw
                        if (bitsize == 1) //RGBA
                        {
                            data = reader.GetSection(texDataOffset, (int)size * bitsize);

                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Luminance8;
                            tex.PixelFormat    = PixelFormat.Luminance;
                        }
                    }
                    else
                    if (format == 2)
                    {
                        // Paletted

                        if (bitsize == 0) //4bpp
                        {
                            data = reader.GetSection(texDataOffset, (int)size / 2);

                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Alpha4;
                        }
                        else if (bitsize == 1) //8bpp
                        {
                            data = reader.GetSection(texDataOffset, (int)size * bitsize);

                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Alpha8;
                        }
                    }
                    else
                    {
                        if (bitsize == 2)
                        {
                            data = reader.GetSection(texDataOffset, (int)size * bitsize);
                            // swap endian
                            for (int j = 0; j < data.Length / 2; j++)
                            {
                                byte temp = data[j * 2];
                                data[j * 2]       = data[(j * 2) + 1];
                                data[(j * 2) + 1] = temp;
                            }
                            tex.Mipmaps.Add(data);
                            tex.InternalFormat = PixelInternalFormat.Rgb5A1;
                        }
                        else if (bitsize == 3)
                        {
                            tex.InternalFormat = PixelInternalFormat.Rgba8;
                            data = reader.GetSection(texDataOffset, (int)size * 4);
                            tex.Mipmaps.Add(data);
                        }
                    }
                }

                // Objects--------------------------------------------------------
                // now parse until end
                bool done = false;
                Stack <GenericBone> boneStack  = new Stack <GenericBone>();
                GenericBone         parentBone = null;

                reader.Seek(objectOffset);
                reader.Skip(4); // idk
                int maybeCount = reader.ReadInt32();

                string          currentMaterialName = "";
                GenericMaterial currentMaterial     = new GenericMaterial();
                GenericBone     CurrentBone         = null;

                while (!done)
                {
                    int doff, temp;
                    //Console.WriteLine(reader.Position().ToString("x") + " " + reader.ReadByte().ToString("x"));
                    reader.ReadByte();
                    reader.Seek(reader.Position - 1);
                    switch (reader.ReadByte())
                    {
                    case 0x03:     // Perhaps some object offset? Offset goes to beginning of file. Material maybe?
                        reader.Skip(0x08 - 1);
                        break;

                    case 0x05:
                        reader.Skip(0x04 - 1);
                        boneStack.Push(CurrentBone);
                        parentBone = boneStack.Peek();
                        break;

                    case 0x06:
                        reader.Skip(0x04 - 1);
                        if (boneStack.Count > 0)
                        {
                            boneStack.Pop();
                            if (boneStack.Count > 0)
                            {
                                parentBone = boneStack.Peek();
                            }
                        }
                        break;

                    case 0x08:
                        reader.Skip(4 - 1);
                        int s1 = reader.ReadByte() & 0x7F;
                        reader.Skip(1);
                        int s2 = reader.ReadInt16();
                        reader.Skip(4);
                        // pops matrix
                        // maybe pop until you get to this bone?
                        //Also maybe some texture thing?
                        Console.WriteLine("What dis?" + " " + s1 + " " + s2);
                        //throw new Exception("Weird Special Thing");

                        /*for (int i = popto - s1; i < popto + s2; i++)
                         * {
                         *  Bone bo = skel.GetBoneByID(i);
                         *  boneStack.Push(bo);
                         * }*/
                        break;

                    case 0x18:     // idk has 4 values
                        reader.Skip(0x08 - 1);
                        break;

                    case 0x1D:
                        int id     = reader.ReadByte();
                        int what   = reader.ReadByte();
                        int parent = (sbyte)reader.ReadByte();

                        // read bone properties
                        Vector3 trans = new Vector3((short)reader.ReadInt16(), (short)reader.ReadInt16(), (short)reader.ReadInt16());
                        Vector3 rot   = new Vector3((short)reader.ReadInt16() / 180, ((short)reader.ReadInt16()) / 180, (short)reader.ReadInt16() / 180);

                        // to radians
                        rot.X = (rot.X * (float)Math.PI) / 180f;
                        rot.Y = (rot.Y * (float)Math.PI) / 180f;
                        rot.Z = (rot.Z * (float)Math.PI) / 180f;

                        //rot = new Vector3(rot.Z, rot.X, rot.Y);

                        Vector3 scale = new Vector3();
                        scale.X = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF;
                        scale.Y = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF;
                        scale.Z = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF;

                        int parent2 = boneStack.Count;

                        GenericBone b = new GenericBone();
                        b.Name = "Bone_" + id;
                        if (parentBone != null)
                        {
                            b.ParentIndex = Model.Skeleton.IndexOf(parentBone);
                        }
                        else
                        {
                            b.ParentIndex = -1;
                        }
                        b.ID       = id;
                        b.Scale    = new Vector3(1, 1, 1);  // scale
                        b.Position = trans;
                        b.Rotation = rot;

                        CurrentBone = b;
                        Model.Skeleton.Bones.Add(b);

                        //Console.WriteLine(reader.Position().ToString("x") + " " + b.Name + " " + b.p1 + " " + what + " " + parent + " " + boneStack.Count + " " + trans.ToString() + " " + rot.ToString() + " " + scale.ToString());
                        //Console.WriteLine(b.transform.ToString());
                        break;

                    case 0x1E:
                        //reader.Skip(3);
                        reader.Skip(1);
                        int w = reader.ReadInt16();     // bone index
                        doff = reader.ReadInt32();
                        temp = (int)reader.Position;

                        reader.Seek((uint)doff);
                        {
                            GenericMesh mesh = DisplayListToGenericMesh(N64Tools.ReadDisplayList(reader, Model.Skeleton.IndexOf(Model.Skeleton.GetBoneByID(w)), Model.Skeleton.GetWorldTransform(Model.Skeleton.GetBoneByID(w))));
                            mesh.MaterialName = currentMaterialName;
                            Model.Meshes.Add(mesh);
                        }
                        reader.Seek((uint)temp);

                        break;

                    case 0x22:
                        int materialIndex = reader.ReadByte();
                        int ww            = (short)reader.ReadInt16();

                        doff = reader.ReadInt32();
                        temp = (int)reader.Position;
                        if (doff == 0)
                        {
                            continue;
                        }

                        reader.Seek((uint)doff);
                        {
                            GenericMesh mesh = DisplayListToGenericMesh(N64Tools.ReadDisplayList(reader, Model.Skeleton.IndexOf(parentBone), Model.Skeleton.GetWorldTransform(parentBone)));
                            mesh.MaterialName = currentMaterialName;
                            Model.Meshes.Add(mesh);
                        }
                        reader.Seek((uint)temp);
                        //((DisplayList)DisplayLists.Nodes[DisplayLists.Nodes.Count - 1]).Mat = unk;
                        //Console.WriteLine("Material Maybe 0x" + reader.pos().ToString("x") + " " + unk + " " + .Count);
                        break;

                    case 0x23:
                        reader.Skip(1);
                        int tidunk = (short)reader.ReadInt16();
                        int texOff = reader.ReadInt32();    //& 0x1FFFF Material Offset?
                        int tid    = (short)reader.ReadInt16();
                        int pid    = (short)reader.ReadInt16();
                        reader.Skip(4);    // 0xFF padding
                        //Console.WriteLine("TextureCount " + tid + " " + pid + " " + tidunk + " " + texOfreader.ToString("x"));
                        if (tid != -1)
                        {
                            currentMaterial     = new GenericMaterial();
                            currentMaterialName = "material_" + Model.MaterialBank.Count;
                            var diffuse = BakeTexturePalette(Textures[tid], pid, Palettes);
                            diffuse.Name = "texture_" + Model.TextureBank.Count;
                            currentMaterial.TextureDiffuse = diffuse.Name;
                            Model.TextureBank.Add(diffuse.Name, diffuse);
                            Model.MaterialBank.Add(currentMaterialName, currentMaterial);
                        }
                        else
                        {
                            var currentTexture = currentMaterial.TextureDiffuse;
                            currentMaterial                = new GenericMaterial();
                            currentMaterialName            = "material_" + Model.MaterialBank.Count;
                            currentMaterial.TextureDiffuse = currentTexture;
                            Model.MaterialBank.Add(currentMaterialName, currentMaterial);
                        }

                        // Read Texture Info At Offset
                        int tt = (int)reader.Position;
                        reader.Seek((uint)texOff);
                        ReadTextureCodes(reader, currentMaterial);
                        reader.Seek((uint)tt);
                        break;                        // Texture Binding

                    case 0x24: reader.Skip(3); break; // has to do with matrix popping

                    case 0x25:
                        reader.Skip(0x04 - 1);
                        //Console.WriteLine("Unknown 0x" + reader.pos().ToString("x"));
                        break;

                    default:
                        done = true;
                        break;
                    }
                    ;
                }
            }


            // Post Process

            // optimized texture sharing
            Dictionary <string, string>         newTexName  = new Dictionary <string, string>();
            Dictionary <string, GenericTexture> newTexBank  = new Dictionary <string, GenericTexture>();
            Dictionary <byte[], string>         TextureBank = new Dictionary <byte[], string>();

            foreach (var tex in Model.TextureBank)
            {
                if (!TextureBank.ContainsKey(tex.Value.Mipmaps[0]))
                {
                    string newName = "texture_" + newTexName.Count;
                    newTexName.Add(tex.Key, newName);
                    newTexBank.Add(newName, tex.Value);
                    TextureBank.Add(tex.Value.Mipmaps[0], newName);
                }
                else
                {
                    newTexName.Add(tex.Key, TextureBank[tex.Value.Mipmaps[0]]);
                }
            }

            Model.TextureBank = newTexBank;

            foreach (var mesh in Model.Meshes)
            {
                var material = Model.GetMaterial(mesh);
                if (material != null && material.TextureDiffuse != null)
                {
                    material.TextureDiffuse = newTexName[material.TextureDiffuse];
                }
            }

            Console.WriteLine(TextureBank.Count + " total textures");

            // Transform Verts

            /*int meshindex = 0;
             * foreach(GenericMesh mesh in Model.Meshes)
             * {
             *  mesh.Name = "Mesh_" + meshindex;
             *  GenericVertex[] CorrectedVertices = mesh.Vertices.ToArray();
             *  for(int i =0; i < CorrectedVertices.Length; i++)
             *  {
             *      CorrectedVertices[i].Pos = Vector3.TransformPosition(CorrectedVertices[i].Pos, Model.Skeleton.GetWorldTransform((int)CorrectedVertices[i].Bones.X));
             *  }
             *  mesh.Vertices.Clear();
             *  mesh.Vertices.AddRange(CorrectedVertices);
             * }*/
        }
示例#22
0
文件: JStar.cs 项目: ST3RmY/Metanoia
        public GenericModel ToGenericModel()
        {
            var mdl = new GenericModel()
            {
                Skeleton = Skeleton
            };;

            byte[] Data      = File.ReadAllBytes(@"chr0020_model.npki");
            byte[] ImageData = File.ReadAllBytes(@"chr0020_model.npkv");

            foreach (var t in TXRs)
            {
                GenericTexture tex = new GenericTexture();
                tex.Width  = (uint)t.Width;
                tex.Height = (uint)t.Height;

                var buf = new byte[t.Width * t.Height / 2];
                Array.Copy(ImageData, t.BufferOffsets[0], buf, 0, buf.Length);
                buf = VitaSwizzle.UnswizzlePS4(buf, t.Width, t.Height);
                tex.Mipmaps.Add(buf);

                tex.InternalFormat = OpenTK.Graphics.OpenGL.PixelInternalFormat.CompressedRgbS3tcDxt1Ext;

                if (!mdl.TextureBank.ContainsKey(t.Name))
                {
                    mdl.TextureBank.Add(t.Name, tex);
                }

                Console.WriteLine(tex.Width + " " + tex.Height + " " + t.Unknown.ToString("X") + " " + t.BufferOffsets[0].ToString("X") + " " + t.BufferSizes[0].ToString("X"));
            }

            foreach (var v in VTXs)
            {
                if (v.BufferSizes.Length < 2)
                {
                    continue;
                }
                GenericMesh m = new GenericMesh();
                mdl.Meshes.Add(m);
                m.Name = v.Name;

                using (DataReader r = new DataReader(Data))
                {
                    for (uint i = 0; i < v.BufferSizes[1]; i += 2)
                    {
                        r.Seek((uint)v.BufferOffsets[1] + i);
                        //r.PrintPosition();
                        var index = r.ReadInt16();

                        GenericVertex vert = new GenericVertex();

                        foreach (var attr in v.Attribtues)
                        {
                            r.Seek((uint)(v.BufferOffsets[0] + v.BufferInfos[attr.RESBufferIndex].Offset + index * v.BufferInfos[attr.RESBufferIndex].Stride + attr.BufferOffset));

                            switch (attr.AttributeName)
                            {
                            case 1:
                                vert.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                break;

                            case 2:
                                vert.Nrm = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                break;

                            case 5:
                                vert.UV0 = new OpenTK.Vector2(r.ReadSingle(), r.ReadSingle());
                                break;

                            case 8:
                                var b1 = v.Bones[r.ReadInt32()];
                                var b2 = v.Bones[r.ReadInt32()];
                                var b3 = v.Bones[r.ReadInt32()];
                                var b4 = v.Bones[r.ReadInt32()];
                                vert.Bones = new OpenTK.Vector4(Skeleton.IndexOf(Skeleton.GetBoneByName(b1)),
                                                                Skeleton.IndexOf(Skeleton.GetBoneByName(b2)),
                                                                Skeleton.IndexOf(Skeleton.GetBoneByName(b3)),
                                                                Skeleton.IndexOf(Skeleton.GetBoneByName(b4)));
                                break;

                            case 7:
                                vert.Weights = new OpenTK.Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                break;
                            }
                        }

                        if (v.Bones.Count == 1)
                        {
                            vert.Bones   = new OpenTK.Vector4(Skeleton.IndexOf(Skeleton.GetBoneByName(v.Bones[0])), 0, 0, 0);
                            vert.Weights = new OpenTK.Vector4(1, 0, 0, 0);
                        }

                        m.Vertices.Add(vert);
                        m.Triangles.Add(i / 2);

                        //Console.WriteLine(index + " " + v.BufferOffsets[0].ToString("X") + " " + v.BufferInfos[0].Offset + " " + v.BufferInfos[0].Stride);
                    }
                    //m.Optimize();
                }
            }

            return(mdl);
        }