public bool Deserialize(BinaryStream stream, AssetManager assetManager) { // Header string magic = stream.ReadString(3); Assert.AreEqual(MAGIC, magic, "Chunk header mismatch!"); int lodLevel = Convert.ToInt32(stream.ReadString(1)); Assert.AreNotEqual(0, lodLevel, "Use the CNK0 serializer for LOD0 terrain chunks."); Version = stream.ReadUInt32(); if (!Enum.IsDefined(typeof(ChunkType), (int)Version)) { Debug.LogWarning("Could not decode chunk " + Name + ". Unknown cnk version " + Version); return(false); } ChunkType = (ChunkType)Version; DecompressedSize = stream.ReadUInt32(); CompressedSize = stream.ReadUInt32(); // Read the compressed buffer. stream.ReadBytes(CompressedBuffer, (int)CompressedSize); // Decompression // Make sure our buffer is large enough. DecompressedBuffer.PrepareBuffer((int)DecompressedSize); // Perform decompression using Lzham. InflateReturnCode result = LzhamInterop.DecompressForgelightData(CompressedBuffer.Data, CompressedSize, DecompressedBuffer.Data, DecompressedSize); if (result != InflateReturnCode.LZHAM_Z_STREAM_END && result != InflateReturnCode.LZHAM_Z_OK) { //This chunk is invalid, or something went wrong. return(false); } using (MemoryStream decompressedStream = new MemoryStream(DecompressedBuffer.Data, 0, (int)DecompressedSize)) { //Textures uint textureCount = decompressedStream.ReadUInt32(); Textures.PrepareBuffer((int)textureCount); for (int i = 0; i < textureCount; i++) { Texture texture = Textures[i]; if (texture == null) { texture = new Texture(); Textures[i] = texture; } uint colorNxMapSize = decompressedStream.ReadUInt32(); texture.ColorNXMap = assetManager.CreateAsset <Dds>(decompressedStream.ReadBytes((int)colorNxMapSize)); uint specNyMapSize = decompressedStream.ReadUInt32(); texture.SpecNyMap = assetManager.CreateAsset <Dds>(decompressedStream.ReadBytes((int)specNyMapSize)); uint extraData1Size = decompressedStream.ReadUInt32(); decompressedStream.ReadBytes(texture.ExtraData1, (int)extraData1Size); uint extraData2Size = decompressedStream.ReadUInt32(); decompressedStream.ReadBytes(texture.ExtraData2, (int)extraData2Size); uint extraData3Size = decompressedStream.ReadUInt32(); decompressedStream.ReadBytes(texture.ExtraData3, (int)extraData3Size); uint extraData4Size = decompressedStream.ReadUInt32(); decompressedStream.ReadBytes(texture.ExtraData4, (int)extraData4Size); } //Verts Per Side VertsPerSide = decompressedStream.ReadUInt32(); //Height Maps uint heightMapCount = decompressedStream.ReadUInt32(); int n = (int)(heightMapCount / 4); for (int i = 0; i < 4; i++) { for (int j = 0; j < n; j++) { Dictionary <int, HeightMap> entry; if (!HeightMaps.ContainsKey(i)) { entry = new Dictionary <int, HeightMap>(); HeightMaps[i] = entry; } else { entry = HeightMaps[i]; } HeightMap heightMapData = new HeightMap(); heightMapData.Val1 = decompressedStream.ReadInt16(); heightMapData.Val2 = decompressedStream.Read1Byte(); heightMapData.Val3 = decompressedStream.Read1Byte(); entry[j] = heightMapData; } } //Indices uint indexCount = decompressedStream.ReadUInt32(); for (int i = 0; i < indexCount; i++) { Indices.Add(decompressedStream.ReadUInt16()); } //Verts uint vertCount = decompressedStream.ReadUInt32(); for (int i = 0; i < vertCount; i++) { Vertex vertex = new Vertex(); vertex.X = decompressedStream.ReadInt16(); vertex.Y = decompressedStream.ReadInt16(); vertex.HeightFar = decompressedStream.ReadInt16(); vertex.HeightNear = decompressedStream.ReadInt16(); vertex.Color = decompressedStream.ReadUInt32(); Vertices.Add(vertex); } //TODO HACK - Daybreak, why are some chunks (that have a version 2 header) actually version 1? long offset = decompressedStream.Position; try { //Render Batches uint renderBatchCount = decompressedStream.ReadUInt32(); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); if (ChunkType == ChunkType.H1Z1_Planetside2V2) { renderBatch.Unknown = decompressedStream.ReadUInt32(); } renderBatch.IndexOffset = decompressedStream.ReadUInt32(); renderBatch.IndexCount = decompressedStream.ReadUInt32(); renderBatch.VertexOffset = decompressedStream.ReadUInt32(); renderBatch.VertexCount = decompressedStream.ReadUInt32(); RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = decompressedStream.ReadUInt32(); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = decompressedStream.ReadBytes(320).ToList(); OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = decompressedStream.ReadUInt32(); for (int i = 0; i < unknownShort1Count; i++) { UnknownShorts1.Add(decompressedStream.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = decompressedStream.ReadUInt32(); for (int i = 0; i < unknownVectors1Count; i++) { UnknownVectors1.Add(new Vector3(decompressedStream.ReadSingle(), decompressedStream.ReadSingle(), decompressedStream.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = decompressedStream.ReadUInt32(); if (tileOccluderCount > 16) { throw new ArgumentOutOfRangeException(); } for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = decompressedStream.ReadBytes(64).ToList(); TileOccluderInfos.Add(tileOccluderInfo); } } catch (Exception) { // Some of these may have been populated from the "try". RenderBatches.Clear(); OptimizedDraws.Clear(); UnknownShorts1.Clear(); UnknownVectors1.Clear(); TileOccluderInfos.Clear(); decompressedStream.Position = offset; //Render Batches uint renderBatchCount = decompressedStream.ReadUInt32(); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); renderBatch.IndexOffset = decompressedStream.ReadUInt32(); renderBatch.IndexCount = decompressedStream.ReadUInt32(); renderBatch.VertexOffset = decompressedStream.ReadUInt32(); renderBatch.VertexCount = decompressedStream.ReadUInt32(); RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = decompressedStream.ReadUInt32(); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = decompressedStream.ReadBytes(320).ToList(); OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = decompressedStream.ReadUInt32(); for (int i = 0; i < unknownShort1Count; i++) { UnknownShorts1.Add(decompressedStream.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = decompressedStream.ReadUInt32(); for (int i = 0; i < unknownVectors1Count; i++) { UnknownVectors1.Add(new Vector3(decompressedStream.ReadSingle(), decompressedStream.ReadSingle(), decompressedStream.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = decompressedStream.ReadUInt32(); if (tileOccluderCount > 16) { return(false); } for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = decompressedStream.ReadBytes(64).ToList(); TileOccluderInfos.Add(tileOccluderInfo); } } } return(true); }
public bool InitializeFromStream(string name, string displayName, MemoryStream stream) { using (BinaryReader binaryReader = new BinaryReader(stream)) { Name = name; DisplayName = displayName; //Header byte[] magic = binaryReader.ReadBytes(4); if (magic[0] != 'C' || magic[1] != 'N' || magic[2] != 'K' /* || * magic[3] != '1'*/) { return(false); } Version = binaryReader.ReadUInt32(); if (!Enum.IsDefined(typeof(ChunkType), (int)Version)) { Debug.LogWarning("Could not decode chunk " + name + ". Unknown cnk version " + Version); return(false); } ChunkType = (ChunkType)Version; DecompressedSize = binaryReader.ReadUInt32(); CompressedSize = binaryReader.ReadUInt32(); // Decompression // Make sure our buffers are large enough. if (CompressedBuffer.Length < CompressedSize) { Array.Resize(ref CompressedBuffer, (int)CompressedSize); } if (DecompressedBuffer.Length < DecompressedSize) { Array.Resize(ref DecompressedBuffer, (int)DecompressedSize); } // Read the compressed buffer. binaryReader.Read(CompressedBuffer, 0, (int)CompressedSize); // Perform decompression using Lzham. InflateReturnCode result = LzhamInterop.DecompressForgelightData(CompressedBuffer, CompressedSize, DecompressedBuffer, DecompressedSize); if (result != InflateReturnCode.LZHAM_Z_STREAM_END && result != InflateReturnCode.LZHAM_Z_OK) { //This chunk is invalid, or something went wrong. return(false); } } using (MemoryStream decompressedStream = new MemoryStream(DecompressedBuffer, 0, (int)DecompressedSize)) { using (BinaryReader binaryReader = new BinaryReader(decompressedStream)) { //Textures uint textureCount = binaryReader.ReadUInt32(); for (int i = 0; i < textureCount; i++) { Texture texture = new Texture(); uint colorNxMapSize = binaryReader.ReadUInt32(); if (colorNxMapSize > 0) { texture.ColorNXMap = binaryReader.ReadBytes((int)colorNxMapSize).ToList(); } uint specNyMapSize = binaryReader.ReadUInt32(); if (specNyMapSize > 0) { texture.SpecNyMap = binaryReader.ReadBytes((int)specNyMapSize).ToList(); } uint extraData1Size = binaryReader.ReadUInt32(); if (extraData1Size > 0) { texture.ExtraData1 = binaryReader.ReadBytes((int)extraData1Size).ToList(); } uint extraData2Size = binaryReader.ReadUInt32(); if (extraData2Size > 0) { texture.ExtraData2 = binaryReader.ReadBytes((int)extraData2Size).ToList(); } uint extraData3Size = binaryReader.ReadUInt32(); if (extraData3Size > 0) { texture.ExtraData3 = binaryReader.ReadBytes((int)extraData3Size).ToList(); } uint extraData4Size = binaryReader.ReadUInt32(); if (extraData4Size > 0) { texture.ExtraData4 = binaryReader.ReadBytes((int)extraData4Size).ToList(); } Textures.Add(texture); } //Verts Per Side VertsPerSide = binaryReader.ReadUInt32(); //Height Maps uint heightMapCount = binaryReader.ReadUInt32(); int n = (int)(heightMapCount / 4); for (int i = 0; i < 4; i++) { for (int j = 0; j < n; j++) { Dictionary <int, HeightMap> entry; if (!HeightMaps.ContainsKey(i)) { entry = new Dictionary <int, HeightMap>(); HeightMaps[i] = entry; } else { entry = HeightMaps[i]; } HeightMap heightMapData = new HeightMap(); heightMapData.Val1 = binaryReader.ReadInt16(); heightMapData.Val2 = binaryReader.ReadByte(); heightMapData.Val3 = binaryReader.ReadByte(); entry[j] = heightMapData; } } //Indices uint indexCount = binaryReader.ReadUInt32(); for (int i = 0; i < indexCount; i++) { Indices.Add(binaryReader.ReadUInt16()); } //Verts uint vertCount = binaryReader.ReadUInt32(); for (int i = 0; i < vertCount; i++) { Vertex vertex = new Vertex(); vertex.X = binaryReader.ReadInt16(); vertex.Y = binaryReader.ReadInt16(); vertex.HeightFar = binaryReader.ReadInt16(); vertex.HeightNear = binaryReader.ReadInt16(); vertex.Color = binaryReader.ReadUInt32(); Vertices.Add(vertex); } //TODO HACK - Daybreak, why are some chunks (that have a version 2 header) actually version 1? long offset = binaryReader.BaseStream.Position; try { //Render Batches uint renderBatchCount = binaryReader.ReadUInt32(); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); if (ChunkType == ChunkType.H1Z1_Planetside2V2) { renderBatch.Unknown = binaryReader.ReadUInt32(); } renderBatch.IndexOffset = binaryReader.ReadUInt32(); renderBatch.IndexCount = binaryReader.ReadUInt32(); renderBatch.VertexOffset = binaryReader.ReadUInt32(); renderBatch.VertexCount = binaryReader.ReadUInt32(); RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = binaryReader.ReadUInt32(); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = binaryReader.ReadBytes(320).ToList(); OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = binaryReader.ReadUInt32(); for (int i = 0; i < unknownShort1Count; i++) { UnknownShorts1.Add(binaryReader.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = binaryReader.ReadUInt32(); for (int i = 0; i < unknownVectors1Count; i++) { UnknownVectors1.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = binaryReader.ReadUInt32(); if (tileOccluderCount > 16) { throw new ArgumentOutOfRangeException(); } for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = binaryReader.ReadBytes(64).ToList(); TileOccluderInfos.Add(tileOccluderInfo); } } catch (Exception) { // Some of these may have been populated from the "try". RenderBatches.Clear(); OptimizedDraws.Clear(); UnknownShorts1.Clear(); UnknownVectors1.Clear(); TileOccluderInfos.Clear(); binaryReader.BaseStream.Position = offset; //Render Batches uint renderBatchCount = binaryReader.ReadUInt32(); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); renderBatch.IndexOffset = binaryReader.ReadUInt32(); renderBatch.IndexCount = binaryReader.ReadUInt32(); renderBatch.VertexOffset = binaryReader.ReadUInt32(); renderBatch.VertexCount = binaryReader.ReadUInt32(); RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = binaryReader.ReadUInt32(); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = binaryReader.ReadBytes(320).ToList(); OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = binaryReader.ReadUInt32(); for (int i = 0; i < unknownShort1Count; i++) { UnknownShorts1.Add(binaryReader.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = binaryReader.ReadUInt32(); for (int i = 0; i < unknownVectors1Count; i++) { UnknownVectors1.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = binaryReader.ReadUInt32(); if (tileOccluderCount > 16) { return(false); } for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = binaryReader.ReadBytes(64).ToList(); TileOccluderInfos.Add(tileOccluderInfo); } } } } return(true); }
public static Cnk0 LoadFromStream(string name, string displayName, MemoryStream stream) { Cnk0 chunk = new Cnk0(); BinaryReader binaryReader = new BinaryReader(stream); chunk.Name = name; chunk.DisplayName = displayName; //Header byte[] magic = binaryReader.ReadBytes(4); if (magic[0] != 'C' || magic[1] != 'N' || magic[2] != 'K' || magic[3] != '0') { return(null); } chunk.Version = binaryReader.ReadUInt32(); if (!Enum.IsDefined(typeof(ChunkType), (int)chunk.Version)) { Debug.LogWarning("Could not decode chunk " + name + ". Unknown cnk version " + chunk.Version); return(null); } chunk.ChunkType = (ChunkType)chunk.Version; chunk.DecompressedSize = binaryReader.ReadUInt32(); chunk.CompressedSize = binaryReader.ReadUInt32(); //Decompression byte[] compressedBuffer = binaryReader.ReadBytes((int)chunk.CompressedSize); byte[] decompressedBuffer = new byte[chunk.DecompressedSize]; InflateReturnCode result = LzhamInterop.DecompressForgelightData(compressedBuffer, chunk.CompressedSize, decompressedBuffer, chunk.DecompressedSize); if (result != InflateReturnCode.LZHAM_Z_STREAM_END && result != InflateReturnCode.LZHAM_Z_OK) { //This chunk is invalid. return(null); } using (MemoryStream decompressedStream = new MemoryStream(decompressedBuffer)) { binaryReader = new BinaryReader(decompressedStream); //Tiles uint tileCount = binaryReader.ReadUInt32(); chunk.Tiles = new List <Tile>((int)tileCount); for (int i = 0; i < tileCount; i++) { Tile tile = new Tile(); tile.X = binaryReader.ReadInt32(); tile.Y = binaryReader.ReadInt32(); tile.UnknownInt1 = binaryReader.ReadInt32(); tile.UnknownInt2 = binaryReader.ReadInt32(); uint ecosCount = binaryReader.ReadUInt32(); if (ecosCount > 0) { tile.Ecos = new List <Tile.Eco>((int)ecosCount); for (int j = 0; j < ecosCount; j++) { Tile.Eco eco = new Tile.Eco(); eco.ID = binaryReader.ReadUInt32(); uint florasCount = binaryReader.ReadUInt32(); eco.Floras = new List <Tile.Eco.Flora>((int)florasCount); for (int k = 0; k < florasCount; k++) { Tile.Eco.Flora flora = new Tile.Eco.Flora(); uint layersCount = binaryReader.ReadUInt32(); flora.Layers = new List <Tile.Eco.Flora.Layer>((int)layersCount); for (int l = 0; l < layersCount; l++) { Tile.Eco.Flora.Layer layer = new Tile.Eco.Flora.Layer(); layer.UnknownUint1 = binaryReader.ReadUInt32(); layer.UnknownUint2 = binaryReader.ReadUInt32(); flora.Layers.Add(layer); } eco.Floras.Add(flora); } tile.Ecos.Add(eco); } } tile.Index = binaryReader.ReadUInt32(); tile.UnknownInt3 = binaryReader.ReadUInt32(); uint imageSize = binaryReader.ReadUInt32(); if (imageSize > 0) { tile.ImageData = binaryReader.ReadBytes((int)imageSize).ToList(); } uint layerTexturesCount = binaryReader.ReadUInt32(); if (layerTexturesCount > 0) { tile.LayerTextures = binaryReader.ReadBytes((int)layerTexturesCount).ToList(); } chunk.Tiles.Add(tile); } //Unknown Data chunk.UnknownInt1 = binaryReader.ReadInt32(); uint unknownCount = binaryReader.ReadUInt32(); chunk.UnknownArray1 = new List <Unknown1>((int)unknownCount); for (int i = 0; i < unknownCount; i++) { Unknown1 unknown1 = new Unknown1(); unknown1.Height = binaryReader.ReadInt16(); unknown1.UnknownByte1 = binaryReader.ReadByte(); unknown1.UnknownByte2 = binaryReader.ReadByte(); chunk.UnknownArray1.Add(unknown1); } //Indices uint indexCount = binaryReader.ReadUInt32(); chunk.Indices = new List <ushort>((int)indexCount); for (int i = 0; i < indexCount; i++) { chunk.Indices.Add(binaryReader.ReadUInt16()); } //Verts uint vertCount = binaryReader.ReadUInt32(); chunk.Vertices = new List <Vertex>((int)vertCount); for (int i = 0; i < vertCount; i++) { Vertex vertex = new Vertex(); vertex.X = binaryReader.ReadInt16(); vertex.Y = binaryReader.ReadInt16(); vertex.HeightFar = binaryReader.ReadInt16(); vertex.HeightNear = binaryReader.ReadInt16(); vertex.Color1 = binaryReader.ReadUInt32(); vertex.Color2 = binaryReader.ReadUInt32(); chunk.Vertices.Add(vertex); } //TODO HACK - Daybreak, why are some chunks (that have a version 2 header) actually version 1? long offset = binaryReader.BaseStream.Position; try { //Render Batches uint renderBatchCount = binaryReader.ReadUInt32(); chunk.RenderBatches = new List <RenderBatch>((int)renderBatchCount); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); if (chunk.ChunkType == ChunkType.H1Z1_Planetside2V2) { renderBatch.Unknown = binaryReader.ReadUInt32(); } renderBatch.IndexOffset = binaryReader.ReadUInt32(); renderBatch.IndexCount = binaryReader.ReadUInt32(); renderBatch.VertexOffset = binaryReader.ReadUInt32(); renderBatch.VertexCount = binaryReader.ReadUInt32(); chunk.RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = binaryReader.ReadUInt32(); chunk.OptimizedDraws = new List <OptimizedDraw>((int)optimizedDrawCount); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = binaryReader.ReadBytes(320).ToList(); chunk.OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = binaryReader.ReadUInt32(); chunk.UnknownShorts1 = new List <ushort>((int)unknownShort1Count); for (int i = 0; i < unknownShort1Count; i++) { chunk.UnknownShorts1.Add(binaryReader.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = binaryReader.ReadUInt32(); chunk.UnknownVectors1 = new List <Vector3>((int)unknownVectors1Count); for (int i = 0; i < unknownVectors1Count; i++) { chunk.UnknownVectors1.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = binaryReader.ReadUInt32(); chunk.TileOccluderInfos = new List <TileOccluderInfo>((int)tileOccluderCount); for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = binaryReader.ReadBytes(64).ToList(); chunk.TileOccluderInfos.Add(tileOccluderInfo); } } catch (EndOfStreamException) { binaryReader.BaseStream.Position = offset; //Render Batches uint renderBatchCount = binaryReader.ReadUInt32(); chunk.RenderBatches = new List <RenderBatch>((int)renderBatchCount); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); renderBatch.IndexOffset = binaryReader.ReadUInt32(); renderBatch.IndexCount = binaryReader.ReadUInt32(); renderBatch.VertexOffset = binaryReader.ReadUInt32(); renderBatch.VertexCount = binaryReader.ReadUInt32(); chunk.RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = binaryReader.ReadUInt32(); chunk.OptimizedDraws = new List <OptimizedDraw>((int)optimizedDrawCount); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = binaryReader.ReadBytes(320).ToList(); chunk.OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = binaryReader.ReadUInt32(); chunk.UnknownShorts1 = new List <ushort>((int)unknownShort1Count); for (int i = 0; i < unknownShort1Count; i++) { chunk.UnknownShorts1.Add(binaryReader.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = binaryReader.ReadUInt32(); chunk.UnknownVectors1 = new List <Vector3>((int)unknownVectors1Count); for (int i = 0; i < unknownVectors1Count; i++) { chunk.UnknownVectors1.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = binaryReader.ReadUInt32(); chunk.TileOccluderInfos = new List <TileOccluderInfo>((int)tileOccluderCount); for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = binaryReader.ReadBytes(64).ToList(); chunk.TileOccluderInfos.Add(tileOccluderInfo); } } } return(chunk); }
public static CnkLOD LoadFromStream(string name, string displayName, MemoryStream stream) { CnkLOD chunk = new CnkLOD(); BinaryReader binaryReader = new BinaryReader(stream); chunk.Name = name; chunk.DisplayName = displayName; //Header byte[] magic = binaryReader.ReadBytes(4); if (magic[0] != 'C' || magic[1] != 'N' || magic[2] != 'K' /* || * magic[3] != '1'*/) { return(null); } chunk.Version = binaryReader.ReadUInt32(); if (!Enum.IsDefined(typeof(ChunkType), (int)chunk.Version)) { Debug.LogWarning("Could not decode chunk " + name + ". Unknown cnk version " + chunk.Version); return(null); } chunk.ChunkType = (ChunkType)chunk.Version; chunk.DecompressedSize = binaryReader.ReadUInt32(); chunk.CompressedSize = binaryReader.ReadUInt32(); //Decompression byte[] compressedBuffer = binaryReader.ReadBytes((int)chunk.CompressedSize); byte[] decompressedBuffer = new byte[chunk.DecompressedSize]; InflateReturnCode result = LzhamInterop.DecompressForgelightData(compressedBuffer, chunk.CompressedSize, decompressedBuffer, chunk.DecompressedSize); if (result != InflateReturnCode.LZHAM_Z_STREAM_END && result != InflateReturnCode.LZHAM_Z_OK) { //This chunk is invalid. return(null); } using (MemoryStream decompressedStream = new MemoryStream(decompressedBuffer)) { binaryReader = new BinaryReader(decompressedStream); //Textures uint textureCount = binaryReader.ReadUInt32(); chunk.Textures = new List <Texture>((int)textureCount); for (int i = 0; i < textureCount; i++) { Texture texture = new Texture(); uint colorNxMapSize = binaryReader.ReadUInt32(); if (colorNxMapSize > 0) { texture.ColorNXMap = binaryReader.ReadBytes((int)colorNxMapSize).ToList(); } uint specNyMapSize = binaryReader.ReadUInt32(); if (specNyMapSize > 0) { texture.SpecNyMap = binaryReader.ReadBytes((int)specNyMapSize).ToList(); } uint extraData1Size = binaryReader.ReadUInt32(); if (extraData1Size > 0) { texture.ExtraData1 = binaryReader.ReadBytes((int)extraData1Size).ToList(); } uint extraData2Size = binaryReader.ReadUInt32(); if (extraData2Size > 0) { texture.ExtraData2 = binaryReader.ReadBytes((int)extraData2Size).ToList(); } uint extraData3Size = binaryReader.ReadUInt32(); if (extraData3Size > 0) { texture.ExtraData3 = binaryReader.ReadBytes((int)extraData3Size).ToList(); } uint extraData4Size = binaryReader.ReadUInt32(); if (extraData4Size > 0) { texture.ExtraData4 = binaryReader.ReadBytes((int)extraData4Size).ToList(); } chunk.Textures.Add(texture); } //Verts Per Side chunk.VertsPerSide = binaryReader.ReadUInt32(); //Height Maps uint heightMapCount = binaryReader.ReadUInt32(); int n = (int)(heightMapCount / 4); for (int i = 0; i < 4; i++) { for (int j = 0; j < n; j++) { Dictionary <int, HeightMap> entry; if (!chunk.HeightMaps.ContainsKey(i)) { entry = new Dictionary <int, HeightMap>(); chunk.HeightMaps[i] = entry; } else { entry = chunk.HeightMaps[i]; } HeightMap heightMapData = new HeightMap(); heightMapData.Val1 = binaryReader.ReadInt16(); heightMapData.Val2 = binaryReader.ReadByte(); heightMapData.Val3 = binaryReader.ReadByte(); entry[j] = heightMapData; } } //Indices uint indexCount = binaryReader.ReadUInt32(); chunk.Indices = new List <ushort>((int)indexCount); for (int i = 0; i < indexCount; i++) { chunk.Indices.Add(binaryReader.ReadUInt16()); } //Verts uint vertCount = binaryReader.ReadUInt32(); chunk.Vertices = new List <Vertex>((int)vertCount); for (int i = 0; i < vertCount; i++) { Vertex vertex = new Vertex(); vertex.X = binaryReader.ReadInt16(); vertex.Y = binaryReader.ReadInt16(); vertex.HeightFar = binaryReader.ReadInt16(); vertex.HeightNear = binaryReader.ReadInt16(); vertex.Color = binaryReader.ReadUInt32(); chunk.Vertices.Add(vertex); } //TODO HACK - Daybreak, why are some chunks (that have a version 2 header) actually version 1? long offset = binaryReader.BaseStream.Position; try { //Render Batches uint renderBatchCount = binaryReader.ReadUInt32(); chunk.RenderBatches = new List <RenderBatch>((int)renderBatchCount); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); if (chunk.ChunkType == ChunkType.H1Z1_Planetside2V2) { renderBatch.Unknown = binaryReader.ReadUInt32(); } renderBatch.IndexOffset = binaryReader.ReadUInt32(); renderBatch.IndexCount = binaryReader.ReadUInt32(); renderBatch.VertexOffset = binaryReader.ReadUInt32(); renderBatch.VertexCount = binaryReader.ReadUInt32(); chunk.RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = binaryReader.ReadUInt32(); chunk.OptimizedDraws = new List <OptimizedDraw>((int)optimizedDrawCount); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = binaryReader.ReadBytes(320).ToList(); chunk.OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = binaryReader.ReadUInt32(); chunk.UnknownShorts1 = new List <ushort>((int)unknownShort1Count); for (int i = 0; i < unknownShort1Count; i++) { chunk.UnknownShorts1.Add(binaryReader.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = binaryReader.ReadUInt32(); chunk.UnknownVectors1 = new List <Vector3>((int)unknownVectors1Count); for (int i = 0; i < unknownVectors1Count; i++) { chunk.UnknownVectors1.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = binaryReader.ReadUInt32(); chunk.TileOccluderInfos = new List <TileOccluderInfo>((int)tileOccluderCount); for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = binaryReader.ReadBytes(64).ToList(); chunk.TileOccluderInfos.Add(tileOccluderInfo); } } catch (Exception) { binaryReader.BaseStream.Position = offset; //Render Batches uint renderBatchCount = binaryReader.ReadUInt32(); chunk.RenderBatches = new List <RenderBatch>((int)renderBatchCount); for (int i = 0; i < renderBatchCount; i++) { RenderBatch renderBatch = new RenderBatch(); renderBatch.IndexOffset = binaryReader.ReadUInt32(); renderBatch.IndexCount = binaryReader.ReadUInt32(); renderBatch.VertexOffset = binaryReader.ReadUInt32(); renderBatch.VertexCount = binaryReader.ReadUInt32(); chunk.RenderBatches.Add(renderBatch); } //Optimized Draw uint optimizedDrawCount = binaryReader.ReadUInt32(); chunk.OptimizedDraws = new List <OptimizedDraw>((int)optimizedDrawCount); for (int i = 0; i < optimizedDrawCount; i++) { OptimizedDraw optimizedDraw = new OptimizedDraw(); optimizedDraw.Data = binaryReader.ReadBytes(320).ToList(); chunk.OptimizedDraws.Add(optimizedDraw); } //Unknown Data uint unknownShort1Count = binaryReader.ReadUInt32(); chunk.UnknownShorts1 = new List <ushort>((int)unknownShort1Count); for (int i = 0; i < unknownShort1Count; i++) { chunk.UnknownShorts1.Add(binaryReader.ReadUInt16()); } //Unknown Data uint unknownVectors1Count = binaryReader.ReadUInt32(); chunk.UnknownVectors1 = new List <Vector3>((int)unknownVectors1Count); for (int i = 0; i < unknownVectors1Count; i++) { chunk.UnknownVectors1.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } //Tile Occluder Info uint tileOccluderCount = binaryReader.ReadUInt32(); chunk.TileOccluderInfos = new List <TileOccluderInfo>((int)tileOccluderCount); for (int i = 0; i < tileOccluderCount; i++) { TileOccluderInfo tileOccluderInfo = new TileOccluderInfo(); tileOccluderInfo.Data = binaryReader.ReadBytes(64).ToList(); chunk.TileOccluderInfos.Add(tileOccluderInfo); } } } return(chunk); }