private static void OutputVertices(bool scaleMesh, StringBuilder sb, RrfMesh mesh, int3 parentOffset)
        {
            sb.AppendLine($"# {mesh.VertexCount} Vertexes");
            sb.AppendLine($"# {mesh.VertexAddressRange.Start}");
            foreach (var v in mesh.Vertices)
            {
                var offsetV = new float3(mesh.Origin + parentOffset);
                var floatV  = new float3(v.Coord);

                // Resize mesh
                if (scaleMesh)
                {
                    offsetV /= 1000;
                    offsetV /= 1000;
                    floatV  /= 1000;
                    floatV  /= 1000;
                }

                floatV += offsetV;

                if (v.AttributeId != 0)
                {
                    var attrName = Enum.GetName(typeof(RrfAttribute), v.AttributeId);
                    sb.AppendLine($"# Attribute {v.AttributeId} {attrName}");
                }

                sb.AppendLine($"v {floatV.X} {floatV.Z} {-floatV.Y}");
            }

            sb.AppendLine($"# {mesh.VertexAddressRange.End}");
        }
        private static void OutputFaces(RrfModel model, StringBuilder sb, RrfMesh mesh, int index)
        {
            sb.AppendLine($"# {mesh.FaceCount} Faces");
            sb.AppendLine($"# {mesh.FaceAddressRange.Start}");
            foreach (var face in mesh.Faces)
            {
                var vertexIndexOffset = 1 + model.Meshes.Take(index).Sum(f => f.VertexCount);

                sb.AppendLine(
                    $"f {face.VertexIndexes[0] + vertexIndexOffset}" +
                    $" {face.VertexIndexes[1] + vertexIndexOffset}" +
                    $" {face.VertexIndexes[2] + vertexIndexOffset}" +
                    (face.IsQuad ? $" {face.VertexIndexes[3] + vertexIndexOffset}" : string.Empty));
            }

            sb.AppendLine($"# {mesh.FaceAddressRange.End}");
        }
示例#3
0
        private static void LoadMeshHeaders(ref RrfModel rrfModel, ref FileStream fileStream)
        {
            for (var meshIndex = 0; meshIndex < rrfModel.MeshCount; meshIndex++)
            {
                var mesh = new RrfMesh
                {
                    HeaderAddressRange = new AddressRange
                    {
                        Start = fileStream.Position
                    }
                };

                // Read mesh name at 0x14
                const int maxNameLength = 0xC;

                for (var i = 0; i < maxNameLength; i++)
                {
                    var nByte = fileStream.ReadByte();

                    // Escape on first 0 byte
                    if (nByte == 0x0)
                    {
                        break;
                    }

                    mesh.Name += (char)nByte;
                }

                // Skip mesh name field
                var nameOffset = maxNameLength - mesh.Name.Length - 1; // Minus one because we read a null byte
                fileStream.Seek(nameOffset, SeekOrigin.Current);
                var nameEnd = fileStream.Position;

                mesh.Origin = new int3(fileStream.ReadInt32(), fileStream.ReadInt32(), fileStream.ReadInt32());

                // Read bounds
                mesh.BoundingBox         = new int3(fileStream.ReadInt32());
                mesh.BoundingBoxOffset   = new int3(fileStream.ReadInt32());
                mesh.BoundingBox.Y       = fileStream.ReadInt32();
                mesh.BoundingBoxOffset.Y = fileStream.ReadInt32();
                mesh.BoundingBox.Z       = fileStream.ReadInt32();
                mesh.BoundingBoxOffset.Z = fileStream.ReadInt32();

                // Read unknown values
                const int unknownNumbersOffset = 0x44;
                while (fileStream.Position < nameEnd + unknownNumbersOffset)
                {
                    mesh.UnknownPreTypeBytes.Add(fileStream.ReadInt32());
                }

                // Mesh type byte at 0x64
                mesh.Type = fileStream.ReadByte();

                // Read unknown type bytes
                for (var i = 0; i < 0x3; i++)
                {
                    mesh.UnknownTypeBytes.Add(fileStream.ReadByte());
                }

                mesh.VertexCount = fileStream.ReadInt32();

                // Skip terminating(?) FF FF FF FF bytes
                fileStream.Seek(0x4, SeekOrigin.Current);

                // Read child elements
                mesh.ChildCount = fileStream.ReadInt32();

                for (var i = 0; i < mesh.ChildCount && mesh.ChildCount > 0; i++)
                {
                    mesh.ChildMeshes.Add(fileStream.ReadInt32());
                }

                // Skip remaining child elements range
                var unknownIntCount = (32 - mesh.ChildCount) * 4;   // 4x to skip by int size
                fileStream.Seek(unknownIntCount, SeekOrigin.Current);

                // Read address ints
                mesh.UnknownZeroValue = fileStream.ReadInt32(); // RolloverIndex

                mesh.FaceCount        = fileStream.ReadInt32();
                mesh.FaceAddressRange = new AddressRange(fileStream.ReadInt32(), fileStream.ReadInt32());

                mesh.DuplicateVertexValue = fileStream.ReadInt32(); // Duplicate(?) vertex count?

                mesh.VertexAddressRange  = new AddressRange(fileStream.ReadInt32(), fileStream.ReadInt32());
                mesh.UnknownAddressRange = new AddressRange(fileStream.ReadInt32(), fileStream.ReadInt32());

                mesh.HeaderAddressRange.End = fileStream.Position;

                // Skip duplicate address patterns
                fileStream.Seek(0xFC, SeekOrigin.Current);

                rrfModel.Meshes.Add(mesh);
            }
        }