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); }