Example #1
0
        private void ProcessNonSharedGeometryData(Dictionary <uint, List <Triangle> > groupedTriangles, BinaryReader reader, uint driver, uint primitiveType, uint primitiveHeaderPointer, uint nextPrimitivePointer, uint polygonIndex, uint dataCount)
        {
            var primitivePosition = reader.BaseStream.Position;

            ProcessGeometryPrimitiveHeader(reader, primitiveHeaderPointer, polygonIndex, out var vertTop, out var normTop, out var coordTop, out var dataTop);
            reader.BaseStream.Seek(_offset + dataTop + polygonIndex, SeekOrigin.Begin);
            for (var j = 0; j < dataCount; j++)
            {
                var packetStructure = TMDHelper.CreateHMDPacketStructure(driver, primitiveType, reader);
                //var offset = reader.BaseStream.Position;
                if (packetStructure != null)
                {
                    TMDHelper.AddTrianglesToGroup(groupedTriangles, packetStructure,
                                                  index =>
                    {
                        var position = reader.BaseStream.Position;
                        reader.BaseStream.Seek(_offset + vertTop + index * 8, SeekOrigin.Begin);
                        var x      = reader.ReadInt16();
                        var y      = reader.ReadInt16();
                        var z      = reader.ReadInt16();
                        var pad    = reader.ReadInt16();
                        var vertex = new Vector3(x, y, z);
                        reader.BaseStream.Seek(position, SeekOrigin.Begin);
                        return(vertex);
                    },
                                                  index =>
                    {
                        var position = reader.BaseStream.Position;
                        reader.BaseStream.Seek(_offset + normTop + index * 8, SeekOrigin.Begin);
                        var nx     = TMDHelper.ConvertNormal(reader.ReadInt16());
                        var ny     = TMDHelper.ConvertNormal(reader.ReadInt16());
                        var nz     = TMDHelper.ConvertNormal(reader.ReadInt16());
                        var pad    = FInt.Create(reader.ReadInt16());
                        var normal = new Vector3
                        {
                            X = nx,
                            Y = ny,
                            Z = nz
                        };
                        reader.BaseStream.Seek(position, SeekOrigin.Begin);
                        return(normal);
                    }
                                                  );
                }
            }
            reader.BaseStream.Seek(primitivePosition, SeekOrigin.Begin);
        }
Example #2
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);
        }