// TODO: Change to stream-based loading /// <summary> /// Creates a new ADT object from a file on disk /// </summary> /// <param name="Data">Byte array containing ADT data.</param> /// <returns>A parsed ADT file with objects for all chunks</returns> public TerrainTile(byte[] Data) { using (MemoryStream ms = new MemoryStream(Data)) { using (BinaryReader br = new BinaryReader(ms)) { // In all ADT files, the version chunk and header chunk are at the beginning of the file, // with the header following the version. From them, the rest of the chunks can be // seeked to and read. // Read Version Chunk this.Version = br.ReadIFFChunk<TerrainVersion>(); // Read the header chunk this.Header = br.ReadIFFChunk<TerrainHeader>(); if (this.Header.MapChunkOffsetsOffset > 0) { br.BaseStream.Position = this.Header.MapChunkOffsetsOffset; this.MapChunkOffsets = br.ReadIFFChunk<TerrainMapChunkOffsets>(); } if (this.Header.TexturesOffset > 0) { br.BaseStream.Position = this.Header.TexturesOffset; this.Textures = br.ReadIFFChunk<TerrainTextures>(); } if (this.Header.ModelsOffset > 0) { br.BaseStream.Position = this.Header.ModelsOffset; this.Models = br.ReadIFFChunk<TerrainModels>(); } if (this.Header.ModelIndicesOffset > 0) { br.BaseStream.Position = this.Header.ModelIndicesOffset; this.ModelIndices = br.ReadIFFChunk<TerrainModelIndices>(); } if (this.Header.WorldModelObjectsOffset > 0) { br.BaseStream.Position = this.Header.WorldModelObjectsOffset; this.WorldModelObjects = br.ReadIFFChunk<TerrainWorldModelObjects>(); } if (this.Header.WorldModelObjectIndicesOffset > 0) { br.BaseStream.Position = this.Header.WorldModelObjectIndicesOffset; this.WorldModelObjectIndices = br.ReadIFFChunk<TerrainWorldObjectModelIndices>(); } if (this.Header.LiquidOffset > 0) { br.BaseStream.Position = this.Header.LiquidOffset; this.Liquids = br.ReadIFFChunk<TerrainLiquid>(); // TODO: [#9] Pass in DBC liquid type to load the vertex data } // Read and fill the map chunks foreach (MapChunkOffsetEntry Entry in this.MapChunkOffsets.Entries) { br.BaseStream.Position = Entry.MapChunkOffset; this.MapChunks.Add(br.ReadIFFChunk<TerrainMapChunk>()); } } } }
public WorldLOD(byte[] inData) { using (MemoryStream ms = new MemoryStream(inData)) { using (BinaryReader br = new BinaryReader(ms)) { // Set up the two area lists with default values for (int i = 0; i < 4096; ++i) { this.MapAreas.Add(null); this.MapAreaHoles.Add(null); } this.Version = br.ReadIFFChunk<TerrainVersion>(); if (br.PeekChunkSignature() == TerrainWorldModelObjects.Signature) { this.WorldModelObjects = br.ReadIFFChunk<TerrainWorldModelObjects>(); } if (br.PeekChunkSignature() == TerrainWorldObjectModelIndices.Signature) { this.WorldModelObjectIndices = br.ReadIFFChunk<TerrainWorldObjectModelIndices>(); } if (br.PeekChunkSignature() == TerrainWorldModelObjectPlacementInfo.Signature) { this.WorldModelObjectPlacementInfo = br.ReadIFFChunk<TerrainWorldModelObjectPlacementInfo>(); } this.MapAreaOffsets = br.ReadIFFChunk<WorldLODMapAreaOffsets>(); // Read the map areas and their holes for (int y = 0; y < 64; ++y) { for (int x = 0; x < 64; ++x) { int mapAreaOffsetIndex = (y * 64) + x; uint mapAreaOffset = this.MapAreaOffsets.MapAreaOffsets[mapAreaOffsetIndex]; if (mapAreaOffset > 0) { br.BaseStream.Position = mapAreaOffset; this.MapAreas[mapAreaOffsetIndex] = br.ReadIFFChunk<WorldLODMapArea>(); if (br.PeekChunkSignature() == WorldLODMapAreaHoles.Signature) { this.MapAreaHoles[mapAreaOffsetIndex] = br.ReadIFFChunk<WorldLODMapAreaHoles>(); } else { this.MapAreaHoles[mapAreaOffsetIndex] = WorldLODMapAreaHoles.CreateEmpty(); } } else { this.MapAreas[mapAreaOffsetIndex] = null; this.MapAreaHoles[mapAreaOffsetIndex] = null; } } } } } }