Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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;
                }
            }
        }