/// <summary> /// Initialized the vertex & index buffers for this mesh scene /// </summary> public void ReInitialize() { if (m_noTexturing) { ReInitializeWithoutTexturing(); return; } // prepare vars m_coloredTrifans.Clear(); m_texturedTrifans.Clear(); // loop through the texturing info and determine for each of them what // type of decoration it is. m_decorations = new MeshDecoration[m_simpleMesh.TextureInfo.Length]; m_textures = new Texture[m_decorations.Length]; for (int i = 0; i < m_decorations.Length; i++) { m_decorations[i] = new MeshDecoration(m_simpleMesh.TextureInfo[i]); if (m_decorations[i].DecorationType == DecorationType.Texture) { Bitmap bmp = m_decorations[i].Texture.GetBitmap(); m_textures[i] = new Texture(m_device, bmp, 0, Pool.Managed); } } // we'll have to create two sets of index buffers: // one for textured trifans and one for colored trifans // we'll have to determine for each trifan to which of these it belongs List <VertexLookup> texturedVertexTable = new List <VertexLookup>(); List <VertexLookup> coloredVertexTable = new List <VertexLookup>(); List <ushort> texturedIndexList = new List <ushort>(); List <ushort> coloredIndexList = new List <ushort>(); for (int i = 0; i < (int)m_simpleMesh.SecondTrifanSet.TrifanCount; i++) { TrifanInfo trifan = m_simpleMesh.SecondTrifanSet.TrifanData[i]; bool drawSolidColor = false; drawSolidColor = (trifan.Flags & 0x04) == 0x04; // draw solid when this trifan is drawn using a solid color drawSolidColor = drawSolidColor || (m_decorations[(int)trifan.TextureIndex].DecorationType == DecorationType.SolidColor); if (drawSolidColor) { Color color = m_decorations[(int)trifan.TextureIndex].SolidColor; TrifanDrawInfo trifanInfo = new TrifanDrawInfo(); trifanInfo.IndexBufferStart = (ushort)coloredIndexList.Count; trifanInfo.PrimitiveCount = trifan.VertexCount - 2; for (int j = 0; j < trifan.VertexIndices.Length; j++) { VertexLookup lookup = new VertexLookup(trifan.VertexIndices[j], 0, color); ushort vertexIndex; if (!coloredVertexTable.Contains(lookup)) { coloredVertexTable.Add(lookup); } vertexIndex = (ushort)coloredVertexTable.IndexOf(lookup); coloredIndexList.Add(vertexIndex); } m_coloredTrifans.Add(i, trifanInfo); } else { TrifanDrawInfo trifanInfo = new TrifanDrawInfo(); trifanInfo.IndexBufferStart = (ushort)texturedIndexList.Count; trifanInfo.PrimitiveCount = trifan.VertexCount - 2; for (int j = 0; j < trifan.VertexIndices.Length; j++) { VertexLookup lookup = new VertexLookup(trifan.VertexIndices[j], trifan.UVIndex[j]); ushort vertexIndex; if (!texturedVertexTable.Contains(lookup)) { texturedVertexTable.Add(lookup); } vertexIndex = (ushort)texturedVertexTable.IndexOf(lookup); texturedIndexList.Add(vertexIndex); } m_texturedTrifans.Add(i, trifanInfo); } } // now create the actual index & vertex buffers // texture vb & ib if (texturedVertexTable.Count > 0) { m_vbTextured = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), texturedVertexTable.Count, m_device, Usage.WriteOnly, CustomVertex.PositionNormalTextured.Format, Pool.Managed); GraphicsStream stream = m_vbTextured.Lock(0, 0, LockFlags.None); foreach (VertexLookup lookup in texturedVertexTable) { VertexInfo vertex = m_simpleMesh.VertexInfo[(int)lookup.VertexId]; stream.Write(new CustomVertex.PositionNormalTextured(vertex.X, vertex.Y, vertex.Z, vertex.NX, vertex.NY, vertex.NZ, vertex.CUVData[lookup.UVIndex].U, vertex.CUVData[lookup.UVIndex].V)); } m_vbTextured.Unlock(); m_ibTextured = new IndexBuffer(typeof(ushort), texturedIndexList.Count, m_device, Usage.WriteOnly, Pool.Managed); stream = m_ibTextured.Lock(0, 0, LockFlags.None); stream.Write(texturedIndexList.ToArray()); m_ibTextured.Unlock(); } m_vbTexturedLength = texturedVertexTable.Count; // color vb & ib if (coloredVertexTable.Count > 0) { m_vbColored = new VertexBuffer(typeof(CustomVertex.PositionNormalColored), coloredVertexTable.Count, m_device, Usage.WriteOnly, CustomVertex.PositionNormalColored.Format, Pool.Managed); GraphicsStream stream = m_vbColored.Lock(0, 0, LockFlags.None); foreach (VertexLookup lookup in coloredVertexTable) { VertexInfo vertex = m_simpleMesh.VertexInfo[(int)lookup.VertexId]; stream.Write(new CustomVertex.PositionNormalColored(vertex.X, vertex.Y, vertex.Z, vertex.NX, vertex.NY, vertex.NZ, lookup.Color.ToArgb())); } m_vbColored.Unlock(); m_ibColored = new IndexBuffer(typeof(ushort), coloredIndexList.Count, m_device, Usage.WriteOnly, Pool.Managed); stream = m_ibColored.Lock(0, 0, LockFlags.None); stream.Write(coloredIndexList.ToArray()); m_ibColored.Unlock(); } m_vbColoredLength = coloredVertexTable.Count; }
/// <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); }
public void ReInitializeWithoutTexturing() { // prepare vars m_coloredTrifans.Clear(); m_texturedTrifans.Clear(); // loop through the texturing info and determine for each of them what // type of decoration it is. m_decorations = new MeshDecoration[0]; m_textures = new Texture[0]; // create a single trifan set of red trifans List <VertexLookup> coloredVertexTable = new List <VertexLookup>(); List <ushort> coloredIndexList = new List <ushort>(); for (int i = 0; i < (int)m_simpleMesh.SecondTrifanSet.TrifanCount; i++) { TrifanInfo trifan = m_simpleMesh.SecondTrifanSet.TrifanData[i]; Color color = Color.Red; TrifanDrawInfo trifanInfo = new TrifanDrawInfo(); trifanInfo.IndexBufferStart = (ushort)coloredIndexList.Count; trifanInfo.PrimitiveCount = trifan.VertexCount - 2; for (int j = 0; j < trifan.VertexIndices.Length; j++) { VertexLookup lookup = new VertexLookup(trifan.VertexIndices[j], 0, color); ushort vertexIndex; if (!coloredVertexTable.Contains(lookup)) { coloredVertexTable.Add(lookup); } vertexIndex = (ushort)coloredVertexTable.IndexOf(lookup); coloredIndexList.Add(vertexIndex); } m_coloredTrifans.Add(i, trifanInfo); } // now create the actual index & vertex buffers // texture vb & ib m_vbTexturedLength = 0; // color vb & ib if (coloredVertexTable.Count > 0) { m_vbColored = new VertexBuffer(typeof(CustomVertex.PositionNormalColored), coloredVertexTable.Count, m_device, Usage.WriteOnly, CustomVertex.PositionNormalColored.Format, Pool.Managed); GraphicsStream stream = m_vbColored.Lock(0, 0, LockFlags.None); foreach (VertexLookup lookup in coloredVertexTable) { VertexInfo vertex = m_simpleMesh.VertexInfo[(int)lookup.VertexId]; stream.Write(new CustomVertex.PositionNormalColored(vertex.X, vertex.Y, vertex.Z, vertex.NX, vertex.NY, vertex.NZ, lookup.Color.ToArgb())); } m_vbColored.Unlock(); m_ibColored = new IndexBuffer(typeof(ushort), coloredIndexList.Count, m_device, Usage.WriteOnly, Pool.Managed); stream = m_ibColored.Lock(0, 0, LockFlags.None); stream.Write(coloredIndexList.ToArray()); m_ibColored.Unlock(); } m_vbColoredLength = coloredVertexTable.Count; }
/// <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(); } }