Пример #1
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);
        }
Пример #2
0
 public static void SetVisited <VertexT, EdgeT, GraphT>(this GenericVertex <VertexT, EdgeT, GraphT> v, bool visitedOrNot)
     where VertexT : GenericVertex <VertexT, EdgeT, GraphT>
     where EdgeT : GenericEdge <VertexT, EdgeT, GraphT>
     where GraphT : GenericGraph <VertexT, EdgeT, GraphT>
 {
     v.Flags[(int)GenericVertex <VertexT, EdgeT, GraphT> .VertexFlags.VertexFlags_Visited] = visitedOrNot;
 }
Пример #3
0
        private static string WriteWeights(GenericVertex v)
        {
            StringBuilder o = new StringBuilder();

            int Count = 0;

            if (v.Weights.X != 0)
            {
                Count++;
                o.Append($"{v.Bones.X} {v.Weights.X} ");
            }
            if (v.Weights.Y != 0)
            {
                Count++;
                o.Append($"{v.Bones.Y} {v.Weights.Y} ");
            }
            if (v.Weights.Z != 0)
            {
                Count++;
                o.Append($"{v.Bones.Z} {v.Weights.Z} ");
            }
            if (v.Weights.W != 0)
            {
                Count++;
                o.Append($"{v.Bones.W} {v.Weights.W} ");
            }


            return(Count + " " + o.ToString());
        }
Пример #4
0
        public static GenericVertex[] GetAccelDecor(RedLine line)
        {
            var linecolor  = Constants.RedLineColor;
            var multiplier = ((RedLine)line).Multiplier;

            GenericVertex[] ret    = new GenericVertex[3 * multiplier];
            var             angle  = Angle.FromLine(line.End, line.Start);
            var             angle2 = Angle.FromRadians(angle.Radians - 1.5708f);
            var             start  = line.Position2;

            for (int idx = 0; idx < multiplier; idx++)
            {
                var a = start;
                var b = angle.MovePoint(start, line.inv ? -8 : 8);
                var c = angle2.MovePoint(b, 8);
                ret[idx * 3 + 0] = new GenericVertex((Vector2)a, linecolor);
                ret[idx * 3 + 1] = new GenericVertex((Vector2)b, linecolor);
                ret[idx * 3 + 2] = new GenericVertex((Vector2)c, linecolor);
                if (idx + 1 < multiplier)
                {
                    start = angle.MovePoint(start, line.inv ? -2 : 2);
                }
            }
            return(ret);
        }
Пример #5
0
 public static bool IsVisited <VertexT, EdgeT, GraphT>(this GenericVertex <VertexT, EdgeT, GraphT> v)
     where VertexT : GenericVertex <VertexT, EdgeT, GraphT>
     where EdgeT : GenericEdge <VertexT, EdgeT, GraphT>
     where GraphT : GenericGraph <VertexT, EdgeT, GraphT>
 {
     return(v.Flags[(int)GenericVertex <VertexT, EdgeT, GraphT> .VertexFlags.VertexFlags_Visited]);
 }
Пример #6
0
        public void Initialize(AutoArray <GameLine> lines)
        {
            Clear();
            ResourceSync initsync = new ResourceSync();

            GenericVertex[] vertices = new GenericVertex[lines.Count * wellsize];
            System.Threading.Tasks.Parallel.For(0, lines.Count, (idx) =>
            {
                var line = (StandardLine)lines[idx];
                var well = GetWell(line);
                for (int i = 0; i < wellsize; i++)
                {
                    vertices[idx * wellsize + i] = well[i];
                }
                try
                {
                    initsync.UnsafeEnterWrite();
                    _lines.Add(line.ID, idx * wellsize);
                }
                finally
                {
                    initsync.UnsafeExitWrite();
                }
            });
            _vertexcounter = vertices.Length;
            _vbo.Bind();
            EnsureVBOSize(vertices.Length, false);
            _vbo.SetData(vertices, 0, 0, vertices.Length);
            _vbo.Unbind();
        }
Пример #7
0
        private List <GenericVertex> GetVertexData()
        {
            List <GenericVertex> vertices = new List <GenericVertex>();

            using (DataReader d = new DataReader(new MemoryStream(Mesh.VertexData.TypelessData)))
            {
                var vertexData = Mesh.VertexData;

                // calucate channel strides
                Dictionary <int, int> channelToStride = new Dictionary <int, int>();
                foreach (var c in vertexData.Channels)
                {
                    if (!channelToStride.ContainsKey(c.Stream))
                    {
                        channelToStride.Add(c.Stream, 0);
                    }

                    channelToStride[c.Stream] = Math.Max(channelToStride[c.Stream], c.Offset + 4 * c.Diminsion);
                }

                for (int i = 0; i < Mesh.VertexData.VertexCount; i++)
                {
                    GenericVertex v     = new GenericVertex();
                    int           index = 0;
                    foreach (var c in vertexData.Channels)
                    {
                        d.Position = (uint)(i * channelToStride[c.Stream]);
                        if (c.Stream == 1)
                        {
                            d.Position += (uint)(channelToStride[0] * vertexData.VertexCount);
                        }
                        switch (index)
                        {
                        case 0:
                            if (c.Diminsion != 3 || c.Format != 0)
                            {
                                throw new NotSupportedException();
                            }
                            v.Pos = new Vector3(d.ReadSingle(), d.ReadSingle(), d.ReadSingle());
                            //v.Pos = v.Pos.Xzy;
                            break;

                        case 1:
                            if (c.Diminsion != 3 || c.Format != 0)
                            {
                                throw new NotSupportedException();
                            }
                            v.Nrm = new Vector3(d.ReadSingle(), d.ReadSingle(), d.ReadSingle());
                            //v.Nrm = v.Nrm.Xzy;
                            break;
                        }
                        index++;
                    }
                    vertices.Add(v);
                }
            }

            return(vertices);
        }
Пример #8
0
        private static List<GenericVertex> ToGenericVertices(List<DivaVertex> inVerts)
        {
            List<GenericVertex> outVerts = new List<GenericVertex>();

            foreach(var v in inVerts)
            {
                var vertex = new GenericVertex()
                {
                    Pos = new Vector3(v.Position.X, v.Position.Y, v.Position.Z),
                    Nrm = new Vector3(v.Normal.X, v.Normal.Y, v.Normal.Z),
                    UV0 = new Vector2(v.UV0.X, v.UV0.Y),
                    Clr = new Vector4(v.Color.X, v.Color.Y, v.Color.Z, v.Color.W)
                };
                int weightCount = 0;
                if(v.Weights.X > 0)
                {
                    vertex.Bones[weightCount] = v.Bones.X;
                    vertex.Weights[weightCount++] = v.Weights.X;
                }
                if (v.Weights.Y > 0)
                {
                    vertex.Bones[weightCount] = v.Bones.Y;
                    vertex.Weights[weightCount++] = v.Weights.Y;
                }
                if (v.Weights.Z > 0)
                {
                    vertex.Bones[weightCount] = v.Bones.Z;
                    vertex.Weights[weightCount++] = v.Weights.Z;
                }
                if (v.Weights.W > 0)
                {
                    vertex.Bones[weightCount] = v.Bones.W;
                    vertex.Weights[weightCount++] = v.Weights.W;
                }
                if (v.WeightsExt.X > 0)
                {
                    vertex.Bones[weightCount] = v.BonesExt.X;
                    vertex.Weights[weightCount++] = v.WeightsExt.X;
                }
                if (v.WeightsExt.Y > 0)
                {
                    vertex.Bones[weightCount] = v.BonesExt.Y;
                    vertex.Weights[weightCount++] = v.WeightsExt.Y;
                }
                if (v.WeightsExt.Z > 0)
                {
                    vertex.Bones[weightCount] = v.BonesExt.Z;
                    vertex.Weights[weightCount++] = v.WeightsExt.Z;
                }
                if (v.WeightsExt.W > 0)
                {
                    vertex.Bones[weightCount] = v.BonesExt.W;
                    vertex.Weights[weightCount++] = v.WeightsExt.W;
                }
                outVerts.Add(vertex);
            }

            return outVerts;
        }
Пример #9
0
        public static GenericVertex[] GetAccelDecor(RedLine line)
        {
            var linecolor  = Constants.RedLineColor;
            var multiplier = ((RedLine)line).Multiplier;
            var shapecount = Math.Min(multiplier, 3);

            if (multiplier > 3)
            {
                shapecount += 4;
            }
            GenericVertex[] ret    = new GenericVertex[3 * shapecount];
            var             angle  = Angle.FromLine(line.End, line.Start);
            var             angle2 = Angle.FromRadians(angle.Radians - 1.5708f);
            var             start  = line.Position2;

            for (int idx = 0; idx < Math.Min(multiplier, 3); idx++)
            {
                var a = start;
                var b = angle.MovePoint(start, line.inv ? -8 : 8);
                var c = angle2.MovePoint(b, 8);
                ret[idx * 3 + 0] = new GenericVertex((Vector2)a, linecolor);
                ret[idx * 3 + 1] = new GenericVertex((Vector2)b, linecolor);
                ret[idx * 3 + 2] = new GenericVertex((Vector2)c, linecolor);
                if (idx + 1 < multiplier)
                {
                    start = angle.MovePoint(start, line.inv ? -2 : 2);
                }
            }

            if (multiplier > 3)
            {
                // Draw White plus
                var a = angle.MovePoint(start, line.inv ? -2 : 2);
                var b = angle2.MovePoint(a, 2);
                var c = angle2.MovePoint(b, 3);

                Vector2[] tall = Utility.GetThickLine(
                    (Vector2)b, (Vector2)c, Angle.FromVector(c - b), 0.5f);
                Vector2[] tess = Utility.TesselateThickLine(tall);
                for (int i = 0; i < tess.Length; i++)
                {
                    ret[3 * 3 + i] = new GenericVertex(tess[i], Color.White);
                }

                a = angle2.MovePoint(b, 1.5);
                b = angle.MovePoint(a, -1.5);
                c = angle.MovePoint(a, 1.5);

                tall = Utility.GetThickLine(
                    (Vector2)b, (Vector2)c, Angle.FromVector(c - b), 0.5f);
                tess = Utility.TesselateThickLine(tall);
                for (int i = 0; i < tess.Length; i++)
                {
                    ret[5 * 3 + i] = new GenericVertex(tess[i], Color.White);
                }
            }
            return(ret);
        }
Пример #10
0
        public void RemoveLine(StandardLine line)
        {
            var vertexbase = _lines[line.ID];
            var empty      = new GenericVertex[wellsize];

            _vbo.Bind();
            _vbo.SetData(empty, 0, vertexbase, wellsize);
            _vbo.Unbind();
        }
Пример #11
0
        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());
                }
            }
        }
Пример #12
0
        public void Initialize(List <RedLine> lines)
        {
            Clear();
            if (lines.Count == 0)
            {
                return;
            }
            //max size for init
            var          redshapes = new GenericVertex[lines.Count * ShapeSize * 3][];
            ResourceSync initsync  = new ResourceSync();
            int          vertcount = 0;

            System.Threading.Tasks.Parallel.For(0, lines.Count,
                                                (idx) =>
            {
                var acc        = GetAccelDecor(lines[idx]);
                redshapes[idx] = acc;
                System.Threading.Interlocked.Add(ref vertcount, acc.Length);
            });
            GenericVertex[] verts = new GenericVertex[vertcount];
            _indices.EnsureCapacity(vertcount);
            _indices.UnsafeSetCount(vertcount);
            int shapepos = 0;

            for (int idx = 0; idx < lines.Count; idx++)
            {
                var acc   = redshapes[idx];
                var entry = new accelentry()
                {
                    start  = shapepos,
                    shapes = acc.Length / ShapeSize
                };
                for (int i = 0; i < acc.Length; i++)
                {
                    verts[shapepos] = acc[i];
                    _indices.unsafe_array[shapepos] = shapepos;
                    shapepos++;
                }
                _lookup.Add(lines[idx].ID, entry);
            }


            _vertcount = verts.Length;
            _accelbuffer.Bind();
            EnsureVBOSize(verts.Length, false);
            _accelbuffer.SetData(verts, 0, 0, verts.Length);
            _accelbuffer.Unbind();
            _accelibo.Bind();
            EnsureIBOSize(_indices.Count, false);
            _accelibo.SetData(_indices.unsafe_array, 0, 0, _indices.Count);
            _accelibo.Unbind();
        }
Пример #13
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);
        }
Пример #14
0
        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;
            }
        }
Пример #15
0
        private List <GenericVertex> GetCompVertexData()
        {
            List <GenericVertex> vertices = new List <GenericVertex>();

            var positions = Mesh.CompVertices.GetDecompressedFloats();

            for (int i = 0; i < positions.Length / 3; i++)
            {
                var vert = new GenericVertex();
                vert.Pos = new Vector3(positions[i * 3 + 0], positions[i * 3 + 1], positions[i * 3 + 2]);
                vertices.Add(vert);
            }

            return(vertices);
        }
Пример #16
0
        private GenericVertex SingleBind(GenericVertex vert, GenericSkeleton s)
        {
            Vector3 p = Vector3.Zero;
            Vector3 n = Vector3.Zero;

            for (int i = 0; i < 1; i++)
            {
                if (vert.Weights[i] > 0)
                {
                    n += Vector3.TransformNormal(vert.Nrm, s.GetWorldTransform((int)vert.Bones[i]));   // * vert.Weights[i];
                    p += Vector3.TransformPosition(vert.Pos, s.GetWorldTransform((int)vert.Bones[i])); // * vert.Weights[i];
                }
            }

            vert.Pos = p;
            vert.Nrm = n;
            return(vert);
        }
Пример #17
0
        public static GenericVertex[] GetWell(StandardLine line)
        {
            var angle = Angle.FromLine(line);

            angle.Radians += line.inv ? -1.5708 : 1.5708; //90 degrees
            var offset    = angle.MovePoint(Vector2d.Zero, StandardLine.Zone);
            var wellcolor = Color.FromArgb(80, 80, 80, 80);
            var tl        = new GenericVertex((Vector2)(line.Start), wellcolor);
            var tr        = new GenericVertex((Vector2)(line.End), wellcolor);
            var bl        = new GenericVertex((Vector2)(line.End + offset), wellcolor);
            var br        = new GenericVertex((Vector2)(line.Start + offset), wellcolor);

            return(new GenericVertex[]
            {
                tl, tr, bl,
                bl, br, tl
            });
        }
Пример #18
0
        private List <GenericVertex> ToGenericVertex(GXVertex[] InVerts, List <HSD_JOBJ> BoneList, List <HSD_JOBJWeight> WeightList, HSD_JOBJ parent)
        {
            var finalList = new List <GenericVertex>(InVerts.Length);

            var transform = skeleton.GetWorldTransform(skeleton.Bones[jobjToIndex[parent]]);

            foreach (var inVert in InVerts)
            {
                GenericVertex vertex = new GenericVertex();
                vertex.Pos = Vector3.TransformPosition(new Vector3(inVert.Pos.X, inVert.Pos.Y, inVert.Pos.Z), transform);
                vertex.Nrm = Vector3.TransformNormal(new Vector3(inVert.Nrm.X, inVert.Nrm.Y, inVert.Nrm.Z), transform);
                vertex.UV0 = new Vector2(inVert.TEX0.X, inVert.TEX0.Y);
                if (inVert.Clr0.A != 0 || inVert.Clr0.R != 0 || inVert.Clr0.G != 0 || inVert.Clr0.B != 0)
                {
                    vertex.Clr = new Vector4(inVert.Clr0.R, inVert.Clr0.G, inVert.Clr0.B, inVert.Clr0.A);
                }

                vertex.Bones   = new Vector4(jobjToIndex[parent], 0, 0, 0);
                vertex.Weights = new Vector4(1, 0, 0, 0);

                if (WeightList != null)
                {
                    var weightList = WeightList[inVert.PMXID / 3];
                    // single bind fix
                    if (weightList != null && weightList.JOBJs.Count == 1)
                    {
                        vertex.Pos = Vector3.TransformPosition(vertex.Pos, skeleton.GetWorldTransform(skeleton.Bones[jobjToIndex[weightList.JOBJs[0]]]));
                        vertex.Nrm = Vector3.TransformNormal(vertex.Nrm, skeleton.GetWorldTransform(skeleton.Bones[jobjToIndex[weightList.JOBJs[0]]]));
                    }

                    //Bone Weights
                    for (int i = 0; i < weightList.Weights.Count; i++)
                    {
                        vertex.Bones[i]   = jobjToIndex[weightList.JOBJs[i]];
                        vertex.Weights[i] = weightList.Weights[i];
                    }
                }

                finalList.Add(vertex);
            }

            return(finalList);
        }
Пример #19
0
        private GenericVertex ReadVertex(DataReader reader, int weightCount)
        {
            GenericVertex v = new GenericVertex();

            v.Pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
            v.Nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

            if (weightCount == 1)
            {
                v.Bones   = new Vector4(reader.ReadInt32(), 0, 0, 0);
                v.Weights = new Vector4(1, 0, 0, 0);
            }
            else
            if (weightCount == 2)
            {
                for (int w = 0; w < weightCount; w++)
                {
                    v.Weights[w] = reader.ReadSingle();
                }
                for (int w = 0; w < weightCount; w++)
                {
                    v.Bones[w] = reader.ReadInt16();
                }
            }
            else
            if (weightCount == 4)
            {
                for (int w = 0; w < weightCount; w++)
                {
                    v.Weights[w] = reader.ReadSingle();
                }
                for (int w = 0; w < weightCount; w++)
                {
                    v.Bones[w] = reader.ReadByte();
                }
            }
            return(v);
        }
Пример #20
0
        public List <GenericVertex> GetVertex(int bufferIndex)
        {
            var buffer     = Buffers[bufferIndex];
            var attributes = Attributes[bufferIndex];

            var max = 0;

            //Console.WriteLine(i + " " + buffer.Count + " " + buffer.Buffer.Length / buffer.Stride);

            List <GenericVertex> vertices = new List <GenericVertex>();

            using (DataReader r = new DataReader(new MemoryStream(buffer.Buffer)))
            {
                for (int i = 0; i < buffer.Count; i++)
                {
                    GenericVertex vert = new GenericVertex();
                    foreach (var att in attributes)
                    {
                        r.Seek((uint)(i * buffer.Stride + att.offset));

                        switch ((G1MVertexAttribute)att.semantic)
                        {
                        case G1MVertexAttribute.POSITION:     //Position
                            if (att.datatype < 4)
                            {
                                vert.Pos      = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                vert.Extra3.X = r.ReadSingle();
                            }
                            else
                            {
                                throw new Exception("Verty 0x" + att.datatype.ToString("x"));
                            }
                            break;

                        case G1MVertexAttribute.WEIGHT:     //Weights?
                            if (att.datatype == 0x0B)
                            {
                                vert.Weights = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle());
                            }
                            else if (att.datatype == 0x02)
                            {
                                vert.Weights = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 0);     // 4th is calculated?
                            }
                            else if (att.datatype == 0x03)
                            {
                                vert.Weights = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                            }
                            else if (att.datatype == 0x0A)
                            {
                                vert.Weights = new Vector4(r.ReadHalfSingle(),
                                                           r.ReadHalfSingle(),
                                                           0,
                                                           0);
                                vert.Weights.Z = 1.0f - vert.Weights.X - vert.Weights.Y;
                            }
                            else
                            {
                                throw new Exception("Weight " + att.datatype);
                                //Console.WriteLine();
                            }
                            //
                            break;

                        case G1MVertexAttribute.BONES:     //Nodes?
                            if (att.datatype == 0x05)
                            {
                                //if(!cloth)
                                vert.Bones = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte());
                                //Console.WriteLine((vertBuffer[i].node/3).ToString());
                            }
                            else
                            if (att.datatype == 0x0D)
                            {
                                vert.Bones = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte());
                            }
                            else
                            {
                                Console.WriteLine("Bone Weight " + att.datatype);
                            }
                            break;

                        case G1MVertexAttribute.NORMALS:     //Normals?
                            if (att.datatype == 0x0b)
                            {
                                vert.Nrm      = new Vector3(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle());
                                vert.Extra3.Y = (r.ReadHalfSingle());
                            }
                            if (att.datatype == 0x02 || att.datatype == 0x03)
                            {
                                vert.Nrm      = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                                vert.Extra3.Y = (r.ReadSingle());
                            }
                            break;

                        case G1MVertexAttribute.TEXCOORD0:     //UV?
                            var uv = Vector2.Zero;
                            if (att.datatype == 0x0A || att.datatype == 1)
                            {
                                uv = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle());
                            }
                            else
                            if (att.datatype == 0x5)
                            {
                                vert.Extra2 = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte());
                            }
                            else
                            {
                                Console.WriteLine(att.datatype);
                            }
                            if (att.track == 0)
                            {
                                vert.UV0 = uv;
                            }
                            break;

                        case G1MVertexAttribute.BINORMAL:
                            if (att.datatype == 0x02)
                            {
                                vert.Bit = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1);
                            }
                            else if (att.datatype == 0x03)
                            {
                                vert.Bit = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                            }
                            else if (att.datatype == 0x0B)
                            {
                                vert.Bit = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle());
                            }
                            else
                            {
                                throw new Exception("Unknown vertex stream 0x0A01 type.");
                            }
                            break;

                        case G1MVertexAttribute.TANGENT:
                            if (att.datatype == 0x02)
                            {
                                vert.Tan = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1);
                            }
                            else if (att.datatype == 0x03)
                            {
                                vert.Tan = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                            }
                            else if (att.datatype == 0x0B)
                            {
                                vert.Tan = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle());
                            }
                            else
                            {
                                throw new Exception("Unknown vertex stream 0x0600 type.");
                            }
                            break;

                        case G1MVertexAttribute.FOG:
                            if (att.track == 0 && att.datatype == 5)
                            {
                                vert.Fog = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte());
                            }
                            break;

                        case G1MVertexAttribute.COLOR:
                            var colr = Vector4.One;
                            if (att.datatype == 0x02)
                            {
                                colr = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1);
                            }
                            else if (att.datatype == 0x03)
                            {
                                colr = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                            }
                            else if (att.datatype == 0x0B)
                            {
                                colr = new Vector4(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle());
                            }
                            else if (att.datatype == 0x0D)
                            {
                                colr = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f);
                            }
                            else
                            {
                                throw new Exception("Unknown vertex stream 0x0A01 type.");
                            }

                            if (att.track == 0)
                            {
                                vert.Clr = Vector4.One;    // colr;
                            }
                            else
                            {
                                vert.Clr1 = colr;
                            }
                            break;

                        case G1MVertexAttribute.UNK1:
                            if (att.datatype == 0x05)
                            {
                                vert.Extra = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte());
                            }
                            break;

                        default:
                            //if(type.Equals("3DS"))
                            //File.WriteAllBytes("dump.bin", buffer.Buffer);
                            throw new Exception("Unknown Semantic " + att.semantic.ToString("x") + " " + att.offset.ToString("X"));
                            //break;
                        }
                    }

                    vertices.Add(vert);
                }
            }
            Console.WriteLine("Max: " + max.ToString("X"));

            return(vertices);
        }
Пример #21
0
        private List <GenericVertex> ParseBuffer(byte[] buffer)
        {
            List <GenericVertex> Vertices = new List <GenericVertex>();

            byte[] attributeBuffer = new byte[0];
            int    stride          = 0;
            int    vertexCount     = 0;

            using (DataReader r = new DataReader(new System.IO.MemoryStream(buffer)))
            {
                r.Seek(0x4);
                uint attOffset    = r.ReadUInt16();
                int  attSomething = r.ReadInt16();
                uint verOffset    = r.ReadUInt16();
                stride      = r.ReadInt16();
                vertexCount = r.ReadInt32();

                attributeBuffer = Decompress.Level5Decom(r.GetSection(attOffset, attSomething));
                buffer          = Decompress.Level5Decom(r.GetSection(verOffset, (int)(r.Length - verOffset)));
            }

            int[] ACount = new int[10];
            int[] AOffet = new int[10];
            int[] ASize  = new int[10];
            int[] AType  = new int[10];
            using (DataReader r = new DataReader(new System.IO.MemoryStream(attributeBuffer)))
            {
                for (int i = 0; i < 10; i++)
                {
                    ACount[i] = r.ReadByte();
                    AOffet[i] = r.ReadByte();
                    ASize[i]  = r.ReadByte();
                    AType[i]  = r.ReadByte();

                    if (ACount[i] > 0 && i != 0 && i != 1 && i != 2 && i != 4 && i != 7 && i != 8 && i != 9)
                    {
                        Console.WriteLine(i + " " + ACount[i] + " " + AOffet[i] + " " + ASize[i] + " " + AType[i]);
                    }
                }
            }

            using (DataReader r = new DataReader(new System.IO.MemoryStream(buffer)))
            {
                for (int i = 0; i < vertexCount; i++)
                {
                    GenericVertex vert = new GenericVertex();
                    vert.Clr = new Vector4(1, 1, 1, 1);
                    for (int j = 0; j < 10; j++)
                    {
                        r.Seek((uint)(i * stride + AOffet[j]));
                        switch (j)
                        {
                        case 0:     //Position
                            vert.Pos = ReadAttribute(r, AType[j], ACount[j]).Xyz;
                            break;

                        case 1:     //Tangent
                            break;

                        case 2:     //Normal
                            vert.Nrm = ReadAttribute(r, AType[j], ACount[j]).Xyz;
                            break;

                        case 4:     //UV0
                            vert.UV0 = ReadAttribute(r, AType[j], ACount[j]).Xy;
                            break;

                        case 7:     //Bone Weight
                            vert.Weights = ReadAttribute(r, AType[j], ACount[j]);
                            break;

                        case 8:     //Bone Index
                            Vector4 vn = ReadAttribute(r, AType[j], ACount[j]);
                            if (NodeTable.Length > 0 && NodeTable.Length != 1)
                            {
                                vert.Bones = new Vector4(NodeTable[(int)vn.X], NodeTable[(int)vn.Y], NodeTable[(int)vn.Z], NodeTable[(int)vn.W]);
                            }
                            break;

                        case 9:     // Color
                            vert.Clr = ReadAttribute(r, AType[j], ACount[j]).Yzwx;
                            break;
                        }
                    }
                    Vertices.Add(vert);
                }
            }

            //
            return(Vertices);
        }
Пример #22
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);
                }
            }
        }
Пример #23
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();
        }
Пример #24
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);
                }
            }
        }
Пример #25
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();
                }
            }
        }
Пример #26
0
        public void ParseOBE(byte[] data)
        {
            DataReader reader = new DataReader(new MemoryStream(data));

            reader.BigEndian = true;
            reader.Position  = 0x20;
            var vertexCount  = reader.ReadUInt32();
            var vertexOffset = reader.ReadUInt32();

            var dataChunkCount  = reader.ReadInt32();
            var dataChunkOffset = reader.ReadUInt32();
            var dataOffset      = reader.ReadUInt32();

            int[] chunkCounts = new int[dataChunkCount];
            reader.Position = dataChunkOffset;
            for (int i = 0; i < dataChunkCount; i++)
            {
                chunkCounts[i]   = reader.ReadInt32();
                reader.Position += 12; // there's a hash here too
            }

            int totalChunks = 0;

            reader.Position = dataOffset;
            foreach (var count in chunkCounts)
            {
                var vertices = new List <MeshObject>();
                meshGroups.Add(vertices);
                totalChunks += count;
                for (int i = 0; i < count; i++)
                {
                    // GAMECUBE
                    var ob = new MeshObject();
                    ob.PrimitiveType = reader.ReadInt16() >> 8;
                    ob.VertexCount   = reader.ReadInt16();
                    ob.BoneIndices   = new int[reader.ReadByte()];
                    ob.UnkCount      = reader.ReadByte();
                    reader.Position += 2;

                    for (int bi = 0; bi < ob.BoneIndices.Length; bi++)
                    {
                        ob.BoneIndices[bi] = reader.ReadByte();
                    }

                    vertices.Add(ob);
                    reader.Position += (uint)(0xA - ob.BoneIndices.Length);

                    // XBOX

                    /*var ob = new MeshObject()
                     * {
                     *  PrimitiveType = reader.ReadInt16(),
                     *  VertexCount = reader.ReadInt16(),
                     * };
                     * ob.BoneIndices = new int[reader.ReadInt16()];
                     * ob.UnkCount = reader.ReadInt16();
                     *
                     * Console.WriteLine(ob.VertexCount.ToString("X") + " " + ob.PrimitiveType);
                     *
                     * for (int bi = 0; bi < ob.BoneIndices.Length; bi++)
                     *  ob.BoneIndices[bi] = reader.ReadByte();
                     *
                     * meshObjects.Add(ob);
                     *
                     * reader.Position += (uint)(0x30 - ob.BoneIndices.Length);*/
                }
            }


            reader.Position = 0xA0; // 0x80
            var ModelInfoOffset = reader.ReadUInt32();
            var ModelInfoCount  = reader.ReadUInt32();

            ParseBone(reader, ModelInfoOffset);

            //Skeleton.TransformWorldToRelative();

            reader.Position = 0x94;
            var SomeOffset = reader.ReadUInt32();
            var SomeCount  = reader.ReadUInt32();

            for (var ob = 0; ob < SomeCount; ob++)
            {
                var hash = reader.ReadUInt32();
                var c    = reader.ReadUInt16();
            }

            reader.Position = 0x50;
            int maxBoneWeight = reader.ReadByte();

            reader.ReadByte();
            int flag = reader.ReadUInt16();
            var VertexTableReaderOffset = reader.ReadUInt32();
            var VertexTableOffset       = reader.ReadUInt32();
            var VertexTableSize         = reader.ReadUInt32();
            var positionTableOffset     = reader.ReadUInt32();
            var normalTableOffset       = reader.ReadUInt32();
            var uvTableOffset           = reader.ReadUInt32();
            var colorTableOffset        = reader.ReadUInt32();

            reader.ReadUInt32(); //vertex count
            reader.ReadUInt32(); //normal count
            var morphTargetOffset = reader.ReadUInt32();

            if (flag == 0x12 || flag == 0x1A)
            {
                reader.Position = VertexTableReaderOffset;
                for (int i = 0; i < totalChunks; i++)
                {
                    var offset = reader.ReadUInt32();
                    var size   = reader.ReadUInt32();

                    var temp = reader.Position;
                    reader.Position = VertexTableOffset + offset;
                    int primType  = reader.ReadInt16();
                    int vertCount = reader.ReadInt16();

                    for (int v = 0; v < vertCount; v++)
                    {
                        if (maxBoneWeight == 1)
                        {
                            reader.ReadByte(); // bone probably divide by 3
                        }
                        var vertexIndex = reader.ReadInt16();
                        var normalIndex = reader.ReadInt16();
                        var colorIndex  = reader.ReadInt16();
                        var uvIndex     = reader.ReadInt16();

                        var temp2 = reader.Position;

                        var vertex = new GenericVertex();

                        int stride = 0x20;
                        if (maxBoneWeight == 1)
                        {
                            stride = 0x10;
                        }

                        reader.Position = (uint)(vertexOffset + stride * vertexIndex);

                        vertex.Pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        if (maxBoneWeight == 1)
                        {
                            vertex.Bones   = new Vector4(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                            vertex.Weights = new Vector4(1, 0, 0, 0);
                            //Console.WriteLine(vertex.Bones.ToString());//TODO: I don't understand
                        }
                        else
                        if (maxBoneWeight == 2 || maxBoneWeight == 3 || maxBoneWeight == 4)
                        {
                            vertex.Bones   = new Vector4(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
                            vertex.Weights = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0);
                            reader.ReadSingle();
                        }
                        else
                        {
                            throw new NotImplementedException($"Bone Weight {maxBoneWeight} not supported");
                        }

                        //reader.Position = (uint)(positionTableOffset + 12 * vertexIndex);
                        //vertex.Pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                        reader.Position = (uint)(normalTableOffset + 3 * normalIndex);
                        vertex.Nrm      = new Vector3(reader.ReadSByte(), reader.ReadSByte(), reader.ReadSByte());
                        vertex.Nrm.Normalize();

                        reader.Position = (uint)(uvTableOffset + 8 * uvIndex);
                        vertex.UV0      = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                        reader.Position = (uint)(colorTableOffset + 4 * colorIndex);
                        vertex.Clr      = new Vector4(reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f);

                        vertices.Add(vertex);

                        reader.Position = temp2;
                    }

                    reader.Position = temp;
                }
                //FixBoneIndices();
            }
            else
            {
                reader.Position = vertexOffset;
                for (var v = 0; v < vertexCount; v++)
                {
                    // GAMECUBE
                    var vertex = new GenericVertex();

                    vertex.Pos     = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    vertex.Weights = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0);
                    vertex.Bones   = new Vector4(reader.ReadByte() / 3, reader.ReadByte() / 3, reader.ReadByte() / 3, reader.ReadByte() / 3);
                    vertex.Nrm     = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    vertex.Clr     = new Vector4(reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f, reader.ReadByte() / 128f);
                    vertex.UV0     = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                    vertices.Add(vertex);
                }

                FixBoneIndices();
            }


            //Morphs ------------------------

            reader.Position = morphTargetOffset;

            var numOfMorphs      = reader.ReadInt32();
            var morphVertexCount = reader.ReadInt32();
            var morphFlag        = reader.ReadInt32();

            reader.Position = morphTargetOffset + 0x40;
            for (int m = 0; m < numOfMorphs; m++)
            {
                var MorphVertex = new Dictionary <int, GenericVertex>();
                for (int i = 0; i < morphVertexCount; i++)
                {
                    var morphPos       = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    int vertexPosition = reader.ReadInt32();
                    var morphNormal    = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    reader.ReadInt32();
                    // ??
                    if (morphFlag == 1)
                    {
                        reader.Position += 16;
                    }

                    MorphVertex.Add(vertexPosition, new GenericVertex()
                    {
                        Pos = vertices[vertexPosition].Pos + morphPos,
                        Nrm = morphNormal
                    });

                    /*if(m == 7)
                     * {
                     *  var vertex = vertices[vertexPosition];
                     *  vertex.Pos = vertices[vertexPosition].Pos + morphPos;
                     *  vertices[vertexPosition] = vertex;
                     * }*/
                }
                _morphs.Add($"Morph_{m}", MorphVertex);
            }
        }
Пример #27
0
        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);
        }
Пример #28
0
        public void Export(string FilePath, GenericModel Model)
        {
            using (StreamWriter w = new StreamWriter(new FileStream(FilePath, FileMode.Create)))
            {
                w.WriteLine("version 1");

                if (Model.Skeleton != null)
                {
                    w.WriteLine("nodes");
                    foreach (GenericBone bone in Model.Skeleton.Bones)
                    {
                        w.WriteLine($" {Model.Skeleton.IndexOf(bone)} \"{bone.Name}\" {bone.ParentIndex}");
                    }
                    // meshNodes
                    foreach (var mesh in Model.Meshes)
                    {
                        w.WriteLine($" {Model.Skeleton.Bones.Count + Model.Meshes.IndexOf(mesh)} \"{mesh.Name}\" -1");
                    }
                    w.WriteLine("end");
                    w.WriteLine("skeleton");
                    w.WriteLine("time 0");
                    foreach (GenericBone bone in Model.Skeleton.Bones)
                    {
                        w.WriteLine($" {Model.Skeleton.IndexOf(bone)} {bone.Position.X} {bone.Position.Y} {bone.Position.Z} {bone.Rotation.X} {bone.Rotation.Y} {bone.Rotation.Z}");
                    }
                    foreach (var mesh in Model.Meshes)
                    {
                        w.WriteLine($" {Model.Skeleton.Bones.Count + Model.Meshes.IndexOf(mesh)} 0 0 0 0 0 0");
                    }
                    w.WriteLine("end");
                }

                w.WriteLine("triangles");
                Dictionary <GenericTexture, string> TextureBank = new Dictionary <GenericTexture, string>();
                foreach (GenericMesh m in Model.Meshes)
                {
                    if (!m.Export)
                    {
                        continue;
                    }

                    var meshIndex = Model.Skeleton.Bones.Count + Model.Meshes.IndexOf(m);
                    m.MakeTriangles();
                    string MaterialName = m.Name;
                    if (m.MaterialName != null && Model.MaterialBank.ContainsKey(m.MaterialName))
                    {
                        var material = Model.MaterialBank[m.MaterialName];
                        if (material.TextureDiffuse != null && Model.TextureBank.ContainsKey(material.TextureDiffuse))
                        {
                            var texture = Model.TextureBank[material.TextureDiffuse];
                            if (TextureBank.ContainsKey(texture))
                            {
                                MaterialName = TextureBank[texture];
                            }
                            else
                            {
                                string TextureName = material.TextureDiffuse.Equals("") ? "Texture_" + TextureBank.Count + ".png" : material.TextureDiffuse + ".png";

                                if (texture.Mipmaps.Count != 0)
                                {
                                    Rendering.RenderTexture Temp = new Rendering.RenderTexture();
                                    Temp.LoadGenericTexture(texture);
                                    Temp.ExportPNG(new FileInfo(FilePath).Directory.FullName + "/" + TextureName);
                                    Temp.Delete();
                                }
                                TextureBank.Add(texture, TextureName);
                                MaterialName = TextureName;
                            }
                        }
                    }
                    for (int i = 0; i < m.Triangles.Count; i += 3)
                    {
                        w.WriteLine(MaterialName);
                        {
                            GenericVertex v = m.Vertices[(int)m.Triangles[i]];
                            w.WriteLine($" {meshIndex} {v.Pos.X} {v.Pos.Y} {v.Pos.Z} {v.Nrm.X} {v.Nrm.Y} {v.Nrm.Z} {v.UV0.X} {v.UV0.Y} " + WriteWeights(v));
                        }
                        {
                            GenericVertex v = m.Vertices[(int)m.Triangles[i + 1]];
                            w.WriteLine($" {meshIndex} {v.Pos.X} {v.Pos.Y} {v.Pos.Z} {v.Nrm.X} {v.Nrm.Y} {v.Nrm.Z} {v.UV0.X} {v.UV0.Y} " + WriteWeights(v));
                        }
                        {
                            GenericVertex v = m.Vertices[(int)m.Triangles[i + 2]];
                            w.WriteLine($" {meshIndex} {v.Pos.X} {v.Pos.Y} {v.Pos.Z} {v.Nrm.X} {v.Nrm.Y} {v.Nrm.Z} {v.UV0.X} {v.UV0.Y} " + WriteWeights(v));
                        }
                    }
                }
                w.WriteLine("end");

                w.Close();
            }

            if (Model.HasMorphs)
            {
                WriteVTA(FilePath.Replace(".smd", ".vta"), Model);
            }
        }
Пример #29
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();
                }
            }
        }
Пример #30
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);
                }
            }
        }