Esempio n. 1
0
        /// <summary>
        /// Read mesh data to record array.
        /// </summary>
        /// <param name="record">Destination record index.</param>
        private bool ReadMesh(int record)
        {
            // Create empty mesh
            records[record].PureMesh = new PureMesh();

            // Create plane array
            int faceCount = records[record].Header.PlaneCount;

            records[record].PureMesh.Planes = new PurePlane[faceCount];

            // Get reader for normal data
            long         normalPosition = records[record].Header.NormalListOffset;
            BinaryReader normalReader   = records[record].MemoryFile.GetReader(normalPosition);

            // Read native data into plane array
            int          uniqueTextureCount = 0;
            MeshVersions version = records[record].Version;
            long         position = records[record].Header.PlaneListOffset;
            BinaryReader reader = records[record].MemoryFile.GetReader(position);
            BinaryReader pointReader = records[record].MemoryFile.GetReader();
            BinaryReader planeDataReader = records[record].MemoryFile.GetReader();
            int          minX = 0, maxX = 0, minY = 0, maxY = 0, minZ = 0, maxZ = 0;

            for (int plane = 0; plane < faceCount; plane++)
            {
                // Read plane header
                records[record].PureMesh.Planes[plane].Header.Position        = reader.BaseStream.Position;
                records[record].PureMesh.Planes[plane].Header.PlanePointCount = reader.ReadByte();
                records[record].PureMesh.Planes[plane].Header.Unknown1        = reader.ReadByte();
                records[record].PureMesh.Planes[plane].Header.Texture         = reader.ReadUInt16();
                records[record].PureMesh.Planes[plane].Header.UVunpack        = reader.ReadInt32();

                // Read the normal data for this plane
                Int32 nx = normalReader.ReadInt32();
                Int32 ny = normalReader.ReadInt32();
                Int32 nz = normalReader.ReadInt32();

                // Build list of unique textures across all planes - this will be used later to create submesh buffers
                UInt16 textureBitfield = records[record].PureMesh.Planes[plane].Header.Texture;
                int    textureArchive  = textureBitfield >> 7;
                int    textureRecord   = textureBitfield & 0x7f;
                bool   foundTexture    = false;
                for (int i = 0; i < uniqueTextureCount; i++)
                {
                    if (uniqueTextureBuffer[i].Archive == textureArchive && uniqueTextureBuffer[i].Record == textureRecord)
                    {
                        foundTexture = true;
                        break;
                    }
                }
                if (!foundTexture)
                {
                    uniqueTextureBuffer[uniqueTextureCount].Archive = textureArchive;
                    uniqueTextureBuffer[uniqueTextureCount].Record  = textureRecord;
                    uniqueTextureCount++;
                }

                // Store texture index for this plane
                records[record].PureMesh.Planes[plane].TextureIndex.Archive = textureArchive;
                records[record].PureMesh.Planes[plane].TextureIndex.Record  = textureRecord;

                // Read plane points
                int pointCount = records[record].PureMesh.Planes[plane].Header.PlanePointCount;
                records[record].PureMesh.Planes[plane].Points = new FaceUVTool.DFPurePoint[pointCount];
                for (int point = 0; point < pointCount; point++)
                {
                    // Read offset
                    int pointOffset = reader.ReadInt32();

                    // Read UV data
                    int u = reader.ReadInt16();
                    int v = reader.ReadInt16();

                    // Fix some UV coordinates (process only the first 3 points as
                    // coordinates from point 4 and above are ignored)
                    if (point < 3)
                    {
                        // Fix incorrect coordinates
                        FixBadUVCoordinates(record, plane, point, ref u, ref v);

                        // Fix coordinates which require specific unpacking
                        if (records[record].PureMesh.Planes[plane].Header.UVunpack == 0)
                        {
                            UVunpack(ref u);
                            UVunpack(ref v);
                        }
                    }

                    // Store UV coordinates
                    records[record].PureMesh.Planes[plane].Points[point].u = u;
                    records[record].PureMesh.Planes[plane].Points[point].v = v;

                    // Get point position
                    long pointPosition = records[record].Header.PointListOffset;
                    switch (version)
                    {
                    case MeshVersions.Version27:
                    case MeshVersions.Version26:
                        pointPosition += pointOffset;
                        break;

                    case MeshVersions.Version25:
                        pointPosition += (pointOffset * 3);
                        break;
                    }

                    // Read native point values
                    pointReader.BaseStream.Position = pointPosition;
                    int x = pointReader.ReadInt32();
                    int y = pointReader.ReadInt32();
                    int z = pointReader.ReadInt32();

                    // Find min/max values of native points so far
                    // This can be used to construct a tight box around mesh
                    if (x < minX)
                    {
                        minX = x;
                    }
                    if (x > maxX)
                    {
                        maxX = x;
                    }
                    if (y < minY)
                    {
                        minY = y;
                    }
                    if (y > maxY)
                    {
                        maxY = y;
                    }
                    if (z < minZ)
                    {
                        minZ = z;
                    }
                    if (z > maxZ)
                    {
                        maxZ = z;
                    }

                    // Store native point values
                    records[record].PureMesh.Planes[plane].Points[point].x = x;
                    records[record].PureMesh.Planes[plane].Points[point].y = y;
                    records[record].PureMesh.Planes[plane].Points[point].z = z;

                    // Store native normal values for each vertex
                    records[record].PureMesh.Planes[plane].Points[point].nx = nx;
                    records[record].PureMesh.Planes[plane].Points[point].ny = ny;
                    records[record].PureMesh.Planes[plane].Points[point].nz = nz;
                }

                // Read unknown plane data
                planeDataReader.BaseStream.Position = records[record].Header.PlaneDataOffset + plane * 24;
                records[record].PureMesh.Planes[plane].PlaneData = planeDataReader.ReadBytes(24);

                // Store size of mesh
                DFMesh.DFPoint size = new DFMesh.DFPoint();
                size.X = (maxX / pointDivisor - minX / pointDivisor);
                size.Y = (maxY / pointDivisor - minY / pointDivisor);
                size.Z = (maxZ / pointDivisor - minZ / pointDivisor);
                records[record].PureMesh.Size = size;

                // Store centre of mesh
                DFMesh.DFPoint centre = new DFMesh.DFPoint();
                centre.X = size.X / 2;
                centre.Y = size.Y / 2;
                centre.Z = size.Z / 2;
                records[record].PureMesh.Centre = centre;
            }

            //// Read unknown object data, but ignore known non-conforming objects
            //if (records[record].Header.ObjectDataCount > 0 &&
            //    records[record].ObjectId != 4722 &&
            //    records[record].ObjectId != 7614)
            //{
            //    // Create object data record array
            //    records[record].ObjectDataRecords = new ObjectDataRecord[records[record].Header.ObjectDataCount];

            //    // Start reading
            //    reader.BaseStream.Position = records[record].Header.ObjectDataOffset;
            //    for (int i = 0; i < records[record].Header.ObjectDataCount; i++)
            //    {
            //        // Read object data record header
            //        records[record].ObjectDataRecords[i].Header.N1 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.N2 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.N3 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.N4 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.SubRecordCount = reader.ReadInt16();

            //        // Read unknown sub-records
            //        records[record].ObjectDataRecords[i].SubRecords = new ObjectDataSubRecord[records[record].ObjectDataRecords[i].Header.SubRecordCount];
            //        for (int j = 0; j < records[record].ObjectDataRecords[i].Header.SubRecordCount; j++)
            //        {
            //            records[record].ObjectDataRecords[i].SubRecords[j].Unknown1 = reader.ReadBytes(6);
            //        }
            //    }
            //}

            // Copy valid part of unique texture list into pureMesh data and create plane buffer for decomposition
            records[record].PureMesh.UniqueTextures = new TextureIndex[uniqueTextureCount];
            for (int i = 0; i < uniqueTextureCount; i++)
            {
                records[record].PureMesh.UniqueTextures[i] = uniqueTextureBuffer[i];
                subMeshBuffer[i].TextureArchive            = uniqueTextureBuffer[i].Archive;
                subMeshBuffer[i].TextureRecord             = uniqueTextureBuffer[i].Record;
                subMeshBuffer[i].planeCount  = 0;
                subMeshBuffer[i].PlaneBuffer = new DFPlaneBuffer[planeBufferLength];
            }

            return(true);
        }
        /// <summary>
        /// Read mesh data to record array.
        /// </summary>
        /// <param name="record">Destination record index.</param>
        private bool ReadMesh(int record)
        {
            // Create empty mesh
            records[record].PureMesh = new PureMesh();

            // Create plane array
            int faceCount = records[record].Header.PlaneCount;

            records[record].PureMesh.Planes = new PurePlane[faceCount];

            // Get reader for normal data
            long         normalPosition = records[record].Header.NormalListOffset;
            BinaryReader normalReader   = records[record].MemoryFile.GetReader(normalPosition);

            // Read native data into plane array
            int          uniqueTextureCount = 0;
            MeshVersions version            = records[record].Version;
            long         position           = records[record].Header.PlaneListOffset;
            BinaryReader reader             = records[record].MemoryFile.GetReader(position);
            BinaryReader pointReader        = records[record].MemoryFile.GetReader();
            BinaryReader planeDataReader    = records[record].MemoryFile.GetReader();

            for (int plane = 0; plane < faceCount; plane++)
            {
                // Read plane header
                records[record].PureMesh.Planes[plane].Header.Position        = reader.BaseStream.Position;
                records[record].PureMesh.Planes[plane].Header.PlanePointCount = reader.ReadByte();
                records[record].PureMesh.Planes[plane].Header.Unknown1        = reader.ReadByte();
                records[record].PureMesh.Planes[plane].Header.Texture         = reader.ReadUInt16();
                records[record].PureMesh.Planes[plane].Header.Unknown2        = reader.ReadUInt32();

                // Read the normal data for this plane
                Int32 nx = normalReader.ReadInt32();
                Int32 ny = normalReader.ReadInt32();
                Int32 nz = normalReader.ReadInt32();

                // Build list of unique textures across all planes - this will be used later to create submesh buffers
                UInt16 textureBitfield = records[record].PureMesh.Planes[plane].Header.Texture;
                int    textureArchive  = textureBitfield >> 7;
                int    textureRecord   = textureBitfield & 0x7f;
                bool   foundTexture    = false;
                for (int i = 0; i < uniqueTextureCount; i++)
                {
                    if (uniqueTextureBuffer[i].Archive == textureArchive && uniqueTextureBuffer[i].Record == textureRecord)
                    {
                        foundTexture = true;
                        break;
                    }
                }
                if (!foundTexture)
                {
                    uniqueTextureBuffer[uniqueTextureCount].Archive = textureArchive;
                    uniqueTextureBuffer[uniqueTextureCount].Record  = textureRecord;
                    uniqueTextureCount++;
                }

                // Store texture index for this plane
                records[record].PureMesh.Planes[plane].TextureIndex.Archive = textureArchive;
                records[record].PureMesh.Planes[plane].TextureIndex.Record  = textureRecord;

                // Read plane points
                int pointCount = records[record].PureMesh.Planes[plane].Header.PlanePointCount;
                records[record].PureMesh.Planes[plane].Points = new FaceUVTool.DFPurePoint[pointCount];
                for (int point = 0; point < pointCount; point++)
                {
                    // Read offset
                    int pointOffset = reader.ReadInt32();

                    // Read UV data
                    Int16 u = reader.ReadInt16();
                    Int16 v = reader.ReadInt16();

                    // Fix certain UV coordinates that are
                    // packed oddly, or aligned outside of poly.
                    int threshold = 14335;
                    while (u > threshold)
                    {
                        u = (Int16)(0x4000 - u);
                    }
                    while (u < -threshold)
                    {
                        u = (Int16)(0x4000 + u);
                    }
                    while (v > threshold)
                    {
                        v = (Int16)(0x4000 - v);
                    }
                    while (v < -threshold)
                    {
                        v = (Int16)(0x4000 + v);
                    }

                    // Store UV coordinates
                    records[record].PureMesh.Planes[plane].Points[point].u = u;
                    records[record].PureMesh.Planes[plane].Points[point].v = v;

                    // Get point position
                    long pointPosition = records[record].Header.PointListOffset;
                    switch (version)
                    {
                    case MeshVersions.Version27:
                    case MeshVersions.Version26:
                        pointPosition += pointOffset;
                        break;

                    case MeshVersions.Version25:
                        pointPosition += (pointOffset * 3);
                        break;
                    }

                    // Store native point values
                    pointReader.BaseStream.Position = pointPosition;
                    records[record].PureMesh.Planes[plane].Points[point].x = pointReader.ReadInt32();
                    records[record].PureMesh.Planes[plane].Points[point].y = pointReader.ReadInt32();
                    records[record].PureMesh.Planes[plane].Points[point].z = pointReader.ReadInt32();

                    // Store native normal values for each vertex
                    records[record].PureMesh.Planes[plane].Points[point].nx = nx;
                    records[record].PureMesh.Planes[plane].Points[point].ny = ny;
                    records[record].PureMesh.Planes[plane].Points[point].nz = nz;
                }

                // Read unknown plane data
                planeDataReader.BaseStream.Position = records[record].Header.PlaneDataOffset + plane * 24;
                records[record].PureMesh.Planes[plane].PlaneData = planeDataReader.ReadBytes(24);
            }

            //// Read unknown object data, but ignore known non-conforming objects
            //if (records[record].Header.ObjectDataCount > 0 &&
            //    records[record].ObjectId != 4722 &&
            //    records[record].ObjectId != 7614)
            //{
            //    // Create object data record array
            //    records[record].ObjectDataRecords = new ObjectDataRecord[records[record].Header.ObjectDataCount];

            //    // Start reading
            //    reader.BaseStream.Position = records[record].Header.ObjectDataOffset;
            //    for (int i = 0; i < records[record].Header.ObjectDataCount; i++)
            //    {
            //        // Read object data record header
            //        records[record].ObjectDataRecords[i].Header.N1 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.N2 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.N3 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.N4 = reader.ReadInt32();
            //        records[record].ObjectDataRecords[i].Header.SubRecordCount = reader.ReadInt16();

            //        // Read unknown sub-records
            //        records[record].ObjectDataRecords[i].SubRecords = new ObjectDataSubRecord[records[record].ObjectDataRecords[i].Header.SubRecordCount];
            //        for (int j = 0; j < records[record].ObjectDataRecords[i].Header.SubRecordCount; j++)
            //        {
            //            records[record].ObjectDataRecords[i].SubRecords[j].Unknown1 = reader.ReadBytes(6);
            //        }
            //    }
            //}

            // Copy valid part of unique texture list into pureMesh data and create plane buffer for decomposition
            records[record].PureMesh.UniqueTextures = new TextureIndex[uniqueTextureCount];
            for (int i = 0; i < uniqueTextureCount; i++)
            {
                records[record].PureMesh.UniqueTextures[i] = uniqueTextureBuffer[i];
                subMeshBuffer[i].TextureArchive            = uniqueTextureBuffer[i].Archive;
                subMeshBuffer[i].TextureRecord             = uniqueTextureBuffer[i].Record;
                subMeshBuffer[i].planeCount  = 0;
                subMeshBuffer[i].PlaneBuffer = new DFPlaneBuffer[planeBufferLength];
            }

            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// Read mesh data to record array.
        /// </summary>
        /// <param name="Record">Destination record index.</param>
        private bool ReadMesh(int Record)
        {
            // Create empty mesh
            Records[Record].PureMesh = new PureMesh();

            // Create plane array
            int faceCount = Records[Record].Header.PlaneCount;

            Records[Record].PureMesh.Planes = new PurePlane[faceCount];

            // Get reader for normal data
            long         normalPosition = Records[Record].Header.NormalListOffset;
            BinaryReader normalReader   = Records[Record].MemoryFile.GetReader(normalPosition);

            // Read native data into plane array
            int          uniqueTextureCount = 0;
            MeshVersions version            = Records[Record].Version;
            long         position           = Records[Record].Header.PlaneListOffset;
            BinaryReader reader             = Records[Record].MemoryFile.GetReader(position);
            BinaryReader pointReader        = Records[Record].MemoryFile.GetReader();
            BinaryReader planeDataReader    = Records[Record].MemoryFile.GetReader();

            for (int plane = 0; plane < faceCount; plane++)
            {
                // Read plane header
                Records[Record].PureMesh.Planes[plane].Header.Position        = reader.BaseStream.Position;
                Records[Record].PureMesh.Planes[plane].Header.PlanePointCount = reader.ReadByte();
                Records[Record].PureMesh.Planes[plane].Header.Unknown1        = reader.ReadByte();
                Records[Record].PureMesh.Planes[plane].Header.Texture         = reader.ReadUInt16();
                Records[Record].PureMesh.Planes[plane].Header.Unknown2        = reader.ReadUInt32();

                // Read the normal data for this plane
                Int32 nx = normalReader.ReadInt32();
                Int32 ny = normalReader.ReadInt32();
                Int32 nz = normalReader.ReadInt32();

                // Build list of unique textures across all planes - this will be used later to create submesh buffers
                UInt16 textureBitfield = Records[Record].PureMesh.Planes[plane].Header.Texture;
                int    textureArchive  = textureBitfield >> 7;
                int    textureRecord   = textureBitfield & 0x7f;
                bool   foundTexture    = false;
                for (int i = 0; i < uniqueTextureCount; i++)
                {
                    if (UniqueTextureBuffer[i].Archive == textureArchive && UniqueTextureBuffer[i].Record == textureRecord)
                    {
                        foundTexture = true;
                        break;
                    }
                }
                if (!foundTexture)
                {
                    UniqueTextureBuffer[uniqueTextureCount].Archive = textureArchive;
                    UniqueTextureBuffer[uniqueTextureCount].Record  = textureRecord;
                    uniqueTextureCount++;
                }

                // Store texture index for this plane
                Records[Record].PureMesh.Planes[plane].TextureIndex.Archive = textureArchive;
                Records[Record].PureMesh.Planes[plane].TextureIndex.Record  = textureRecord;

                // Read plane points
                int pointCount = Records[Record].PureMesh.Planes[plane].Header.PlanePointCount;
                Records[Record].PureMesh.Planes[plane].Points = new FaceUVTool.DFPurePoint[pointCount];
                for (int point = 0; point < pointCount; point++)
                {
                    // Read offset
                    int pointOffset = reader.ReadInt32();

                    // Read UV data
                    Int16 u = reader.ReadInt16();
                    Int16 v = reader.ReadInt16();

                    // Fix certain UV coordinates that are
                    // packed oddly, or aligned outside of poly.
                    int threshold = 15000;
                    while (u > threshold)
                    {
                        u = (Int16)(0x4000 - u);
                    }
                    while (u < -threshold)
                    {
                        u = (Int16)(0x4000 + u);
                    }
                    while (v > threshold)
                    {
                        v = (Int16)(0x4000 - v);
                    }
                    while (v < -threshold)
                    {
                        v = (Int16)(0x4000 + v);
                    }

                    // Store UV coordinates
                    Records[Record].PureMesh.Planes[plane].Points[point].u = u;
                    Records[Record].PureMesh.Planes[plane].Points[point].v = v;

                    // Get point position
                    long pointPosition = Records[Record].Header.PointListOffset;
                    switch (version)
                    {
                    case MeshVersions.Version27:
                    case MeshVersions.Version26:
                        pointPosition += pointOffset;
                        break;

                    case MeshVersions.Version25:
                        pointPosition += (pointOffset * 3);
                        break;
                    }

                    // Store native point values
                    pointReader.BaseStream.Position = pointPosition;
                    Records[Record].PureMesh.Planes[plane].Points[point].x = pointReader.ReadInt32();
                    Records[Record].PureMesh.Planes[plane].Points[point].y = pointReader.ReadInt32();
                    Records[Record].PureMesh.Planes[plane].Points[point].z = pointReader.ReadInt32();

                    // Store native normal values for each vertex
                    Records[Record].PureMesh.Planes[plane].Points[point].nx = nx;
                    Records[Record].PureMesh.Planes[plane].Points[point].ny = ny;
                    Records[Record].PureMesh.Planes[plane].Points[point].nz = nz;
                }

                // Read unknown plane data
                planeDataReader.BaseStream.Position = Records[Record].Header.PlaneDataOffset + plane * 24;
                Records[Record].PureMesh.Planes[plane].PlaneData = planeDataReader.ReadBytes(24);
            }

            // CURRENTLY UNUSED - Read start of object data
            //if (records[record].header.objectDataCount > 0)
            //{
            //    // Read first object data record only (format is not yet known enough to enumerate)
            //    // This data is only loaded temporarily to look at for now
            //    reader.BaseStream.Position = records[record].header.objectDataOffset;

            //    // Read number array
            //    objectDataHeader dataHeader = new objectDataHeader();
            //    dataHeader.numbers = new Int32[4];
            //    for (int i = 0; i < 4; i++)
            //    {
            //        dataHeader.numbers[i] = reader.ReadInt32();
            //    }

            //    // Read sub-record count
            //    dataHeader.subrecordCount = reader.ReadInt16();
            //}

            // Copy valid part of unique texture list into pureMesh data and create plane buffer for decomposition
            Records[Record].PureMesh.UniqueTextures = new TextureIndex[uniqueTextureCount];
            for (int i = 0; i < uniqueTextureCount; i++)
            {
                Records[Record].PureMesh.UniqueTextures[i] = UniqueTextureBuffer[i];
                SubMeshBuffer[i].TextureArchive            = UniqueTextureBuffer[i].Archive;
                SubMeshBuffer[i].TextureRecord             = UniqueTextureBuffer[i].Record;
                SubMeshBuffer[i].planeCount  = 0;
                SubMeshBuffer[i].PlaneBuffer = new DFPlaneBuffer[PlaneBufferLength];
            }

            return(true);
        }