Ejemplo n.º 1
0
        private RootEntity ParseHMD(BinaryReader reader, out List <Animation> animations, out List <Texture> textures)
        {
            animations = new List <Animation>();
            textures   = new List <Texture>();
            var mapFlag            = reader.ReadUInt32();
            var primitiveHeaderTop = reader.ReadUInt32() * 4;
            var blockCount         = reader.ReadUInt32();

            if (blockCount == 0 || blockCount > Program.MaxHMDBlockCount)
            {
                return(null);
            }
            var modelEntities = new List <ModelEntity>();

            for (uint i = 0; i < blockCount; i++)
            {
                var primitiveSetTop = reader.ReadUInt32() * 4;
                if (primitiveSetTop == 0)
                {
                    continue;
                }
                var blockTop = reader.BaseStream.Position;
                ProccessPrimitive(reader, modelEntities, animations, textures, i, primitiveSetTop, primitiveHeaderTop);
                reader.BaseStream.Seek(blockTop, SeekOrigin.Begin);
            }
            RootEntity rootEntity;

            if (modelEntities.Count > 0)
            {
                rootEntity = new RootEntity();
                foreach (var modelEntity in modelEntities)
                {
                    modelEntity.ParentEntity = rootEntity;
                }
                rootEntity.ChildEntities = modelEntities.ToArray();
                rootEntity.ComputeBounds();
            }
            else
            {
                rootEntity = null;
            }
            var coordCount = reader.ReadUInt32();

            for (var c = 0; c < coordCount; c++)
            {
                var localMatrix = ReadCoord(reader);
                foreach (var modelEntity in modelEntities)
                {
                    if (modelEntity.TMDID == c)
                    {
                        modelEntity.LocalMatrix = localMatrix;
                    }
                }
            }
            var primitiveHeaderCount = reader.ReadUInt32();

            return(rootEntity);
        }
Ejemplo n.º 2
0
        public bool SetupAnimationFrame(float frameIndex, RootEntity[] checkedEntities, RootEntity selectedRootEntity, ModelEntity selectedModelEntity, bool updateMeshData = false)
        {
            _scene.SkeletonBatch.Reset();
            RootEntity rootEntity = null;

            if (selectedRootEntity != null)
            {
                rootEntity = selectedRootEntity;
            }
            else if (selectedModelEntity != null)
            {
                rootEntity = selectedModelEntity.GetRootEntity();
            }
            _scene.MeshBatch.SetupMultipleEntityBatch(checkedEntities, selectedModelEntity, selectedRootEntity, _scene.TextureBinder, updateMeshData || _scene.AutoAttach, false, true);
            return(ProcessAnimationObject(_animation.RootAnimationObject, frameIndex, rootEntity, Matrix4.Identity));
        }
Ejemplo n.º 3
0
        private RootEntity ParsePMD(BinaryReader reader)
        {
            var primPoint = reader.ReadUInt32();
            var vertPoint = reader.ReadUInt32();
            var nObj      = reader.ReadUInt32();

            if (nObj < 1 || nObj > 4000)
            {
                return(null);
            }
            var models = new List <ModelEntity>();

            for (var o = 0; o < nObj; o++)
            {
                var model     = new ModelEntity();
                var triangles = new List <Triangle>();
                var nPointers = reader.ReadUInt32();
                if (nPointers < 1 || nPointers > 4000)
                {
                    return(null);
                }
                for (var p = 0; p < nPointers; p++)
                {
                    var position = reader.BaseStream.Position;
                    var pointer  = reader.ReadUInt32();
                    reader.BaseStream.Seek(_offset + pointer, SeekOrigin.Begin);
                    var nPacket = reader.ReadUInt16();
                    if (nPacket > 4000)
                    {
                        return(null);
                    }
                    var primType = reader.ReadUInt16();
                    if (primType > 15)
                    {
                        return(null);
                    }
                    for (var pk = 0; pk < nPacket; pk++)
                    {
                        switch (primType)
                        {
                        case 0x00:
                            triangles.Add(ReadPolyFT3(reader));
                            break;

                        case 0x01:
                            triangles.AddRange(ReadPolyFT4(reader));
                            break;

                        case 0x02:
                            triangles.Add(ReadPolyGT3(reader));
                            break;

                        case 0x03:
                            triangles.AddRange(ReadPolyGT4(reader));
                            break;

                        case 0x04:
                            triangles.Add(ReadPolyF3(reader));
                            break;

                        case 0x05:
                            triangles.AddRange(ReadPolyF4(reader));
                            break;

                        case 0x06:
                            triangles.Add(ReadPolyG3(reader));
                            break;

                        case 0x07:
                            triangles.AddRange(ReadPolyG4(reader));
                            break;

                        case 0x08:
                            triangles.Add(ReadPolyFT3(reader, true, _offset + vertPoint));
                            break;

                        case 0x09:
                            triangles.AddRange(ReadPolyFT4(reader, true, _offset + vertPoint));
                            break;

                        case 0x0a:
                            triangles.Add(ReadPolyGT3(reader, true, _offset + vertPoint));
                            break;

                        case 0x0b:
                            triangles.AddRange(ReadPolyGT4(reader, true, _offset + vertPoint));
                            break;

                        case 0x0c:
                            triangles.Add(ReadPolyF3(reader, true, _offset + vertPoint));
                            break;

                        case 0x0d:
                            triangles.AddRange(ReadPolyF4(reader, true, _offset + vertPoint));
                            break;

                        case 0x0e:
                            triangles.Add(ReadPolyG3(reader, true, _offset + vertPoint));
                            break;

                        case 0x0f:
                            triangles.AddRange(ReadPolyG4(reader, true, _offset + vertPoint));
                            break;

                        default:
                            if (Program.Debug)
                            {
                                Program.Logger.WriteErrorLine("Unknown primitive:" + primType);
                            }
                            goto EndObject;
                        }
                    }
                    reader.BaseStream.Seek(position + 4, SeekOrigin.Begin);
                }
EndObject:
                model.Triangles = triangles.ToArray();
                models.Add(model);
            }

EndModel:
            if (models.Count > 0)
            {
                var entity = new RootEntity();
                foreach (var model in models)
                {
                    model.ParentEntity = entity;
                }
                entity.ChildEntities = models.ToArray();
                entity.ComputeBounds();
                return(entity);
            }
            return(null);
        }
Ejemplo n.º 4
0
        private RootEntity ParseTmd(BinaryReader reader, string fileTitle)
        {
            var flags = reader.ReadUInt32();

            if (flags != 0 && flags != 1)
            {
                return(null);
            }

            var nObj = reader.ReadUInt32();

            if (nObj == 0 || nObj > Program.MaxTMDObjects)
            {
                return(null);
            }

            var models = new List <ModelEntity>();

            var objBlocks = new ObjBlock[nObj];

            var objOffset = reader.BaseStream.Position;

            for (var o = 0; o < nObj; o++)
            {
                var vertTop      = reader.ReadUInt32();
                var nVert        = reader.ReadUInt32();
                var normalTop    = reader.ReadUInt32();
                var nNormal      = reader.ReadUInt32();
                var primitiveTop = reader.ReadUInt32();
                var nPrimitive   = reader.ReadUInt32();
                var scale        = reader.ReadInt32();

                if (flags == 0)
                {
                    vertTop      += (uint)objOffset;
                    normalTop    += (uint)objOffset;
                    primitiveTop += (uint)objOffset;
                }

                if (nPrimitive > Program.MaxTMDPrimitives)
                {
                    return(null);
                }

                objBlocks[o] = new ObjBlock
                {
                    VertTop      = vertTop,
                    NVert        = nVert,
                    NormalTop    = normalTop,
                    NNormal      = nNormal,
                    PrimitiveTop = primitiveTop,
                    NPrimitive   = nPrimitive,
                    Scale        = scale
                };
            }

            for (uint o = 0; o < objBlocks.Length; o++)
            {
                var objBlock = objBlocks[o];

                var vertices = new Vector3[objBlock.NVert];
                if (Program.IgnoreTmdVersion && objBlock.VertTop < _offset)
                {
                    return(null);
                }
                reader.BaseStream.Seek(objBlock.VertTop, SeekOrigin.Begin);
                for (var v = 0; v < objBlock.NVert; v++)
                {
                    var vx  = reader.ReadInt16();
                    var vy  = reader.ReadInt16();
                    var vz  = reader.ReadInt16();
                    var pad = reader.ReadInt16();
                    if (pad != 0)
                    {
                        if (Program.Debug)
                        {
                            Program.Logger.WriteLine($"Found suspicious pad value of: {pad} at index:{v}");
                        }
                    }
                    var vertex = new Vector3
                    {
                        X = vx,
                        Y = vy,
                        Z = vz
                    };
                    vertices[v] = vertex;
                }

                var normals = new Vector3[objBlock.NNormal];
                if (Program.IgnoreTmdVersion && objBlock.NormalTop < _offset)
                {
                    return(null);
                }
                reader.BaseStream.Seek(objBlock.NormalTop, SeekOrigin.Begin);
                for (var n = 0; n < objBlock.NNormal; n++)
                {
                    var nx  = TMDHelper.ConvertNormal(reader.ReadInt16());
                    var ny  = TMDHelper.ConvertNormal(reader.ReadInt16());
                    var nz  = TMDHelper.ConvertNormal(reader.ReadInt16());
                    var pad = reader.ReadInt16();
                    if (pad != 0)
                    {
                        if (Program.Debug)
                        {
                            Program.Logger.WriteLine($"Found suspicious pad value of: {pad} at index:{n}");
                        }
                    }
                    var normal = new Vector3
                    {
                        X = nx,
                        Y = ny,
                        Z = nz
                    };
                    normals[n] = normal.Normalized();
                }

                var groupedTriangles = new Dictionary <uint, List <Triangle> >();

                reader.BaseStream.Seek(objBlock.PrimitiveTop, SeekOrigin.Begin);
                if (Program.IgnoreTmdVersion && objBlock.PrimitiveTop < _offset)
                {
                    return(null);
                }

                if (Program.Debug)
                {
                    Program.Logger.WriteLine($"Primitive count:{objBlock.NPrimitive} {fileTitle}");
                }
                for (var p = 0; p < objBlock.NPrimitive; p++)
                {
                    var olen            = reader.ReadByte();
                    var ilen            = reader.ReadByte();
                    var flag            = reader.ReadByte();
                    var mode            = reader.ReadByte();
                    var offset          = reader.BaseStream.Position;
                    var packetStructure = TMDHelper.CreateTMDPacketStructure(flag, mode, reader, p);
                    if (packetStructure != null)
                    {
                        TMDHelper.AddTrianglesToGroup(groupedTriangles, packetStructure, delegate(uint index)
                        {
                            if (index >= vertices.Length)
                            {
                                if (Program.IgnoreTmdVersion)
                                {
                                    return(new Vector3(index, 0, 0));
                                }
                                Program.Logger.WriteErrorLine("Vertex index error : " + fileTitle);
                                throw new Exception("Vertex index error: " + fileTitle);
                            }
                            return(vertices[index]);
                        }, delegate(uint index)
                        {
                            if (index >= normals.Length)
                            {
                                if (Program.IgnoreTmdVersion)
                                {
                                    return(new Vector3(index, 0, 0));
                                }
                                Program.Logger.WriteErrorLine("Vertex index error: " + fileTitle);
                                throw new Exception("Vertex index error: " + fileTitle);
                            }
                            return(normals[index]);
                        });
                    }
                    var newOffset = offset + ilen * 4;
                    if (Program.IgnoreTmdVersion && newOffset < _offset)
                    {
                        return(null);
                    }
                    reader.BaseStream.Seek(newOffset, SeekOrigin.Begin);
                }

                foreach (var kvp in groupedTriangles)
                {
                    var triangles = kvp.Value;
                    if (triangles.Count > 0)
                    {
                        var model = new ModelEntity
                        {
                            Triangles   = triangles.ToArray(),
                            TexturePage = kvp.Key,
                            TMDID       = o
                        };
                        models.Add(model);
                    }
                }
            }

            if (models.Count > 0)
            {
                var entity = new RootEntity();
                foreach (var model in models)
                {
                    model.ParentEntity = entity;
                }
                entity.ChildEntities = models.ToArray();
                entity.ComputeBounds();
                return(entity);
            }
            return(null);
        }
Ejemplo n.º 5
0
        private static RootEntity ReadModels(BinaryReader reader)
        {
            var count = BRenderHelper.ReadU16BE(reader.BaseStream);

            if (count == 0 || count > 10000)
            {
                return(null);
            }
            var flags  = BRenderHelper.ReadU16BE(reader.BaseStream);
            var models = new List <ModelEntity>();

            for (var i = 0; i < count; i++)
            {
                var modelEntity = new ModelEntity();
                var radius      = (int)BRenderHelper.ReadU32BE(reader.BaseStream);
                for (var j = 0; j < 9; j++)
                {
                    for (var k = 0; k < 4; k++)
                    {
                        BRenderHelper.ReadU16BE(reader.BaseStream);
                    }
                }
                var countVerts = BRenderHelper.ReadU32BE(reader.BaseStream);
                if (countVerts == 0 || countVerts > 1000)
                {
                    return(null);
                }
                var vertices = new Vector3[countVerts];
                var normals  = new Vector3[countVerts];
                for (var j = 0; j < countVerts; j++)
                {
                    var x = (short)BRenderHelper.ReadU16BE(reader.BaseStream) / 16f;
                    var z = (short)BRenderHelper.ReadU16BE(reader.BaseStream) / 16f;
                    var y = -(short)BRenderHelper.ReadU16BE(reader.BaseStream) / 16f;
                    BRenderHelper.ReadU16BE(reader.BaseStream);
                    vertices[j] = new Vector3(x, y, z);
                }
                for (var j = 0; j < countVerts; j++)
                {
                    var x = (short)BRenderHelper.ReadU16BE(reader.BaseStream) / 16f;
                    var z = (short)BRenderHelper.ReadU16BE(reader.BaseStream) / 16f;
                    var y = -(short)BRenderHelper.ReadU16BE(reader.BaseStream) / 16f;
                    BRenderHelper.ReadU16BE(reader.BaseStream);
                    normals[j] = new Vector3(x, y, z);
                }
                var countFaces = BRenderHelper.ReadU32BE(reader.BaseStream);
                var triangles  = new List <Triangle>();
                //var header = Encoding.ASCII.GetString(reader.ReadBytes(64));
                for (var j = 0; j < countFaces; j++)
                {
                    var unk1 = reader.BaseStream.ReadByte();
                    var unk2 = reader.BaseStream.ReadByte();
                    var unk3 = reader.BaseStream.ReadByte();
                    var unk4 = reader.BaseStream.ReadByte();
                    var unk5 = reader.BaseStream.ReadByte();
                    var unk6 = reader.BaseStream.ReadByte();
                    var unk7 = reader.BaseStream.ReadByte();
                    var unk8 = reader.BaseStream.ReadByte();
                    var f0   = BRenderHelper.ReadU16BE(reader.BaseStream);
                    var f1   = BRenderHelper.ReadU16BE(reader.BaseStream);
                    var f2   = BRenderHelper.ReadU16BE(reader.BaseStream);
                    var f3   = BRenderHelper.ReadU16BE(reader.BaseStream);
                    if (f0 >= vertices.Length || f1 >= vertices.Length || f2 >= vertices.Length || f3 >= vertices.Length)
                    {
                        return(null);
                    }
                    var unk9      = BRenderHelper.ReadU16BE(reader.BaseStream);
                    var unk10     = reader.BaseStream.ReadByte();
                    var primFlags = reader.BaseStream.ReadByte();
                    var vertex0   = vertices[f0];
                    var vertex1   = vertices[f1];
                    var vertex2   = vertices[f2];
                    var normal0   = normals[f0];
                    var normal1   = normals[f1];
                    var normal2   = normals[f2];
                    //if (Math.Abs((normal0 + normal1 + normal2).Length) <= 0.0f)
                    //{
                    normal0 = Vector3.Cross(vertex1 - vertex0, vertex2 - vertex0).Normalized();
                    normal1 = normal0;
                    normal2 = normal0;
                    //}
                    triangles.Add(new Triangle
                    {
                        Vertices          = new[] { vertex0, vertex1, vertex2 },
                        Normals           = new[] { normal0, normal1, normal2 },
                        Colors            = new[] { Color.Grey, Color.Grey, Color.Grey },
                        Uv                = new[] { Vector3.Zero, Vector3.Zero, Vector3.Zero },
                        AttachableIndices = new [] { uint.MaxValue, uint.MaxValue, uint.MaxValue }
                    });
                    if ((primFlags & 0x8) != 0)
                    {
                        var vertex3 = vertices[f3];
                        var normal3 = normals[f3];
                        //if (Math.Abs((normal1 + normal3 + normal2).Length) <= 0.0f)
                        {
                            normal3 = Vector3.Cross(vertex3 - vertex1, vertex2 - vertex1).Normalized();
                            normal1 = normal3;
                            normal2 = normal3;
                        }
                        triangles.Add(new Triangle
                        {
                            Vertices          = new[] { vertex1, vertex3, vertex2 },
                            Normals           = new[] { normal1, normal3, normal2 },
                            Colors            = new[] { Color.Grey, Color.Grey, Color.Grey },
                            Uv                = new[] { Vector3.Zero, Vector3.Zero, Vector3.Zero },
                            AttachableIndices = new[] { uint.MaxValue, uint.MaxValue, uint.MaxValue }
                        });
                    }
                }
                modelEntity.Triangles = triangles.ToArray();
                models.Add(modelEntity);
            }
            if (models.Count > 0)
            {
                var entity = new RootEntity();
                foreach (var model in models)
                {
                    model.ParentEntity = entity;
                }
                entity.ChildEntities = models.ToArray();
                entity.ComputeBounds();
                return(entity);
            }
            return(null);
        }
Ejemplo n.º 6
0
        private RootEntity ReadModels(BinaryReader reader, Dictionary <uint, List <Triangle> > groupedTriangles)
        {
            void AddTriangle(Triangle triangle, uint tPage)
            {
                List <Triangle> triangles;

                if (groupedTriangles.ContainsKey(tPage))
                {
                    triangles = groupedTriangles[tPage];
                }
                else
                {
                    triangles = new List <Triangle>();
                    groupedTriangles.Add(tPage, triangles);
                }
                triangles.Add(triangle);
            }

            //var id0 = reader.ReadByte();
            //var id1 = reader.ReadByte();
            //var id2 = reader.ReadByte();
            //var id3 = reader.ReadByte();
            //if ((char)id0 != 'P' || (char)id1 != 'S' || (char)id2 != 'I' || id3 != 1)
            //{
            //    return null;
            //}
            //
            //var version = reader.ReadUInt32();
            //var flags = reader.ReadUInt32();
            //var name = Encoding.ASCII.GetString(reader.ReadBytes(32));
            //var meshNum = reader.ReadUInt32();
            //var vertNum = reader.ReadUInt32();
            //var primNum = reader.ReadUInt32();
            //var primOffset = reader.ReadUInt32();
            //var animStart = reader.ReadUInt16();
            //var animEnd = reader.ReadUInt16();
            //var animNum = reader.ReadUInt32();
            //var animSegListOffset = reader.ReadUInt32();
            //var numTex = reader.ReadUInt32();
            //var texOff = reader.ReadUInt32();
            //var firstMeshOff = reader.ReadUInt32();
            //var radius = reader.ReadUInt32();
            //var pad = reader.ReadBytes(192 - 88);
            //
            //var models = new List<ModelEntity>();
            //var position = reader.BaseStream.Position;
            //{
            //    reader.BaseStream.Seek(_offset + firstMeshOff, SeekOrigin.Begin);
            //    var vertTop = reader.ReadUInt32();
            //    var vertCount = reader.ReadUInt32();
            //    var normTop = reader.ReadUInt32();
            //    var normCount = reader.ReadUInt32();
            //    var scale = reader.ReadUInt32();
            //
            //    var meshName = Encoding.ASCII.GetString(reader.ReadBytes(16));
            //    var childTop = reader.ReadUInt32();
            //    var nextTop = reader.ReadUInt32();
            //
            //    var numScaleKeys = reader.ReadUInt16();
            //    var numMoveKeys = reader.ReadUInt16();
            //    var numRotKeys = reader.ReadUInt16();
            //    var pad1 = reader.ReadUInt16();
            //
            //    var scaleKeysTop = reader.ReadUInt32();
            //    var moveKeysTop = reader.ReadUInt32();
            //    var rotateKeysTop = reader.ReadUInt32();
            //
            //    var sortListSize0 = reader.ReadUInt16();
            //    var sortListSize1 = reader.ReadUInt16();
            //    var sortListSize2 = reader.ReadUInt16();
            //    var sortListSize3 = reader.ReadUInt16();
            //    var sortListSize4 = reader.ReadUInt16();
            //    var sortListSize5 = reader.ReadUInt16();
            //    var sortListSize6 = reader.ReadUInt16();
            //    var sortListSize7 = reader.ReadUInt16();
            //
            //    var sortListSizeTop0 = reader.ReadUInt32();
            //    var sortListSizeTop1 = reader.ReadUInt32();
            //    var sortListSizeTop2 = reader.ReadUInt32();
            //    var sortListSizeTop3 = reader.ReadUInt32();
            //    var sortListSizeTop4 = reader.ReadUInt32();
            //    var sortListSizeTop5 = reader.ReadUInt32();
            //    var sortListSizeTop6 = reader.ReadUInt32();
            //    var sortListSizeTop7 = reader.ReadUInt32();
            //
            //    var lastScaleKey = reader.ReadUInt16();
            //    var lastMoveKey = reader.ReadUInt16();
            //    var lastRotKey = reader.ReadUInt16();
            //    var pad2 = reader.ReadUInt16();
            //}

#if SHORT_MAP_VERTNOS
            var BFF_FMA_MESH_ID  = 5;
            var BFF_FMA_MESH4_ID = 6;
#else
            var BFF_FMA_MESH_ID  = 1;
            var BFF_FMA_MESH4_ID = 4;
#endif

            var id0 = reader.ReadByte();
            var id1 = reader.ReadByte();
            var id2 = reader.ReadByte();
            var id3 = reader.ReadByte(); //4 or 1
            if ((char)id0 != 'F' || (char)id1 != 'M' || (char)id2 != 'M' || id3 != BFF_FMA_MESH_ID && id3 != BFF_FMA_MESH4_ID)
            {
                return(null);
            }

            var models = new List <ModelEntity>();

            //            // Version 1 mesh headers include flat-poly information. Like what skies used to.
            //#define BFF_FMA_MESH_ID (('F'<<0) | ('M'<<8) | ('M'<<16) | (1<<24))
            //            //#define BFF_FMA_SKYMESH_ID (('F'<<0) | ('M'<<8) | ('S'<<16) | (0<<24))
            //#define BFF_FMA_MESH4_ID (('F'<<0) | ('M'<<8) | ('M'<<16) | (4<<24))

            var length  = ReadInt(reader);
            var nameCrc = ReadLong(reader);

            var minX = ReadIntP(reader);
            var minY = ReadIntP(reader);
            var minZ = ReadIntP(reader);
            var maxX = ReadIntP(reader);
            var maxY = ReadIntP(reader);
            var maxZ = ReadIntP(reader);
            //
            //var offsetX = ReadIntP(reader);
            //var offsetY = ReadIntP(reader);
            //var offsetZ = ReadIntP(reader);
            //var rotX = ReadShort(reader);
            //var rotY = ReadShort(reader);
            //var rotZ = ReadShort(reader);
            //var rotW = ReadShort(reader);

            //var dummy1 = ReadShort(reader);
            //var dummy2 = ReadShort(reader);
            var polyListTop = ReadLong(reader);
            var dummy1      = ReadShort(reader);
            var dummy2      = ReadShort(reader);

            var radius = ReadInt(reader);

            var numVerts = ReadInt(reader);
            var vertsTop = ReadLong(reader);
            var position = reader.BaseStream.Position;
            //var offset = reader.BaseStream.Position - _offset;
            reader.BaseStream.Seek(_offset + vertsTop, SeekOrigin.Begin);
            // reader.BaseStream.Seek(288852, SeekOrigin.Begin);
            var vertices = new Vector3[numVerts];
            var uvs      = new Vector2[numVerts];
            for (var i = 0; i < numVerts; i++)
            {
                var x  = ReadShort(reader);
                var y  = ReadShort(reader);
                var z  = ReadShort(reader);
                var tu = reader.ReadByte();
                var tv = reader.ReadByte();
                vertices[i] = new Vector3(x, y, z);
                uvs[i]      = new Vector2(tu, tv);
            }

            using (var writer = File.CreateText("C:\\USERS\\RICKO\\DESKTOP\\TEST" + nameCrc + ".OBJ"))
            {
                foreach (var vertex in vertices)
                {
                    writer.WriteLine("v " + vertex.X + " " + vertex.Y + " " + vertex.Z);
                }
            }

            reader.BaseStream.Seek(position, SeekOrigin.Begin);

            var numGT3s  = ReadInt(reader);
            var primsTop = ReadInt(reader);
            position = reader.BaseStream.Position;
            reader.BaseStream.Seek(_offset + primsTop, SeekOrigin.Begin);
            if (id3 == BFF_FMA_MESH_ID)
            {
                for (var i = 0; i < numGT3s; i++) //FMA_GT3
                {
                    var r0   = reader.ReadByte();
                    var g0   = reader.ReadByte();
                    var b0   = reader.ReadByte();
                    var code = reader.ReadByte();
                    var u0   = reader.ReadByte();
                    var v0   = reader.ReadByte();
                    var clut = ReadPadData(reader);

                    var r1    = reader.ReadByte();
                    var g1    = reader.ReadByte();
                    var b1    = reader.ReadByte();
                    var pad1  = reader.ReadByte();
                    var u1    = reader.ReadByte();
                    var v1    = reader.ReadByte();
                    var tPage = ReadPadData(reader);

                    var r2   = reader.ReadByte();
                    var g2   = reader.ReadByte();
                    var b2   = reader.ReadByte();
                    var pad2 = reader.ReadByte();
                    var u2   = reader.ReadByte();
                    var v2   = reader.ReadByte();
                    var pad3 = ReadPadData(reader);

                    var vert0 = ReadIndex(reader);
                    var vert1 = ReadIndex(reader);
                    var vert2 = ReadIndex(reader);

                    var triangle = TriangleFromPrimitive(vertices,
                                                         vert0, vert1, vert2,
                                                         r0, g0, b0,
                                                         r1, g1, b1,
                                                         r2, g2, b2,
                                                         u0, v0,
                                                         u1, v1,
                                                         u2, v2);

                    AddTriangle(triangle, tPage);
                }
            }
            else
            {
                var vert0 = ReadIndex(reader);
                var vert1 = ReadIndex(reader);
                var vert2 = ReadIndex(reader);
                var vert3 = ReadIndex(reader);

                var triangle1 = ReadPolyGT3(reader, vertices, vert0, vert1, vert2, out var tPage1);
                //var triangle2 = ReadPolyGT3(reader, vertices, vert1, vert3, vert2, out var tPage2);
                AddTriangle(triangle1, tPage1);
                //AddTriangle(triangle2, 0);
            }

            reader.BaseStream.Seek(position, SeekOrigin.Begin);

            var numGT4s = ReadInt(reader);
            primsTop = ReadInt(reader);
            position = reader.BaseStream.Position;
            reader.BaseStream.Seek(_offset + primsTop, SeekOrigin.Begin);
            if (id3 == BFF_FMA_MESH_ID)
            {
                for (var i = 0; i < numGT4s; i++) //FMA_GT4
                {
                    var r0   = reader.ReadByte();
                    var g0   = reader.ReadByte();
                    var b0   = reader.ReadByte();
                    var code = reader.ReadByte();
                    var u0   = reader.ReadByte();
                    var v0   = reader.ReadByte();
                    var clut = ReadPadData(reader);

                    var r1    = reader.ReadByte();
                    var g1    = reader.ReadByte();
                    var b1    = reader.ReadByte();
                    var pad1  = reader.ReadByte();
                    var u1    = reader.ReadByte();
                    var v1    = reader.ReadByte();
                    var tPage = ReadPadData(reader);

                    var r2   = reader.ReadByte();
                    var g2   = reader.ReadByte();
                    var b2   = reader.ReadByte();
                    var pad2 = reader.ReadByte();
                    var u2   = reader.ReadByte();
                    var v2   = reader.ReadByte();
                    var pad3 = ReadPadData(reader);

                    var r3   = reader.ReadByte();
                    var g3   = reader.ReadByte();
                    var b3   = reader.ReadByte();
                    var pad4 = reader.ReadByte();
                    var u3   = reader.ReadByte();
                    var v3   = reader.ReadByte();
                    var pad5 = ReadPadData(reader);

                    var vert0 = ReadIndex(reader);
                    var vert1 = ReadIndex(reader);
                    var vert2 = ReadIndex(reader);
                    var vert3 = ReadIndex(reader);

                    var triangle1 = TriangleFromPrimitive(vertices,
                                                          vert0, vert1, vert2,
                                                          r0, g0, b0,
                                                          r1, g1, b1,
                                                          r2, g2, b2,
                                                          u0, v0,
                                                          u1, v1,
                                                          u2, v2);

                    var triangle2 = TriangleFromPrimitive(vertices,
                                                          vert1, vert3, vert2,
                                                          r1, g1, b1,
                                                          r3, g3, b3,
                                                          r2, g2, b2,
                                                          u1, v1,
                                                          u3, v3,
                                                          u2, v2);

                    AddTriangle(triangle1, tPage);
                    AddTriangle(triangle2, tPage);
                }
            }
            else
            {
                var vert0 = ReadIndex(reader);
                var vert1 = ReadIndex(reader);
                var vert2 = ReadIndex(reader);
                var vert3 = ReadIndex(reader);

                //two POLY_GT3
                var triangle1 = ReadPolyGT3(reader, vertices, vert0, vert1, vert2, out var tPage1);
                var triangle2 = ReadPolyGT3(reader, vertices, vert1, vert3, vert2, out var tPage2);
                AddTriangle(triangle1, tPage1);
                AddTriangle(triangle2, tPage2);
            }

            reader.BaseStream.Seek(position, SeekOrigin.Begin);

            var numTMaps = ReadInt(reader);
            var tMapsTop = ReadLong(reader);

            var numG3s = ReadInt(reader);
            primsTop = ReadInt(reader);
            position = reader.BaseStream.Position;
            reader.BaseStream.Seek(_offset + primsTop, SeekOrigin.Begin);
            for (var i = 0; i < numG3s; i++) //FMA_G3
            {
                var r0   = reader.ReadByte();
                var g0   = reader.ReadByte();
                var b0   = reader.ReadByte();
                var code = reader.ReadByte();

                var r1   = reader.ReadByte();
                var g1   = reader.ReadByte();
                var b1   = reader.ReadByte();
                var pad1 = reader.ReadByte();

                var r2   = reader.ReadByte();
                var g2   = reader.ReadByte();
                var b2   = reader.ReadByte();
                var pad2 = reader.ReadByte();

                var vert0 = ReadIndex(reader);
                var vert1 = ReadIndex(reader);
                var vert2 = ReadIndex(reader);

                var triangle = TriangleFromPrimitive(vertices,
                                                     vert0, vert1, vert2,
                                                     r0, g0, b0,
                                                     r1, g1, b1,
                                                     r2, g2, b2,
                                                     0, 0,
                                                     0, 0,
                                                     0, 0);

                AddTriangle(triangle, 0);
            }
            reader.BaseStream.Seek(position, SeekOrigin.Begin);

            var numG4s = ReadInt(reader);
            primsTop = ReadInt(reader);
            position = reader.BaseStream.Position;
            reader.BaseStream.Seek(_offset + primsTop, SeekOrigin.Begin);
            for (var i = 0; i < numG4s; i++) //FMA_G4
            {
                var r0   = reader.ReadByte();
                var g0   = reader.ReadByte();
                var b0   = reader.ReadByte();
                var code = reader.ReadByte();

                var r1   = reader.ReadByte();
                var g1   = reader.ReadByte();
                var b1   = reader.ReadByte();
                var pad1 = reader.ReadByte();

                var r2   = reader.ReadByte();
                var g2   = reader.ReadByte();
                var b2   = reader.ReadByte();
                var pad2 = reader.ReadByte();

                var r3   = reader.ReadByte();
                var g3   = reader.ReadByte();
                var b3   = reader.ReadByte();
                var pad3 = reader.ReadByte();

                var vert0 = ReadIndex(reader);
                var vert1 = ReadIndex(reader);
                var vert2 = ReadIndex(reader);
                var vert3 = ReadIndex(reader);

                var triangle1 = TriangleFromPrimitive(vertices,
                                                      vert0, vert1, vert2,
                                                      r0, g0, b0,
                                                      r1, g1, b1,
                                                      r2, g2, b2,
                                                      0, 0,
                                                      0, 0,
                                                      0, 0);

                var triangle2 = TriangleFromPrimitive(vertices,
                                                      vert1, vert3, vert2,
                                                      r1, g1, b1,
                                                      r3, g3, b3,
                                                      r2, g2, b2,
                                                      0, 0,
                                                      0, 0,
                                                      0, 0);


                AddTriangle(triangle1, 0);
                AddTriangle(triangle2, 0);
            }
            reader.BaseStream.Seek(position, SeekOrigin.Begin);

            foreach (var kvp in groupedTriangles)
            {
                var triangles = kvp.Value;
                if (triangles.Count > 0)
                {
                    var model = new ModelEntity
                    {
                        Triangles   = triangles.ToArray(),
                        TexturePage = kvp.Key,
                        TMDID       = 0
                    };
                    models.Add(model);
                }
            }

            if (models.Count > 0)
            {
                var entity = new RootEntity();
                foreach (var model in models)
                {
                    model.ParentEntity = entity;
                }
                entity.ChildEntities = models.ToArray();
                entity.ComputeBounds();
                return(entity);
            }

            return(null);
        }
Ejemplo n.º 7
0
        private static RootEntity ReadModels(BinaryReader reader)
        {
            void AddTriangle(Dictionary <Tuple <uint, uint>, List <Triangle> > groupedTriangles, Triangle triangle, uint modelIndex, uint tPage)
            {
                var             tuple = new Tuple <uint, uint>(modelIndex, tPage);
                List <Triangle> triangles;

                if (groupedTriangles.ContainsKey(tuple))
                {
                    triangles = groupedTriangles[tuple];
                }
                else
                {
                    triangles = new List <Triangle>();
                    groupedTriangles.Add(tuple, triangles);
                }
                triangles.Add(triangle);
            }

            var version = reader.ReadByte();
            var magic2  = reader.ReadByte();
            var magic3  = reader.ReadByte();
            var magic4  = reader.ReadByte();

            if (version != 0x04 && version != 0x03 && version != 0x06)
            {
                return(null);
            }
            if (magic2 != 0x00 || magic3 != 0x02 || magic4 != 0x00)
            {
                return(null);
            }
            var metaPtr     = reader.ReadUInt32(); //todo: read meta
            var objectCount = reader.ReadUInt32();

            if (objectCount == 0 || objectCount > Program.MaxPSXObjectCount)
            {
                return(null);
            }
            var childEntities = new ModelEntity();
            var objectModels  = new PSXModel[objectCount];

            for (var i = 0; i < objectCount; i++)
            {
                var flags      = reader.ReadUInt32();
                var x          = (reader.ReadInt32() / 4096f) / 2.25f; // 4096f;
                var y          = (reader.ReadInt32() / 4096f) / 2.25f; // 4096f;
                var z          = (reader.ReadInt32() / 4096f) / 2.25f; // 4096f;
                var unk1       = reader.ReadUInt32();
                var unk2       = reader.ReadUInt16();
                var modelIndex = reader.ReadUInt16();
                var tx         = reader.ReadUInt16();
                var ty         = reader.ReadUInt16();
                var unk3       = reader.ReadUInt32();
                var palTop     = reader.ReadUInt32();
                objectModels[i] = new PSXModel(x, y, z, modelIndex);
            }
            var modelCount = reader.ReadUInt32();

            if (modelCount == 0 || modelCount > Program.MaxPSXObjectCount)
            {
                return(null);
            }
            var triangleGroups  = new Dictionary <Tuple <uint, uint>, List <Triangle> >();
            var modelEntities   = new List <ModelEntity>();
            var attachmentIndex = 0;

            for (uint i = 0; i < modelCount; i++)
            {
                var modelTop      = reader.ReadUInt32();
                var modelPosition = reader.BaseStream.Position;
                reader.BaseStream.Seek(modelTop, SeekOrigin.Begin);
                var flags       = version == 0x04 ? reader.ReadUInt16() : reader.ReadUInt32();
                var vertexCount = version == 0x04 ? reader.ReadUInt16() : reader.ReadUInt32();
                var planeCount  = version == 0x04 ? reader.ReadUInt16() : reader.ReadUInt32();
                var faceCount   = version == 0x04 ? reader.ReadUInt16() : reader.ReadUInt32();
                var radius      = reader.ReadUInt32();
                var xMax        = reader.ReadUInt16();
                var xMin        = reader.ReadUInt16();
                var yMax        = reader.ReadUInt16();
                var yMin        = reader.ReadUInt16();
                var zMax        = reader.ReadUInt16();
                var zMin        = reader.ReadUInt16();
                if (version == 0x04)
                {
                    var unk2 = reader.ReadUInt32();
                }

                var attachedIndices   = new Dictionary <uint, uint>();
                var attachableIndices = new Dictionary <uint, uint>();
                var vertices          = new Vector3[vertexCount];
                for (uint j = 0; j < vertexCount; j++)
                {
                    var x      = reader.ReadInt16(); //reader.ReadInt16() / 1f) / 2.25f;
                    var y      = reader.ReadInt16(); //reader.ReadInt16() / 1f) / 2.25f;
                    var z      = reader.ReadInt16(); //(reader.ReadInt16() / 1f) / 2.25f;
                    var pad    = reader.ReadInt16();
                    var vertex = new Vector3(
                        x / 1f / 2.25f,
                        y / 1f / 2.25f,
                        z / 1f / 2.25f
                        );
                    if (pad == 1)
                    {
                        attachableIndices.Add(j, (uint)attachmentIndex++);
                    }
                    else if (pad == 2)
                    {
                        attachedIndices.Add(j, (uint)y);
                    }

                    vertices[j] = vertex;
                }

                var normals = new Vector3[planeCount];
                for (uint j = 0; j < planeCount; j++)
                {
                    var x = reader.ReadInt16() / 4096f;
                    var y = reader.ReadInt16() / 4096f;
                    var z = reader.ReadInt16() / 4096f;
                    reader.ReadInt16();
                    normals[j] = new Vector3(
                        x, y, z
                        );
                }

                //uint faceFlags;
                //uint faceLength;
                //if (version == 0x03)
                //{
                //    faceFlags = reader.ReadUInt16();
                //    faceLength = reader.ReadUInt16();
                //}
                //else
                //{
                //    faceFlags = 0;
                //    faceLength = 0;
                //}
                for (uint j = 0; j < faceCount; j++)
                {
                    if (version == 0x04)
                    {
                        var   faceBegin  = reader.BaseStream.Position;
                        var   faceFlags  = reader.ReadUInt16();
                        var   faceLength = reader.ReadUInt16();
                        var   triangle   = (faceFlags & 0x0010) != 0;
                        var   gouraud    = (faceFlags & 0x0800) != 0;
                        var   textured   = (faceFlags & 0x0003) != 0;
                        var   invisible  = (faceFlags & 0x0080) != 0;
                        var   i0         = reader.ReadByte();
                        var   i1         = reader.ReadByte();
                        var   i2         = reader.ReadByte();
                        var   i3         = reader.ReadByte();
                        var   vertex0    = vertices[i0];
                        var   vertex1    = vertices[i1];
                        var   vertex2    = vertices[i2];
                        var   vertex3    = vertices[i3];
                        Color color0;
                        Color color1;
                        Color color2;
                        Color color3;
                        var   r0               = reader.ReadByte() / 255f;
                        var   g0               = reader.ReadByte() / 255f;
                        var   b0               = reader.ReadByte() / 255f;
                        var   command          = reader.ReadByte();
                        var   attachedIndex0   = attachedIndices.TryGetValue(i0, out var index0) ? index0 : uint.MaxValue;
                        var   attachedIndex1   = attachedIndices.TryGetValue(i1, out var index1) ? index1 : uint.MaxValue;
                        var   attachedIndex2   = attachedIndices.TryGetValue(i2, out var index2) ? index2 : uint.MaxValue;
                        var   attachedIndex3   = attachedIndices.TryGetValue(i3, out var index3) ? index3 : uint.MaxValue;
                        var   attachableIndex0 = attachableIndices.TryGetValue(i0, out var attIndex0) ? attIndex0 : uint.MaxValue;
                        var   attachableIndex1 = attachableIndices.TryGetValue(i1, out var attIndex1) ? attIndex1 : uint.MaxValue;
                        var   attachableIndex2 = attachableIndices.TryGetValue(i2, out var attIndex2) ? attIndex2 : uint.MaxValue;
                        var   attachableIndex3 = attachableIndices.TryGetValue(i3, out var attIndex3) ? attIndex3 : uint.MaxValue;
                        if (gouraud)
                        {
                            color0 = color1 = color2 = color3 = Color.Grey; //todo
                        }
                        else
                        {
                            color0 = color1 = color2 = color3 = new Color(r0, g0, b0);
                        }
                        //todo
                        var  planeIndex = reader.ReadUInt16();
                        var  surfFlags  = reader.ReadInt16();
                        var  normal0    = normals[planeIndex];
                        var  normal1    = normals[planeIndex];
                        var  normal2    = normals[planeIndex];
                        var  normal3    = normals[planeIndex];
                        var  uv0        = Vector3.Zero;
                        var  uv1        = Vector3.Zero;
                        var  uv2        = Vector3.Zero;
                        var  uv3        = Vector3.Zero;
                        uint tPage      = 0;
                        if (textured)
                        {
                            tPage = reader.ReadUInt32(); //todo
                            var u0 = reader.ReadByte() / 255f;
                            var v0 = reader.ReadByte() / 255f;
                            var u1 = reader.ReadByte() / 255f;
                            var v1 = reader.ReadByte() / 255f;
                            var u2 = reader.ReadByte() / 255f;
                            var v2 = reader.ReadByte() / 255f;
                            var u3 = reader.ReadByte() / 255f;
                            var v3 = reader.ReadByte() / 255f;
                            uv0 = new Vector3(u0, v0, 0f);
                            uv1 = new Vector3(u1, v1, 0f);
                            uv2 = new Vector3(u2, v2, 0f);
                            uv3 = new Vector3(u3, v3, 0f);
                        }
                        if (!invisible)
                        {
                            AddTriangle(triangleGroups, new Triangle
                            {
                                Vertices = new[] { vertex2, vertex1, vertex0 },
                                Normals  = new[] { normal2, normal1, normal0 },
                                Uv       = new[] { uv2, uv1, uv0 },
                                Colors   = new[] { color2, color1, color0 },
                                OriginalVertexIndices = new uint[] { i2, i1, i0 },
                                AttachedIndices       = new[] { attachedIndex2, attachedIndex1, attachedIndex0 },
                                AttachableIndices     = new[] { attachableIndex2, attachableIndex1, attachableIndex0 }
                            }, i, tPage);
                            if (!triangle)
                            {
                                AddTriangle(triangleGroups, new Triangle
                                {
                                    Vertices = new[] { vertex1, vertex2, vertex3 },
                                    Normals  = new[] { normal1, normal2, normal3 },
                                    Uv       = new[] { uv1, uv2, uv3 },
                                    Colors   = new[] { color1, color2, color3 },
                                    OriginalVertexIndices = new uint[] { i1, i2, i3 },
                                    AttachedIndices       = new[] { attachedIndex1, attachedIndex2, attachedIndex3 },
                                    AttachableIndices     = new[] { attachableIndex1, attachableIndex2, attachableIndex3 }
                                }, i, tPage);
                            }
                        }
                        reader.BaseStream.Seek(faceBegin + faceLength, SeekOrigin.Begin);
                    }
                    else
                    {
                        var   faceBegin  = reader.BaseStream.Position;
                        var   faceFlags  = reader.ReadUInt16();
                        var   faceLength = reader.ReadUInt16();
                        var   triangle   = (faceFlags & 0x0010) != 0;
                        var   gouraud    = (faceFlags & 0x0800) != 0;
                        var   textured   = (faceFlags & 0x0003) != 0;
                        var   invisible  = (faceFlags & 0x0080) != 0;
                        var   i0         = reader.ReadUInt16();
                        var   i1         = reader.ReadUInt16();
                        var   i2         = reader.ReadUInt16();
                        var   i3         = reader.ReadUInt16();
                        var   vertex0    = vertices[i0];
                        var   vertex1    = vertices[i1];
                        var   vertex2    = vertices[i2];
                        var   vertex3    = vertices[i3];
                        Color color0;
                        Color color1;
                        Color color2;
                        Color color3;
                        var   r0               = reader.ReadByte() / 255f;
                        var   g0               = reader.ReadByte() / 255f;
                        var   b0               = reader.ReadByte() / 255f;
                        var   command          = reader.ReadByte();
                        var   attachedIndex0   = attachedIndices.TryGetValue(i0, out var index0) ? index0 : uint.MaxValue;
                        var   attachedIndex1   = attachedIndices.TryGetValue(i1, out var index1) ? index1 : uint.MaxValue;
                        var   attachedIndex2   = attachedIndices.TryGetValue(i2, out var index2) ? index2 : uint.MaxValue;
                        var   attachedIndex3   = attachedIndices.TryGetValue(i3, out var index3) ? index3 : uint.MaxValue;
                        var   attachableIndex0 = attachableIndices.TryGetValue(i0, out var attIndex0) ? attIndex0 : uint.MaxValue;
                        var   attachableIndex1 = attachableIndices.TryGetValue(i1, out var attIndex1) ? attIndex1 : uint.MaxValue;
                        var   attachableIndex2 = attachableIndices.TryGetValue(i2, out var attIndex2) ? attIndex2 : uint.MaxValue;
                        var   attachableIndex3 = attachableIndices.TryGetValue(i3, out var attIndex3) ? attIndex3 : uint.MaxValue;
                        if (gouraud)
                        {
                            color0 = color1 = color2 = color3 = Color.Grey; //todo
                        }
                        else
                        {
                            color0 = color1 = color2 = color3 = new Color(r0, g0, b0);
                        }
                        //todo
                        var  planeIndex = reader.ReadUInt16();
                        var  surfFlags  = reader.ReadInt16();
                        var  normal0    = normals[planeIndex];
                        var  normal1    = normals[planeIndex];
                        var  normal2    = normals[planeIndex];
                        var  normal3    = normals[planeIndex];
                        var  uv0        = Vector3.Zero;
                        var  uv1        = Vector3.Zero;
                        var  uv2        = Vector3.Zero;
                        var  uv3        = Vector3.Zero;
                        uint tPage      = 0;
                        if (textured)
                        {
                            tPage = reader.ReadUInt32(); //todo
                            var u0 = reader.ReadByte() / 255f;
                            var v0 = reader.ReadByte() / 255f;
                            var u1 = reader.ReadByte() / 255f;
                            var v1 = reader.ReadByte() / 255f;
                            var u2 = reader.ReadByte() / 255f;
                            var v2 = reader.ReadByte() / 255f;
                            var u3 = reader.ReadByte() / 255f;
                            var v3 = reader.ReadByte() / 255f;
                            uv0 = new Vector3(u0, v0, 0f);
                            uv1 = new Vector3(u1, v1, 0f);
                            uv2 = new Vector3(u2, v2, 0f);
                            uv3 = new Vector3(u3, v3, 0f);
                        }
                        if (!invisible)
                        {
                            AddTriangle(triangleGroups, new Triangle
                            {
                                Vertices = new[] { vertex2, vertex1, vertex0 },
                                Normals  = new[] { normal2, normal1, normal0 },
                                Uv       = new[] { uv2, uv1, uv0 },
                                Colors   = new[] { color2, color1, color0 },
                                OriginalVertexIndices = new uint[] { i2, i1, i0 },
                                AttachedIndices       = new[] { attachedIndex2, attachedIndex1, attachedIndex0 },
                                AttachableIndices     = new[] { attachableIndex2, attachableIndex1, attachableIndex0 }
                            }, i, tPage);
                            if (!triangle)
                            {
                                AddTriangle(triangleGroups, new Triangle
                                {
                                    Vertices = new[] { vertex1, vertex2, vertex3 },
                                    Normals  = new[] { normal1, normal2, normal3 },
                                    Uv       = new[] { uv1, uv2, uv3 },
                                    Colors   = new[] { color1, color2, color3 },
                                    OriginalVertexIndices = new uint[] { i1, i2, i3 },
                                    AttachedIndices       = new[] { attachedIndex1, attachedIndex2, attachedIndex3 },
                                    AttachableIndices     = new[] { attachableIndex1, attachableIndex2, attachableIndex3 }
                                }, i, tPage);
                            }
                        }
                        reader.BaseStream.Seek(faceBegin + faceLength, SeekOrigin.Begin);
                    }
                }
                reader.BaseStream.Seek(modelPosition, SeekOrigin.Begin);
            }

            //var position = reader.BaseStream.Position;
            //reader.BaseStream.Seek(metaPtr, SeekOrigin.Begin);
            //for (; ; )
            //{
            //    var chunkId = reader.ReadBytes(4);
            //    if (chunkId[0] == 0xFF && chunkId[1] == 0xFF && chunkId[2] == 0xFF && chunkId[3] == 0xFF)
            //    {
            //        break;
            //    }
            //    var chunkString = Encoding.ASCII.GetString(chunkId);
            //    var chunkLength = reader.ReadUInt32();
            //    var chunkData = reader.ReadBytes((int)chunkLength);
            //};
            //reader.BaseStream.Seek(position, SeekOrigin.Begin);

            foreach (var psxModel in objectModels)
            {
                foreach (var kvp in triangleGroups)
                {
                    if (kvp.Key.Item1 == psxModel.ModelIndex)
                    {
                        var triangles = kvp.Value;
                        var model     = new ModelEntity
                        {
                            Triangles   = triangles.ToArray(),
                            TexturePage = kvp.Key.Item2,
                            TMDID       = 1, //todo
                            LocalMatrix = Matrix4.CreateTranslation(psxModel.X, psxModel.Y, psxModel.Z)
                        };
                        modelEntities.Add(model);
                    }
                }
            }
            RootEntity rootEntity;

            if (modelEntities.Count > 0)
            {
                rootEntity = new RootEntity();
                foreach (var modelEntity in modelEntities)
                {
                    modelEntity.ParentEntity = rootEntity;
                }
                rootEntity.ChildEntities = modelEntities.ToArray();
                rootEntity.ComputeBounds();
            }
            else
            {
                rootEntity = null;
            }
            return(rootEntity);
        }
Ejemplo n.º 8
0
        private bool ProcessAnimationObject(AnimationObject animationObject, float frameIndex, RootEntity selectedRootEntity, Matrix4 worldMatrix)
        {
            switch (_animation.AnimationType)
            {
            case AnimationType.VertexDiff:
            case AnimationType.NormalDiff:
            {
                if (selectedRootEntity != null && animationObject.Parent != null)
                {
                    var objectId = animationObject.TMDID.GetValueOrDefault();
                    foreach (ModelEntity childModel in selectedRootEntity.ChildEntities)
                    {
                        if (childModel.TMDID == objectId)
                        {
                            var intFrameIndex = (uint)frameIndex;
                            if (intFrameIndex > animationObject.AnimationFrames.Count - 1)
                            {
                                return(false);
                            }
                            var animationFrame = animationObject.AnimationFrames[intFrameIndex];
                            if (intFrameIndex > 0)
                            {
                                var lastFrame = animationObject.AnimationFrames[intFrameIndex - 1];
                                for (uint j = 0; j < animationFrame.Vertices.Length; j++)
                                {
                                    if (j < lastFrame.Vertices.Length)
                                    {
                                        animationFrame.TempVertices[j] = lastFrame.Vertices[j];
                                    }
                                    else
                                    {
                                        animationFrame.TempVertices[j] = Vector3.Zero;
                                    }
                                }
                            }
                            else
                            {
                                for (uint j = 0; j < animationFrame.Vertices.Length; j++)
                                {
                                    animationFrame.TempVertices[j] = Vector3.Zero;
                                }
                            }
                            var interpolator    = frameIndex % 1;
                            var initialVertices = _animation.AnimationType == AnimationType.VertexDiff ? animationFrame.TempVertices : null;
                            var finalVertices   = _animation.AnimationType == AnimationType.VertexDiff ? animationFrame.Vertices : null;
                            var initialNormals  = _animation.AnimationType == AnimationType.NormalDiff ? animationFrame.TempVertices : null;
                            var finalNormals    = _animation.AnimationType == AnimationType.NormalDiff ? animationFrame.Vertices : null;
                            childModel.Interpolator    = interpolator;
                            childModel.InitialVertices = initialVertices;
                            childModel.FinalVertices   = finalVertices;
                            childModel.InitialNormals  = initialNormals;
                            childModel.FinalNormals    = finalNormals;
                            childModel.TempMatrix      = Matrix4.Identity;
                            //_scene.MeshBatch.BindModelBatch(childModel, childModel.WorldMatrix, _scene.TextureBinder, initialVertices, initialNormals, finalVertices, finalNormals, interpolator);
                        }
                    }
                }
                break;
            }

            case AnimationType.Common:
            {
                if (selectedRootEntity != null)
                {
                    var animationFrames = animationObject.AnimationFrames;
                    var totalFrames     = animationFrames.Count;
                    var localMatrix     = Matrix4.Identity;
                    for (uint f = 0; f <= frameIndex && f < totalFrames; f++)
                    {
                        if (!animationFrames.ContainsKey(f))
                        {
                            continue;
                        }

                        var frameMatrix = Matrix4.Identity;
                        var sumFrame    = animationFrames[f];
                        if (sumFrame.Rotation != null)
                        {
                            var r = Matrix4.CreateFromQuaternion(sumFrame.Rotation.Value);
                            frameMatrix = frameMatrix * r;
                        }
                        else if (sumFrame.EulerRotation != null)
                        {
                            var r = GeomUtils.CreateR(sumFrame.EulerRotation.Value);
                            frameMatrix = frameMatrix * r;
                        }

                        if (sumFrame.Scale != null)
                        {
                            var scale = (Vector3)sumFrame.Scale;
                            var s     = GeomUtils.CreateS(scale.X);
                            frameMatrix = frameMatrix * s;
                        }

                        if (sumFrame.Translation != null)
                        {
                            var translation = (Vector3)sumFrame.Translation;
                            var t           = GeomUtils.CreateT(translation);
                            frameMatrix = frameMatrix * t;
                        }

                        var absoluteMatrixValue = sumFrame.AbsoluteMatrix;
                        if (!absoluteMatrixValue)
                        {
                            frameMatrix *= localMatrix;
                        }

                        localMatrix = frameMatrix;
                    }

                    //if (parentMatrix != null)
                    //{
                    worldMatrix = localMatrix * worldMatrix;
                    //_scene.SkeletonBatch.AddLine(Vector3.TransformPosition(Vector3.One, parentMatrix.Value), Vector3.TransformPosition(Vector3.One, worldMatrix), animationObject == selectedAnimationObject ? Color.Blue : Color.Red);
                    //}
                    //else
                    //{
                    //    worldMatrix = localMatrix;
                    //}
                    //if (selectedRootEntity != null)
                    //{
                    var objectId = animationObject.TMDID.GetValueOrDefault();
                    if (objectId > 0)
                    {
                        var models = selectedRootEntity.GetModelsWithTMDID(objectId - 1);
                        foreach (var childModel in models)
                        {
                            childModel.Interpolator    = 0;
                            childModel.InitialVertices = null;
                            childModel.FinalVertices   = null;
                            childModel.InitialNormals  = null;
                            childModel.FinalNormals    = null;
                            childModel.TempMatrix      = worldMatrix;
                            //_scene.MeshBatch.BindModelBatch(childModel, worldMatrix, _scene.TextureBinder);
                        }
                    }

                    //}
                }

                break;
            }
            }
            foreach (var childAnimationObject in animationObject.Children)
            {
                if (!ProcessAnimationObject(childAnimationObject, frameIndex, selectedRootEntity, worldMatrix))
                {
                    return(false);
                }
            }
            return(true);
        }