/// <summary> /// Reads the dungeon block /// </summary> public uint ReadDungeonBlock() { uint lastFilePos = (uint)m_sourceFile.Position; try { m_sourceFile.PrepareFileForReading(); uint fileId; if (m_myStartPos == 0) { // file id, assert that it matches the file fileId = m_sourceFile.ReadUInt32(); Debug.Assert(fileId == m_sourceFile.FileId); // flags & texture IDs m_flags = m_sourceFile.ReadUInt32(); } else { m_sourceFile.Seek((uint)m_myStartPos); m_sourceFile.AlignToDwordBoundary(); m_flags = 0xFFFFFFFF; fileId = 0xFFFFFFFF; } //Debug.Assert(m_flags == 0x01); // check known flag values m_textureCount = m_sourceFile.ReadUInt32(); // index, perhaps? // unknown values m_t2TrifanCount = m_sourceFile.ReadUInt32(); m_t1TrifanCount = m_sourceFile.ReadUInt32(); m_unkBytesAfterTrifans = m_sourceFile.ReadUInt32(); m_unk4 = m_sourceFile.ReadUInt32(); // vertex data m_vertexCount = m_sourceFile.ReadUInt32(); m_vertexInfo = new VertexInfo[m_vertexCount]; for (int i = 0; i < m_vertexCount; i++) { m_vertexInfo[i].VertexIndex = m_sourceFile.ReadUInt16(); Debug.Assert(i == m_vertexInfo[i].VertexIndex); m_vertexInfo[i].CUVDataLength = m_sourceFile.ReadUInt16(); m_vertexInfo[i].X = m_sourceFile.ReadSingle(); m_vertexInfo[i].Y = m_sourceFile.ReadSingle(); m_vertexInfo[i].Z = m_sourceFile.ReadSingle(); m_vertexInfo[i].NX = m_sourceFile.ReadSingle(); m_vertexInfo[i].NY = m_sourceFile.ReadSingle(); m_vertexInfo[i].NZ = m_sourceFile.ReadSingle(); m_vertexInfo[i].CUVData = new UV[m_vertexInfo[i].CUVDataLength]; for (int j = 0; j < m_vertexInfo[i].CUVDataLength; j++) { m_vertexInfo[i].CUVData[j].U = m_sourceFile.ReadSingle(); m_vertexInfo[i].CUVData[j].V = m_sourceFile.ReadSingle(); } } if (fileId == 0x0d0000ca) { Debugger.Break(); } MeshParser meshParser = new MeshParser(m_sourceFile); T2TrifanSet = meshParser.ParseTrifanSet(true, m_t2TrifanCount, TrifanType.T2, (int)m_unkBytesAfterTrifans); //TrifanInfo[] trifans = new TrifanInfo[(int)m_t1TrifanCount]; //for (int i = 0; i < trifans.Length; i++) //{ // trifans[i] = meshParser.ParseTrifanInfo(); //} T1TrifanSet = meshParser.ParseTrifanSet(true, m_t1TrifanCount, TrifanType.T1); if (!m_sourceFile.HasReachedEnd) { uint nextVal = m_sourceFile.ReadUInt32(); if (nextVal == 1) { BP tmpBP2 = meshParser.ParseTaggedRecord(TrifanType.T0); m_sourceFile.AlignToDwordBoundary(); } else { if (!m_sourceFile.HasReachedEnd) { // break, unknown condition Debugger.Break(); } } } // read tagged record, if needed if (!m_sourceFile.HasReachedEnd) { m_taggedElementStart = m_sourceFile.Position; m_taggedElement = new DungeonBlock(m_sourceFile.CreateCopy(), m_taggedElementStart); uint newPosition = m_taggedElement.ReadDungeonBlock(); m_sourceFile.Seek(newPosition); } Debug.Assert(m_sourceFile.HasReachedEnd); } finally { lastFilePos = (uint)m_sourceFile.Position; m_sourceFile.FileReadingComplete(); } return(lastFilePos); }
/// <summary> /// reads the mesh from file into memory. /// </summary> public void ReadSimpleMesh() { bool breakAfterParsing = false; try { m_sourceFile.PrepareFileForReading(); // file id, assert that it matches the file uint fileId = m_sourceFile.ReadUInt32(); Debug.Assert(fileId == m_sourceFile.FileId); // flags & texture IDs m_flags = m_sourceFile.ReadUInt32(); Debug.Assert(m_flags == 0x02 || m_flags == 0x03 || m_flags == 0x0a || m_flags == 0x0b); // check known flag values if (fileId == 0x01000007) { //Debugger.Break(); } if (m_sourceFile.DatType == DatType.Portal_ToD) { m_textureCount = m_sourceFile.ReadByte(); } else { m_textureCount = m_sourceFile.ReadUInt32(); } m_textureInfo = new uint[m_textureCount]; for (int i = 0; i < m_textureCount; i++) { m_textureInfo[i] = m_sourceFile.ReadUInt32(); } // unknown value, always 0x01 uint unknown1 = m_sourceFile.ReadUInt32(); Debug.Assert(unknown1 == 0x01); // vertex data m_vertexCount = m_sourceFile.ReadUInt32(); m_vertexInfo = new VertexInfo[m_vertexCount]; for (int i = 0; i < m_vertexCount; i++) { m_vertexInfo[i].VertexIndex = m_sourceFile.ReadUInt16(); Debug.Assert(i == m_vertexInfo[i].VertexIndex); m_vertexInfo[i].CUVDataLength = m_sourceFile.ReadUInt16(); if (m_vertexInfo[i].CUVDataLength < m_textureCount) { breakAfterParsing = true; } m_vertexInfo[i].X = m_sourceFile.ReadSingle(); m_vertexInfo[i].Y = m_sourceFile.ReadSingle(); m_vertexInfo[i].Z = m_sourceFile.ReadSingle(); m_vertexInfo[i].NX = m_sourceFile.ReadSingle(); m_vertexInfo[i].NY = m_sourceFile.ReadSingle(); m_vertexInfo[i].NZ = m_sourceFile.ReadSingle(); m_vertexInfo[i].CUVData = new UV[m_vertexInfo[i].CUVDataLength]; for (int j = 0; j < m_vertexInfo[i].CUVDataLength; j++) { m_vertexInfo[i].CUVData[j].U = m_sourceFile.ReadSingle(); m_vertexInfo[i].CUVData[j].V = m_sourceFile.ReadSingle(); } } // look at the flags and decide what comes next. The two least significant // bits decide on how many substructures will follow (one or two). bool hasSetOne = ((m_flags & 0x01) == 0x01); bool hasSetTwo = ((m_flags & 0x02) == 0x02); MeshParser meshParser = new MeshParser(m_sourceFile); if (hasSetOne) { m_firstTrifanSet = meshParser.ParseTrifanSet(true, m_sourceFile.ReadUInt32(), TrifanType.T1); } if (hasSetTwo) { meshParser.ReadThreeFloats(out m_unknown3_a, out m_unknown3_b, out m_unknown3_c); uint trifanCount; if (m_sourceFile.DatType == DatType.Portal_ToD) { trifanCount = m_sourceFile.ReadByte(); } else { trifanCount = m_sourceFile.ReadUInt32(); } m_secondTrifanSet = meshParser.ParseTrifanSet(true, trifanCount, TrifanType.T0); } if (m_sourceFile.DatType == DatType.Portal_ToD) { if ((m_flags & 0x08) == 0x08) { // read uint 32 directing us at some 0x11?????? file uint elevenFile = m_sourceFile.ReadUInt32(); } } Debug.Assert(m_sourceFile.HasReachedEnd); } finally { m_sourceFile.FileReadingComplete(); } if (breakAfterParsing) { //Debugger.Break(); } }