public WMOGroup(string filename) { Filename = filename; var mainChunk = new ChunkData(filename); MOGP = new MOGP(Chunk = mainChunk.GetChunkByName("MOGP")); var stream = Chunk.GetStream(); stream.Seek(Chunk.Offset + MOGP.ChunkHeaderSize, SeekOrigin.Begin); SubData = new ChunkData(stream, Chunk.Size - MOGP.ChunkHeaderSize); Read(); }
public MOGP ReadMOGPChunk(BlizzHeader chunk, BinaryReader bin) { MOGP mogp = new MOGP(); mogp.nameOffset = bin.ReadUInt32(); mogp.descriptiveNameOffset = bin.ReadUInt32(); mogp.flags = (MOGPFlags)bin.ReadUInt32(); mogp.boundingBox1 = bin.Read <Vector3>(); mogp.boundingBox2 = bin.Read <Vector3>(); mogp.ofsPortals = bin.ReadUInt16(); mogp.numPortals = bin.ReadUInt16(); mogp.numBatchesA = bin.ReadUInt16(); mogp.numBatchesB = bin.ReadUInt16(); mogp.numBatchesC = bin.ReadUInt32(); //mogp.fogIndices = bin.ReadBytes(4); bin.ReadBytes(4); mogp.liquidType = bin.ReadUInt32(); mogp.groupID = bin.ReadUInt32(); mogp.unk0 = bin.ReadUInt32(); mogp.unk1 = bin.ReadUInt32(); MemoryStream stream = new MemoryStream(bin.ReadBytes((int)chunk.Size)); var subbin = new BinaryReader(stream); BlizzHeader subchunk; long position = 0; int MOTVi = 0; if (mogp.flags.HasFlag(MOGPFlags.Flag_0x40000000)) { mogp.textureCoords = new MOTV[3][]; } else { mogp.textureCoords = new MOTV[2][]; } while (position < stream.Length) { stream.Position = position; subchunk = new BlizzHeader(subbin.ReadChars(4), subbin.ReadUInt32()); subchunk.Flip(); position = stream.Position + subchunk.Size; //Console.WriteLine(subchunk.ToString()); switch (subchunk.ToString()) { case "MOVI": //Vertex indices for triangles mogp.indices = ReadMOVIChunk(subchunk, subbin); //Console.WriteLine("Read " + mogp.indices.Length + " indices!"); break; case "MOVT": //Vertices chunk mogp.vertices = ReadMOVTChunk(subchunk, subbin); break; case "MOTV": //Texture coordinates mogp.textureCoords[MOTVi++] = ReadMOTVChunk(subchunk, subbin); break; case "MONR": //Normals mogp.normals = ReadMONRChunk(subchunk, subbin); break; case "MOBA": //Render batches mogp.renderBatches = ReadMOBAChunk(subchunk, subbin); break; case "MOPY": //Material info for triangles, two bytes per triangle. mogp.materialInfo = ReadMOPYChunk(subchunk, subbin); break; case "MOBS": //Unk case "MODR": //Doodad references case "MOBN": //Array of t_BSP_NODE case "MOBR": //Face indices case "MOLR": //Light references case "MOCV": //Vertex colors case "MDAL": //Unk (new in WoD?) case "MLIQ": //Liquids case "MOTA": //Unknown case "MOPL": //Unknown case "MOLP": //Unknown continue; default: throw new Exception(String.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subchunk.ToString(), position.ToString())); } } //if(MOTVi == 0) { throw new Exception("Didn't parse any MOTV??"); } // antiportal groups have no motv return(mogp); }
private MOGP ReadMOGPChunk(uint size, BinaryReader bin) { MOGP mogp = new MOGP() { nameOffset = bin.ReadUInt32(), descriptiveNameOffset = bin.ReadUInt32(), flags = (MOGPFlags)bin.ReadUInt32(), boundingBox1 = bin.Read <Vector3>(), boundingBox2 = bin.Read <Vector3>(), ofsPortals = bin.ReadUInt16(), numPortals = bin.ReadUInt16(), numBatchesA = bin.ReadUInt16(), numBatchesB = bin.ReadUInt16(), numBatchesC = bin.ReadUInt32(), unused = bin.ReadUInt32(), liquidType = bin.ReadUInt32(), groupID = bin.ReadUInt32(), unk0 = bin.ReadUInt32(), unk1 = bin.ReadUInt32() }; using (var stream = new MemoryStream(bin.ReadBytes((int)size))) using (var subbin = new BinaryReader(stream)) { long position = 0; int MOTVi = 0; if (mogp.flags.HasFlag(MOGPFlags.Flag_0x40000000)) { mogp.textureCoords = new MOTV[3][]; } else { mogp.textureCoords = new MOTV[2][]; } while (position < stream.Length) { stream.Position = position; var subChunkName = new string(subbin.ReadChars(4).Reverse().ToArray()); var subChunkSize = subbin.ReadUInt32(); position = stream.Position + subChunkSize; switch (subChunkName) { case "MOVI": //Vertex indices for triangles mogp.indices = ReadMOVIChunk(subChunkSize, subbin); //Console.WriteLine("Read " + mogp.indices.Length + " indices!"); break; case "MOVT": //Vertices chunk mogp.vertices = ReadMOVTChunk(subChunkSize, subbin); break; case "MOTV": //Texture coordinates mogp.textureCoords[MOTVi++] = ReadMOTVChunk(subChunkSize, subbin); break; case "MONR": //Normals mogp.normals = ReadMONRChunk(subChunkSize, subbin); break; case "MOBA": //Render batches mogp.renderBatches = ReadMOBAChunk(subChunkSize, subbin); break; case "MOPY": //Material info for triangles, two bytes per triangle. mogp.materialInfo = ReadMOPYChunk(subChunkSize, subbin); break; case "MOBS": //Unk case "MODR": //Doodad references case "MOBN": //Array of t_BSP_NODE case "MOBR": //Face indices case "MOLR": //Light references case "MOCV": //Vertex colors case "MDAL": //Unk (new in WoD?) case "MLIQ": //Liquids case "MOTA": //Unknown case "MOPL": //Unknown case "MOLP": //Unknown case "MOLS": //Unknown continue; default: throw new Exception(String.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subChunkName, position.ToString())); } } } return(mogp); }
private MOGP ReadMOGPChunk(uint size, BinaryReader bin) { var mogp = new MOGP() { nameOffset = bin.ReadUInt32(), descriptiveNameOffset = bin.ReadUInt32(), flags = (MOGPFlags)bin.ReadUInt32(), boundingBox1 = bin.Read <Vector3>(), boundingBox2 = bin.Read <Vector3>(), ofsPortals = bin.ReadUInt16(), numPortals = bin.ReadUInt16(), numBatchesA = bin.ReadUInt16(), numBatchesB = bin.ReadUInt16(), numBatchesC = bin.ReadUInt32(), unused = bin.ReadUInt32(), liquidType = bin.ReadUInt32(), groupID = bin.ReadUInt32(), unk0 = bin.ReadUInt32(), unk1 = bin.ReadUInt32() }; using (var stream = new MemoryStream(bin.ReadBytes((int)size))) using (var subbin = new BinaryReader(stream)) { long position = 0; var MOTVi = 0; if (mogp.flags.HasFlag(MOGPFlags.Flag_0x40000000)) { mogp.textureCoords = new MOTV[3][]; } else { mogp.textureCoords = new MOTV[2][]; } while (position < stream.Length) { stream.Position = position; var subChunkName = (WMOChunks)subbin.ReadUInt32(); var subChunkSize = subbin.ReadUInt32(); position = stream.Position + subChunkSize; switch (subChunkName) { case WMOChunks.MOVI: // MOVI Vertex indices for triangles mogp.indices = ReadMOVIChunk(subChunkSize, subbin); break; case WMOChunks.MOVT: // MOVT Vertices chunk mogp.vertices = ReadMOVTChunk(subChunkSize, subbin); break; case WMOChunks.MOTV: // MOTV Texture coordinates mogp.textureCoords[MOTVi++] = ReadMOTVChunk(subChunkSize, subbin); break; case WMOChunks.MONR: // MONR Normals mogp.normals = ReadMONRChunk(subChunkSize, subbin); break; case WMOChunks.MOBA: // MOBA Render batches mogp.renderBatches = ReadMOBAChunk(subChunkSize, subbin); break; case WMOChunks.MOPY: // MOPY Material info for triangles, two bytes per triangle. mogp.materialInfo = ReadMOPYChunk(subChunkSize, subbin); break; case WMOChunks.MOBS: // MOBS Unk case WMOChunks.MODR: // MODR Doodad references case WMOChunks.MOBN: // MOBN Array of t_BSP_NODE case WMOChunks.MOBR: // MOBR Face indices case WMOChunks.MOLR: // MOLR Light references case WMOChunks.MOCV: // MOCV Vertex colors case WMOChunks.MDAL: // MDAL Unk (new in WoD) case WMOChunks.MLIQ: // MLIQ Liquids case WMOChunks.MOTA: // MOTA Tangent Array case WMOChunks.MOPL: // MOPL Terrain Cutting PLanes case WMOChunks.MOLP: // MOLP Points Lights case WMOChunks.MOLS: // MOLS Spot Lights case WMOChunks.MOPB: // MOPB Prepass Batches case WMOChunks.MLSP: // ? case WMOChunks.MLSS: // ? case WMOChunks.MLSK: // ? case WMOChunks.MOP2: // ? continue; default: #if DEBUG Console.WriteLine(string.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subChunkName.ToString("X"), position.ToString())); break; #else CASCLib.Logger.WriteLine("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subChunkName.ToString("X"), position.ToString()); break; #endif } } } return(mogp); }