public static byte[] ReadFile(FileStream stream) { BinaryReader reader = new BinaryReader(stream); int magic, version; List <CHUNK> chunks = new List <CHUNK>(); magic = reader.ReadInt32(); if (magic != VOX_) { return(null); } version = reader.ReadInt32(); if (version < 150) { Console.WriteLine("format too old! (" + version + ")"); return(null); } else if (version > 150) { Console.WriteLine("format is newer than 150!"); Console.WriteLine("to continue, change the version"); Console.WriteLine("at pos 0x4 to 0x96000000"); return(null); } ParseChunks(reader, chunks); SIZEBlock sb; int sx; int sy; int sz; if (ContainsInstance <SIZEBlock>(chunks)) { sb = GetInstance <SIZEBlock>(chunks); sx = sb.sizeX; sy = sb.sizeY; sz = sb.sizeZ; } else { Console.WriteLine("no size detected! is the file corrupt?"); return(null); } List <RGBABlock.COLORB> colors = new List <RGBABlock.COLORB>(); if (ContainsInstance <RGBABlock>(chunks)) { RGBABlock rgba = GetInstance <RGBABlock>(chunks); for (int i = 0; i < 256; i++) { colors.Add(rgba.colors[i]); } } else { for (int i = 0; i < 256; i++) { RGBABlock.COLORB color = new RGBABlock.COLORB(); color.a = (byte)((DEFAULT_PALETTE[i] & 0xFF000000) >> 24); color.r = (byte)((DEFAULT_PALETTE[i] & 0x00FF0000) >> 16); color.g = (byte)((DEFAULT_PALETTE[i] & 0x0000FF00) >> 8); color.b = (byte)((DEFAULT_PALETTE[i] & 0x000000FF)); colors.Add(color); } } List <byte> usedMaterials = new List <byte>(); if (ContainsInstance <XYZIBlock>(chunks)) { XYZIBlock xyzi = GetInstance <XYZIBlock>(chunks); int voxelCount = sx * sy * sz; for (int i = 0; i < xyzi.voxels.Length; i++) { if (!usedMaterials.Contains(xyzi.voxels[i].m)) { usedMaterials.Add(xyzi.voxels[i].m); } } usedMaterials.Sort(); int voxelDataStart = 4 + (3 * usedMaterials.Count); int dataSize = voxelDataStart + voxelCount; byte[] modelData = new byte[dataSize]; modelData[0] = (byte)sx; modelData[1] = (byte)sy; modelData[2] = (byte)sz; modelData[3] = (byte)usedMaterials.Count; for (int i = 0; i < usedMaterials.Count; i++) { RGBABlock.COLORB color = colors[usedMaterials[i] - 1]; modelData[i * 3 + 4] = color.r; modelData[i * 3 + 5] = color.g; modelData[i * 3 + 6] = color.b; } for (int i = voxelDataStart; i < dataSize; i++) { modelData[i] = 0; } for (int i = 0; i < xyzi.numVoxels; i++) { XYZIBlock.XYZIB xyzib = xyzi.voxels[i]; int x = xyzib.x; int y = xyzib.y; int z = xyzib.z; byte mat = (byte)usedMaterials.FindIndex(m => m == xyzib.m); int index = x + y * sx + z * sx * sy; modelData[voxelDataStart + index] = (byte)(mat + 1); } stream.Close(); return(modelData); } else { Console.WriteLine("no blocks detected! is the file corrupt?"); return(null); } }
private static void ParseChunks(BinaryReader reader, List <CHUNK> chunks) { while (reader.BaseStream.Position < reader.BaseStream.Length) { int block = reader.ReadInt32(); int contentLen = reader.ReadInt32(); int childrenLen = reader.ReadInt32(); switch (block) { case VOX_: Console.WriteLine("should not have encountered \"VOX\" here!"); break; case PACK: PACKBlock pack = new PACKBlock(); pack.id = block; pack.contentLen = contentLen; pack.childrenLen = childrenLen; pack.numModels = reader.ReadInt32(); chunks.Add(pack); break; case SIZE: SIZEBlock size = new SIZEBlock(); size.id = block; size.contentLen = contentLen; size.childrenLen = childrenLen; size.sizeX = reader.ReadInt32(); size.sizeY = reader.ReadInt32(); size.sizeZ = reader.ReadInt32(); chunks.Add(size); break; case XYZI: XYZIBlock xyzi = new XYZIBlock(); xyzi.id = block; xyzi.contentLen = contentLen; xyzi.childrenLen = childrenLen; xyzi.numVoxels = reader.ReadInt32(); xyzi.voxels = new XYZIBlock.XYZIB[xyzi.numVoxels]; for (int i = 0; i < xyzi.numVoxels; i++) { xyzi.voxels[i] = new XYZIBlock.XYZIB(); xyzi.voxels[i].x = reader.ReadByte(); xyzi.voxels[i].y = reader.ReadByte(); xyzi.voxels[i].z = reader.ReadByte(); xyzi.voxels[i].m = reader.ReadByte(); } chunks.Add(xyzi); break; case RGBA: RGBABlock rgba = new RGBABlock(); rgba.id = block; rgba.contentLen = contentLen; rgba.childrenLen = childrenLen; rgba.colors = new RGBABlock.COLORB[256]; for (int i = 0; i < 256; i++) { rgba.colors[i] = new RGBABlock.COLORB(); rgba.colors[i].r = reader.ReadByte(); rgba.colors[i].g = reader.ReadByte(); rgba.colors[i].b = reader.ReadByte(); rgba.colors[i].a = reader.ReadByte(); } chunks.Add(rgba); break; default: CHUNK genericChunk = new CHUNK(); genericChunk.id = block; genericChunk.contentLen = contentLen; genericChunk.childrenLen = childrenLen; chunks.Add(genericChunk); break; } } }