Esempio n. 1
0
        /// <summary>
        /// Load a MagicaVoxel .vox format file into the custom ushort[] structure that we use for voxel chunks.
        /// </summary>
        /// <param name="stream">An open BinaryReader stream that is the .vox file.</param>
        /// <param name="overrideColors">Optional color lookup table for converting RGB values into my internal engine color format.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        private static Color32[] FromMagica(BinaryReader stream, out Vector3Int size)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data
            Color32[]         data      = null; // new Color32[32 * 128 * 32]; // new ushort[32 * 128 * 32];
            Color32[]         colors    = null;
            MagicaVoxelData[] voxelData = null;

            string magic = new string(stream.ReadChars(4));

            /*int version = */ stream.ReadInt32(); // never used, just advance stream cursor

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            int sizex = 0, sizey = 0, sizez = 0;

            size = new Vector3Int(0, 0, 0);

            if (magic == "VOX ")
            {
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId   = stream.ReadChars(4);
                    int    chunkSize = stream.ReadInt32();
                    /*int childChunks = */ stream.ReadInt32(); // never used but we should advance the cursor
                    string chunkName = new string(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName == "SIZE")
                    {
                        // in magica voxel z is up.
                        // in voxel play y is up.
                        // swap z and y
                        sizex = stream.ReadInt32();
                        sizez = stream.ReadInt32();
                        sizey = stream.ReadInt32();

                        if (sizex > 32 || sizey > 32)
                        {
                            subsample = true;
                        }

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                        //int div = (subsample ? 2 : 1); //never used

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                        }
                    }
                    else if (chunkName == "RGBA")
                    {
                        colors = new Color32[256];

                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            /*byte a = */ stream.ReadByte(); // never used. advance cursor

                            colors[i] = new Color32(r, g, b, 255);
                        }
                    }
                    else
                    {
                        stream.ReadBytes(chunkSize);    // read any excess bytes
                    }
                }

                data = new Color32[sizex * sizey * sizez];

                if (voxelData.Length == 0)
                {
                    return(data); // failed to read any valid voxel data
                }

                if (sizex == 0 || sizey == 0 || sizez == 0)
                {
                    return(data);
                }

                if (colors == null)
                {
                    Debug.LogWarning("no colors array");
                }
                else
                {
                    Debug.Log("colors len: " + colors.Length);
                }

                // now push the voxel data into our voxel chunk structure
                for (int i = 0; i < voxelData.Length; i++)
                {
                    // do not store this voxel if it lies out of range of the voxel chunk (32x128x32)
                    if (voxelData[i].x > 31 || voxelData[i].y > 127 || voxelData[i].z > 31)
                    {
                        continue;
                    }

                    // use the voxColors array by default, or overrideColor if it is available
                    int voxel = voxelData[i].x + voxelData[i].z * sizex + voxelData[i].y * sizex * sizez;

                    Color32 c;
                    if (colors != null)
                    {
                        c = colors[voxelData[i].color - 1];
                    }
                    else
                    {
                        c = FromUShortColor(voxColors[voxelData[i].color - 1]);
                    }
                    data[voxel] = c;
                }
            }

            size = new Vector3Int(sizex, sizey, sizez);
            return(data);
        }
Esempio n. 2
0
        /// <summary>
        /// Load a MagicaVoxel .vox format file into the custom ushort[] structure that we use for voxel chunks.
        /// </summary>
        /// <param name="stream">An open BinaryReader stream that is the .vox file.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        public static Result ReadFile(BinaryReader stream)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data
            ushort[] data         = new ushort[32 * 128 * 32];
            Color[]  colors       = null;
            Result   resultObject = new Result();

            MagicaVoxelData[] voxelData = null;

            string magic   = new string(stream.ReadChars(4));
            int    version = stream.ReadInt32();

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId     = stream.ReadChars(4);
                    int    chunkSize   = stream.ReadInt32();
                    int    childChunks = stream.ReadInt32();
                    string chunkName   = new string(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName == "SIZE")
                    {
                        resultObject.sizeX = stream.ReadInt32();
                        resultObject.sizeY = stream.ReadInt32();
                        resultObject.sizeZ = stream.ReadInt32();


                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream);
                        }
                    }
                    else if (chunkName == "RGBA")
                    {
                        colors = new Color[256];

                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            //Store custom color palette
                            colors[i] = new Color(r / 255f, g / 255f, b / 255f, a);
                        }
                    }
                    else
                    {
                        stream.ReadBytes(chunkSize);    // read any excess bytes
                    }
                }
                if (voxelData.Length == 0)
                {
                    return(resultObject);
                }
                resultObject.voxels = new VoxelData[voxelData.Length];
                for (int i = 0; i < voxelData.Length; i++)
                {
                    resultObject.voxels[i] = new VoxelData(voxelData[i].x, voxelData[i].y, voxelData[i].z, colors == null ? getColor(defaultPallet[voxelData[i].color]) : colors[voxelData[i].color - 1]);
                }
            }

            return(resultObject);
        }
Esempio n. 3
0
        /// <summary>
        /// Load a MagicaVoxel .vox format file into the custom ushort[] structure that we use for voxel chunks.
        /// </summary>
        /// <param name="stream">An open BinaryReader stream that is the .vox file.</param>
        /// <param name="overrideColors">Optional color lookup table for converting RGB values into my internal engine color format.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        private static Color32[] FromMagica(BinaryReader stream)
        {
            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            string magic = new string(stream.ReadChars(4));

            if (magic != "VOX ")
            {
                return(null);
            }

            int version = stream.ReadInt32();

            if (version != 150)
            {
                Debug.LogWarning("Vox file version does not match 150. Issues possible.");
            }

            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data
            Color32[]         data      = new Color32[SizeX * SizeY * SizeZ];
            Color32[]         colors    = null;
            MagicaVoxelData[] voxelData = null;

            bool subsample = false;

            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                // each chunk has an ID, size and child chunks
                char[] chunkId     = stream.ReadChars(4);
                int    chunkSize   = stream.ReadInt32();
                int    childChunks = stream.ReadInt32();
                if (childChunks < 0)
                {
                    Debug.LogError("childChunks < 0");
                    return(null);
                }

                string chunkName = new string(chunkId);
                switch (chunkName)
                {
                // Chunk dimensions
                case "SIZE":
                {
                    int sizeX = stream.ReadInt32();
                    int sizeY = stream.ReadInt32();
                    int sizeZ = stream.ReadInt32();

                    if (sizeX > SizeX || sizeZ > SizeZ || sizeY > SizeY)
                    {
                        subsample = true;
                    }

                    stream.ReadBytes(chunkSize - 4 * 3);
                    break;
                }

                // Voxel data
                case "XYZI":
                {
                    // XYZI contains n voxels
                    int numVoxels = stream.ReadInt32();
                    if (numVoxels <= 0)
                    {
                        return(null);
                    }

                    //int div = (subsample ? 2 : 1);

                    // Each voxel has x, y, z and color index values
                    voxelData = new MagicaVoxelData[numVoxels];
                    for (int i = 0; i < voxelData.Length; i++)
                    {
                        voxelData[i] = new MagicaVoxelData(stream, subsample);
                    }

                    break;
                }

                case "RGBA":
                {
                    colors = new Color32[256];
                    for (int i = 0; i < 256; i++)
                    {
                        byte r = stream.ReadByte();
                        byte g = stream.ReadByte();
                        byte b = stream.ReadByte();
                        byte a = stream.ReadByte();

                        // Convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                        colors[i] = new Color32(r, g, b, a);
                        //(ushort) (((r & 0x1f) << 10) | ((g & 0x1f) << 5) | (b & 0x1f));
                    }

                    break;
                }

                default:
                    // Read any excess bytes
                    stream.ReadBytes(chunkSize);
                    break;
                }
            }

            // Failed to read any valid voxel data
            if (voxelData == null || voxelData.Length == 0)
            {
                return(null);
            }

            // Push the voxel data into our voxel chunk structure
            for (int i = 0; i < voxelData.Length; i++)
            {
                // Do not store this voxel if it lies out of range of the voxel chunk (32x128x32)
                if (voxelData[i].X >= SizeX || voxelData[i].Y >= SizeY || voxelData[i].Z >= SizeZ)
                {
                    continue;
                }

                // Use the voxColors array by default, or overrideColor if it is available
                int voxel = (voxelData[i].X + (voxelData[i].Z << LogX) + (voxelData[i].Y << LogY << LogZ));
                if (colors == null)
                {
                    uint col = SVoxColors[voxelData[i].Color - 1];
                    data[voxel] = new Color32((byte)((col >> 16) & 0xFf), (byte)((col >> 8) & 0xFf), (byte)(col & 0xFf), 0xFf);
                }
                else
                {
                    data[voxel] = colors[voxelData[i].Color - 1];
                }
            }

            return(data);
        }
        /// <summary>
        /// Load a MagicaVoxel .vox format file into the custom ushort[] structure that we use for voxel chunks.
        /// </summary>
        /// <param name="stream">An open BinaryReader stream that is the .vox file.</param>
        /// <param name="overrideColors">Optional color lookup table for converting RGB values into my internal engine color format.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        private static byte[] LoadFromStream(BinaryReader stream)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below

            // Initialize null byte
            byte[]            data      = new byte[1];
            uint[]            colors    = null;
            MagicaVoxelData[] voxelData = null;

            // Initialize min and max bounding box extents
            int[] extents = new int[6] {
                256, 256, 256, 0, 0, 0
            };

            string magic     = new string(stream.ReadChars(4));
            int    version   = stream.ReadInt32();
            int    numVoxels = 0;

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                int  sizex = 0, sizey = 0, sizez = 0;
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId     = stream.ReadChars(4);
                    int    chunkSize   = stream.ReadInt32();
                    int    childChunks = stream.ReadInt32();
                    string chunkName   = new string(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName == "SIZE")
                    {
                        sizex = stream.ReadInt32();
                        sizey = stream.ReadInt32();
                        sizez = stream.ReadInt32();

                        if (sizex > 32 || sizey > 32)
                        {
                            subsample = true;
                        }

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        numVoxels = stream.ReadInt32();

                        int div = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];

                        // Set up data array. First 768 bytes are for the color palette
                        // Last 6 bytes are for model bounds
                        data = new byte[numVoxels * 4 + colorPaletteSize * 3 + 6];

                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                        }
                    }
                    else if (chunkName == "RGBA")
                    {
                        colors = new uint[colorPaletteSize];

                        for (int i = 0; i < colorPaletteSize; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            // convert RGBA to 24-bit RGB
                            colors[i] = (uint)((r << 16) | (g << 8) | b);
                        }
                    }
                    else
                    {
                        stream.ReadBytes(chunkSize);    // read any excess bytes
                    }
                }

                if (voxelData.Length == 0)
                {
                    return(data);                       // failed to read any valid voxel data
                }
                // Copy color palette into data array
                for (int i = 0; i < colors.Length; i++)
                {
                    data[i * 3]     = (byte)(colors[i] >> 16);
                    data[i * 3 + 1] = (byte)(colors[i] >> 8);
                    data[i * 3 + 2] = (byte)(colors[i]);
                }

                int offset = 0;

                // now push the voxel data into our voxel chunk structure
                for (int i = 0; i < voxelData.Length; i++)
                {
                    // do not store this voxel if it lies out of range of the voxel chunk (32x128x32)
                    if (voxelData[i].x > 31 || voxelData[i].y > 31 || voxelData[i].z > 127)
                    {
                        continue;
                    }

                    offset = (colorPaletteSize * 3) + (i * 4);

                    data[offset + 1] = (byte)voxelData[i].y;
                    data[offset + 2] = (byte)voxelData[i].x;
                    data[offset + 3] = (byte)voxelData[i].z;
                    data[offset]     = (byte)(voxelData[i].color - 1);

                    // Update extents metadata
                    extents[0] = (voxelData[i].y < extents[0]) ? voxelData[i].y : extents[0];
                    extents[1] = (voxelData[i].x < extents[1]) ? voxelData[i].x : extents[1];
                    extents[2] = (voxelData[i].z < extents[2]) ? voxelData[i].z : extents[2];

                    extents[3] = (voxelData[i].y > extents[3]) ? voxelData[i].y : extents[3];
                    extents[4] = (voxelData[i].x > extents[4]) ? voxelData[i].x : extents[4];
                    extents[5] = (voxelData[i].z > extents[5]) ? voxelData[i].z : extents[5];
                }

                // Add extents metadata
                offset = (numVoxels * 4) + (colorPaletteSize * 3);

                for (int i = 0; i < 6; i++)
                {
                    data[offset + i] = (byte)(extents[i] + 1);
                }
            }

            return(data);
        }
Esempio n. 5
0
    public static Chunk LoadModel(string filename, string type)
    {
        BinaryReader stream = new BinaryReader(File.Open(filename, FileMode.Open));

        int[]             colors    = null;
        MagicaVoxelData[] voxelData = null;

        string magic = new string(stream.ReadChars(4));
        int    version = stream.ReadInt32();
        int    sizex = 0, sizey = 0, sizez = 0;

        if (magic == "VOX ")
        {
            bool subsample = false;
            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                // each chunk has an ID, size and child chunks
                char[] chunkId     = stream.ReadChars(4);
                int    chunkSize   = stream.ReadInt32();
                int    childChunks = stream.ReadInt32();
                string chunkName   = new string(chunkId);

                // there are only 2 chunks we only care about, and they are SIZE and XYZI
                if (chunkName == "SIZE")
                {
                    sizex = stream.ReadInt32();
                    sizey = stream.ReadInt32();
                    sizez = stream.ReadInt32();
                    //if (sizex > 32 || sizey > 32) subsample = true;

                    stream.ReadBytes(chunkSize - 4 * 3);
                }
                else if (chunkName == "XYZI")
                {
                    // XYZI contains n voxels
                    int numVoxels = stream.ReadInt32();
                    //	int div = (subsample ? 2 : 1);

                    // each voxel has x, y, z and color index values
                    voxelData = new MagicaVoxelData[numVoxels];
                    for (int i = 0; i < voxelData.Length; i++)
                    {
                        voxelData [i] = new MagicaVoxelData(stream, false);
                    }
                }
                else if (chunkName == "RGBA")
                {
                    colors = new int[256];

                    for (int i = 0; i < 256; i++)
                    {
                        byte r = stream.ReadByte();
                        byte g = stream.ReadByte();
                        byte b = stream.ReadByte();
                        byte a = stream.ReadByte();

                        // convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                        colors[i] = (int)(((r & 0xFF) << 24) | ((g & 0xFF) << 16) | (b & 0xFF) << 8);
                    }
                }
                else
                {
                    stream.ReadBytes(chunkSize);    // read any excess bytes
                }
            }

            if (voxelData.Length == 0)
            {
                return(null);                       // failed to read any valid voxel data
            }
            // now push the voxel data into our voxel chunk structure

            if (type == "map")
            {
                int scale = 3;
                World.width  = (int)(sizex * scale) / World.chunkSize;
                World.height = (int)(sizez * scale) / World.chunkSize;
                World.depth  = (int)(sizey * scale) / World.chunkSize;
                World.CreateChunks();
                int c = 0;
                for (int i = 0; i < voxelData.Length; i++)
                {
                    c++;
                    int col = (colors == null ? voxColors [voxelData [i].color - 1] : colors [voxelData [i].color - 1]);

                    for (int x1 = voxelData[i].x * (scale - 1) + 1; x1 < voxelData[i].x * (scale - 1) + scale; x1++)
                    {
                        for (int z1 = voxelData[i].z * (scale - 1) + 1; z1 < voxelData[i].z * (scale - 1) + scale; z1++)
                        {
                            for (int y1 = voxelData[i].y * (scale - 1) + 1; y1 < voxelData[i].y * (scale - 1) + scale; y1++)
                            {
                                World.blocks [x1, z1, y1] = col;
                            }
                        }
                    }
                }
                World.RebuildDirtyChunks(true);
                return(null);
            }
            else
            {
                Chunk c = new Chunk();
                c.type = Chunk.TYPE_OBJ;
                c.EnableObject(sizex, sizez, sizey);
                for (int i = 0; i < voxelData.Length; i++)
                {
                    int col = (colors == null ? voxColors [voxelData [i].color - 1] : colors [voxelData [i].color - 1]);
                    c.blocks [voxelData [i].x, voxelData [i].z, voxelData [i].y] = col;
                }
                World.RebuildChunks(c);
                stream.Close();
                return(c);
            }
        }
        return(null);
    }
        public async Task ReadMagica(Stream stream)
        {

            int[] colors = null;
            MagicaVoxelData[] voxelData = null;

            String magic = new String(ReadChars(stream, 4));
            int version = ReadInt32(stream);

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic.CompareTo("VOX ") == 0)
            {
                int sizex = 0, sizey = 0, sizez = 0;
                bool subsample = false;

                while (stream.Position < stream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId = ReadChars(stream, 4);
                    int chunkSize = ReadInt32(stream);
                    int childChunks = ReadInt32(stream);
                    String chunkName = new String(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName.CompareTo("SIZE") == 0)
                    {
                        sizex = ReadInt32(stream);
                        sizey = ReadInt32(stream);
                        sizez = ReadInt32(stream);

                        if (sizex > 32 || sizey > 32)
                            subsample = true;


                        stream.Seek(chunkSize - 4 * 3, SeekOrigin.Current);
                    }
                    else if (chunkName.CompareTo("XYZI") == 0)
                    {
                        // XYZI contains n voxels
                        int numVoxels = ReadInt32(stream);
                        int div = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                    }
                    else if (chunkName.CompareTo("RGBA") == 0)
                    {
                        colors = new int[256];

                        for (int i = 0; i < 256; i++)
                        {

                            int r = stream.ReadByte() & 0xff;
                            int g = stream.ReadByte() & 0xff;
                            int b = stream.ReadByte() & 0xff;
                            int a = stream.ReadByte() & 0xff;

                            colors[i] = (a & 0xff) << 24 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff);

                        }
                    }
                    else stream.Seek(chunkSize, SeekOrigin.Current);   // read any excess bytes
                }

                if (voxelData.Length == 0)
                    return;

                // now push the voxel data into our voxel chunk structure
                for (int i = 0; i < voxelData.Length; i++)
                {
                    // do not store this voxel if it lies out of range of the voxel chunk (32x128x32)
                    if (voxelData[i].x > 31 || voxelData[i].y > 31 || voxelData[i].z > 127)
                        continue;

                    int color = 0;

                    if (colors == null) // use default palette
                    {
                        // WTF hardcoded palette is ABGR, doing ABGR => ARGB
                        color = (int)voxColors[voxelData[i].color - 1];
                        int r = color & 0xff;
                        int g = (color >> 8) & 0xff;
                        int b = (color >> 16) & 0xff;
                        int a = (color >> 28) & 0xff;
                        color = a << 28 | r << 16 | g << 8 | b;
                    }
                    else // use palette from file
                    {
                        color = colors[voxelData[i].color - 1];

                    }

                    if (timelapse)
                        await Task.Delay(2);

                    if (BlockConstructed != null)
                    {
                        Vector3 position = new Vector3(voxelData[i].x, voxelData[i].y, voxelData[i].z);
                        BlockConstructed(new Tuple<Vector3, int>(position, color));
                    }
                }
            }
        }
Esempio n. 7
0
        private void LoadVoxFile(string aFileName)
        {
            //I dissabled compiler warning, because we want to load some values from the file even if we would not use it later.
            //I think it is cleaner this way
            #pragma warning disable
            //Prepare Object
            GameObject newGameObject = new GameObject();
            newGameObject.name = "ImportedFromMagicaVoxel";
            VoxelContainer newVoxelContainer = newGameObject.AddComponent <VoxelContainer>();

            //Open File
            BinaryReader br = new BinaryReader(File.OpenRead(aFileName));

            string magic   = new string(br.ReadChars(4));
            int    version = br.ReadInt32();

            if (magic == "VOX ")
            {
                int sizex = 0, sizey = 0, sizez = 0;

                Color[]           colors = null;
                MagicaVoxelData[] voxelData = null;

                while (br.BaseStream.Position < br.BaseStream.Length)
                {
                    char[] chunkId     = br.ReadChars(4);
                    int    chunkSize   = br.ReadInt32();
                    int    childChunks = br.ReadInt32();
                    string chunkName   = new string(chunkId);

                    if (chunkName == "SIZE")
                    {
                        sizex = br.ReadInt32();
                        sizey = br.ReadInt32();
                        sizez = br.ReadInt32();

                        br.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        int numVoxels = br.ReadInt32();

                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(br);
                        }
                    }
                    else if (chunkName == "RGBA")
                    {
                        colors = new Color[256];

                        for (int i = 0; i < 256; i++)
                        {
                            byte r = br.ReadByte();
                            byte g = br.ReadByte();
                            byte b = br.ReadByte();
                            byte a = br.ReadByte();

                            colors[i].r = r / 255f;
                            colors[i].g = g / 255f;
                            colors[i].b = b / 255f;
                            colors[i].a = a / 255f;
                        }
                    }
                    else
                    {
                        br.ReadBytes(chunkSize);
                    }
                }
                if ((voxelData == null) || (voxelData.Length == 0))
                {
                    return;
                }

                for (int i = 0; i < voxelData.Length; i++)
                {
                    Vector3 position = new Vector3(voxelData[i].x, voxelData[i].z, voxelData[i].y);
                    if (!newVoxelContainer.voxels.ContainsKey(position))
                    {
                        Voxel newVoxel = new Voxel();
                        newVoxel.position = position;
                        newVoxel.color    = (colors == null ? UShortToColor(voxColors[voxelData[i].color - 1]) : colors[voxelData[i].color - 1]);
                        newVoxelContainer.AddVoxel(newVoxel, false);
                    }
                }
                newVoxelContainer.UpdateStructure();
                newVoxelContainer.BuildMesh(true, true, true, true);
            }
            else
            {
                Debug.LogError("Error durring vox import. Probably this is not a .vox file.");
                return;
            }
            #pragma warning restore
        }
        public static void FromMagica(BinaryReader stream, GameObject root, float voxelSize, bool centerPivot)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data

            Color32[] colors = new Color32[256];

            for (int i = 1; i < 256; i++)
            {
                uint hexval = defaultColors[i];
                byte cb = (byte)((hexval >> 16) & 0xFF);
                byte cg = (byte)((hexval >> 8) & 0xFF);
                byte cr = (byte)((hexval >> 0) & 0xFF);

                colors[i - 1] = new Color32(cr, cg, cb, 255);
            }

            MagicaVoxelData[] voxelData = null;

            string magic = new string(stream.ReadChars(4));
            //int version = 
            stream.ReadInt32();
            

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                int sizex = 0, sizey = 0, sizez = 0;
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId = stream.ReadChars(4);
                    int chunkSize = stream.ReadInt32();
                    //int childChunks = 
                    stream.ReadInt32();
                    string chunkName = new string(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName == "SIZE")
                    {
                        sizex = stream.ReadInt32();
                        sizez = stream.ReadInt32();
                        sizey = stream.ReadInt32();

                        //if (sizex > 32 || sizey > 32) subsample = true;

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                       // int div = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                    }
                    else if (chunkName == "RGBA")
                    {
                        
                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            // convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                            colors[i] = new Color32(r, g, b, a);
                        }
                    }
                    else stream.ReadBytes(chunkSize);   // read any excess bytes
                }

                if (voxelData.Length == 0) return; // failed to read any valid voxel data

                    
                if (root != null)
                {
                        
                    Volume voxelVolume = root.GetComponent<Volume>();

                    voxelVolume.XSize = sizex;
                    voxelVolume.YSize = sizey;
                    voxelVolume.ZSize = sizez;
                    voxelVolume.Frames[0].XSize = sizex;
                    voxelVolume.Frames[0].YSize = sizey;
                    voxelVolume.Frames[0].ZSize = sizez;
                    voxelVolume.Frames[0].Voxels = new Voxel[sizex * sizey * sizez];
                    for (int i = 0; i < voxelVolume.Frames[0].Voxels.Length; i++) voxelVolume.Frames[0].Voxels[i].Value = 128;
                    voxelVolume.VoxelSize = voxelSize;

                    if (centerPivot)
                    {
                        voxelVolume.Pivot = (new Vector3(voxelVolume.XSize, voxelVolume.YSize, voxelVolume.ZSize) * voxelVolume.VoxelSize) / 2f;
                        voxelVolume.UpdatePivot();
                    }

                    foreach (MagicaVoxelData v in voxelData)
                    {
                        try
                        {
                            voxelVolume.Frames[0].Voxels[v.x + sizex * (v.z + sizey * v.y)] = new Voxel()
                            {
                                State = VoxelState.Active,
                                Color = colors[v.color-1],
                                Value = 128
                            };
                        }
                        catch (Exception)
                        {

                            Debug.Log(v.x + " " + v.y + " " + v.z);
                        }

                    }

                    voxelVolume.CreateChunks();
                    voxelVolume.SaveForSerialize();
                }


            }
        }
Esempio n. 9
0
        private static Bitmap renderH(MagicaVoxelData[] voxels, int facing, int frame, int maxFrames, bool still, bool darkOutline)
        {
            Bitmap bmp = new Bitmap(vwidth * 16, vheight * 16, PixelFormat.Format32bppArgb);

            // Specify a pixel format.
            PixelFormat pxf = PixelFormat.Format32bppArgb;

            // Lock the bitmap's bits.
            Rectangle  rect    = new Rectangle(0, 0, bmp.Width, bmp.Height);
            BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            // int numBytes = bmp.Width * bmp.Height * 3;
            int numBytes = bmpData.Stride * bmp.Height;

            byte[] argbValues = new byte[numBytes];
            argbValues.Fill <byte>(0);
            byte[] shadowValues = new byte[numBytes];
            shadowValues.Fill <byte>(0);
            byte[] outlineColors = new byte[numBytes];
            outlineColors.Fill <byte>(0);
            byte[] outlineValues = new byte[numBytes];
            outlineValues.Fill <byte>(0);
            bool[] barePositions = new bool[numBytes];
            barePositions.Fill <bool>(false);
            int xSize = 16, ySize = 16;

            MagicaVoxelData[] vls = new MagicaVoxelData[voxels.Length];
            switch (facing)
            {
            case 0:
                vls = voxels;
                break;

            case 1:
                for (int i = 0; i < voxels.Length; i++)
                {
                    byte tempX = (byte)(voxels[i].x - (xSize / 2));
                    byte tempY = (byte)(voxels[i].y - (ySize / 2));
                    vls[i].x     = (byte)((tempY) + (ySize / 2));
                    vls[i].y     = (byte)((tempX * -1) + (xSize / 2) - 1);
                    vls[i].z     = voxels[i].z;
                    vls[i].color = voxels[i].color;
                }
                break;

            case 2:
                for (int i = 0; i < voxels.Length; i++)
                {
                    byte tempX = (byte)(voxels[i].x - (xSize / 2));
                    byte tempY = (byte)(voxels[i].y - (ySize / 2));
                    vls[i].x     = (byte)((tempX * -1) + (xSize / 2) - 1);
                    vls[i].y     = (byte)((tempY * -1) + (ySize / 2) - 1);
                    vls[i].z     = voxels[i].z;
                    vls[i].color = voxels[i].color;
                }
                break;

            case 3:
                for (int i = 0; i < voxels.Length; i++)
                {
                    byte tempX = (byte)(voxels[i].x - (xSize / 2));
                    byte tempY = (byte)(voxels[i].y - (ySize / 2));
                    vls[i].x     = (byte)((tempY * -1) + (ySize / 2) - 1);
                    vls[i].y     = (byte)(tempX + (xSize / 2));
                    vls[i].z     = voxels[i].z;
                    vls[i].color = voxels[i].color;
                }
                break;
            }
            int[] xbuffer = new int[numBytes];
            xbuffer.Fill <int>(-999);
            int[] zbuffer = new int[numBytes];
            zbuffer.Fill <int>(-999);


            int jitter = (((frame % 4) % 3) + ((frame % 4) / 3)) * 2;

            if (maxFrames >= 8)
            {
                jitter = ((frame % 8 > 4) ? 4 - ((frame % 8) ^ 4) : frame % 8);
            }

            foreach (MagicaVoxelData vx in vls.OrderByDescending(v => v.x * 40 - v.y + v.z * 40 * 40 - ((VoxelLogic.WithoutShadingK(v.color) == 23) ? 40 * 40 * 40 : 0))) //voxelData[i].x + voxelData[i].z * 32 + voxelData[i].y * 32 * 128
            {
                int  unshaded      = VoxelLogic.WithoutShadingK(vx.color);
                int  current_color = ((255 - vx.color) % 4 == 0) ? (255 - vx.color) / 4 + hcolorcount : ((254 - vx.color) % 4 == 0) ? (253 - clear) / 4 : (253 - vx.color) / 4;
                bool is_shaded     = (unshaded != current_color);
                int  p             = 0;
                if ((255 - vx.color) % 4 != 0 && (253 - vx.color) % 4 != 0)
                {
                    continue;
                }
                if ((255 - vx.color) % 4 != 0 && current_color >= hcolorcount)
                {
                    continue;
                }

                if (unshaded == hcolorcount - 1)
                {
                    for (int j = 0; j < vheight; j++)
                    {
                        for (int i = 0; i < 4 * vwidth; i++)
                        {
                            p = voxelToPixelH16(i, j, vx.x, vx.y, vx.z, current_color, bmpData.Stride, jitter, still);

                            if (shadowValues[p] == 0)
                            {
                                shadowValues[p] = hrendered[current_color][i + j * (vwidth * 4)];
                            }
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < vheight; j++)
                    {
                        for (int i = 0; i < 4 * vwidth; i++)
                        {
                            p = voxelToPixelH16(i, j, vx.x, vx.y, vx.z, current_color, bmpData.Stride, jitter, still);

                            if (argbValues[p] == 0)
                            {
                                zbuffer[p]    = vx.z;
                                xbuffer[p]    = vx.x;
                                argbValues[p] = hrendered[current_color][i + j * (vwidth * 4)];
                                if (outlineColors[p] == 0)
                                {
                                    outlineColors[p] = hrendered[current_color][i + (4 * vwidth * vheight)]; //(argbValues[p] * 1.2 + 2 < 255) ? (byte)(argbValues[p] * 1.2 + 2) : (byte)255;
                                }
                            }
                        }
                    }
                }
            }

            /*
             * for (int i = 3; i < numBytes; i += 4)
             * {
             *  if (argbValues[i] > 255 * waver_alpha)
             *  {
             *      if (i + 4 >= 0 && i + 4 < argbValues.Length && argbValues[i + 4] == 0 && darkOutline && outlineValues[i + 4] == 0) { outlineValues[i + 4] = 255; } else if (i + 4 >= 0 && i + 4 < argbValues.Length && barePositions[i + 4] == false && (zbuffer[i] - 1 > zbuffer[i + 4] || xbuffer[i] - 1 > xbuffer[i + 4]) && outlineValues[i + 4] == 0) { outlineValues[i + 4] = 255; outlineValues[i + 4 - 1] = outlineColors[i - 1]; outlineValues[i + 4 - 2] = outlineColors[i - 2]; outlineValues[i + 4 - 3] = outlineColors[i - 3]; }
             *      if (i - 4 >= 0 && i - 4 < argbValues.Length && argbValues[i - 4] == 0 && darkOutline && outlineValues[i - 4] == 0) { outlineValues[i - 4] = 255; } else if (i - 4 >= 0 && i - 4 < argbValues.Length && barePositions[i - 4] == false && (zbuffer[i] - 1 > zbuffer[i - 4] || xbuffer[i] - 1 > xbuffer[i - 4]) && outlineValues[i - 4] == 0) { outlineValues[i - 4] = 255; outlineValues[i - 4 - 1] = outlineColors[i - 1]; outlineValues[i - 4 - 2] = outlineColors[i - 2]; outlineValues[i - 4 - 3] = outlineColors[i - 3]; }
             *      if (i + bmpData.Stride >= 0 && i + bmpData.Stride < argbValues.Length && argbValues[i + bmpData.Stride] == 0 && darkOutline && outlineValues[i + bmpData.Stride] == 0) { outlineValues[i + bmpData.Stride] = 255; } else if (i + bmpData.Stride >= 0 && i + bmpData.Stride < argbValues.Length && barePositions[i + bmpData.Stride] == false && (zbuffer[i] - 1 > zbuffer[i + bmpData.Stride] || xbuffer[i] - 1 > xbuffer[i + bmpData.Stride]) && outlineValues[i + bmpData.Stride] == 0) { outlineValues[i + bmpData.Stride] = 255; outlineValues[i + bmpData.Stride - 1] = outlineColors[i - 1]; outlineValues[i + bmpData.Stride - 2] = outlineColors[i - 2]; outlineValues[i + bmpData.Stride - 3] = outlineColors[i - 3]; }
             *      if (i - bmpData.Stride >= 0 && i - bmpData.Stride < argbValues.Length && argbValues[i - bmpData.Stride] == 0 && darkOutline && outlineValues[i - bmpData.Stride] == 0) { outlineValues[i - bmpData.Stride] = 255; } else if (i - bmpData.Stride >= 0 && i - bmpData.Stride < argbValues.Length && barePositions[i - bmpData.Stride] == false && (zbuffer[i] - 1 > zbuffer[i - bmpData.Stride] || xbuffer[i] - 1 > xbuffer[i - bmpData.Stride]) && outlineValues[i - bmpData.Stride] == 0) { outlineValues[i - bmpData.Stride] = 255; outlineValues[i - bmpData.Stride - 1] = outlineColors[i - 1]; outlineValues[i - bmpData.Stride - 2] = outlineColors[i - 2]; outlineValues[i - bmpData.Stride - 3] = outlineColors[i - 3]; }
             *  }
             * }
             */
            for (int i = 3; i < numBytes; i += 4)
            {
                if (argbValues[i] > 0)
                {
                    argbValues[i] = 255;
                }

                if (outlineValues[i] == 255)
                {
                    argbValues[i]     = 255;
                    argbValues[i - 1] = outlineValues[i - 1];
                    argbValues[i - 2] = outlineValues[i - 2];
                    argbValues[i - 3] = outlineValues[i - 3];
                }
            }

            for (int s = 3; s < numBytes; s += 4)
            {
                if (shadowValues[s] > 0)
                {
                    if (argbValues[s] == 0)
                    {
                        argbValues[s - 3] = shadowValues[s - 3];
                        argbValues[s - 2] = shadowValues[s - 2];
                        argbValues[s - 1] = shadowValues[s - 1];
                        argbValues[s - 0] = shadowValues[s - 0];
                    }
                }
            }

            /*
             * for (int s = 3; s < numBytes; s += 4)
             * {
             *  if (shadowValues[s] > 0)
             *  {
             *      foreach (int i in new int[]{ s + 4, s - 4, s + bmpData.Stride, s - bmpData.Stride
             *          //, s + bmpData.Stride + 4, s - bmpData.Stride + 4, s + bmpData.Stride - 4, s - bmpData.Stride - 4
             *      })
             *      {
             *          if (i >= 3 && i < argbValues.Length && argbValues[i] == 0)
             *          {
             *              argbValues[i - 3] = (byte)(shadowValues[s - 3] + 50);
             *              argbValues[i - 2] = (byte)(shadowValues[s - 2] + 50);
             *              argbValues[i - 1] = (byte)(shadowValues[s - 1] + 50);
             *              argbValues[i - 0] = shadowValues[s - 0];
             *          }
             *      }
             *  }
             * }*/
            Marshal.Copy(argbValues, 0, ptr, numBytes);

            // Unlock the bits.
            bmp.UnlockBits(bmpData);

            return(bmp);
        }
Esempio n. 10
0
    private static MagicaVoxelData[] FromMagica(BinaryReader stream)
    {
        // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
        // we're going to return a voxel chunk worth of data
        MagicaVoxelData[] voxelData = null;

        string magic = new string(stream.ReadChars(4));
        int version = stream.ReadInt32();

        // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
        if (magic == "VOX ")
        {
            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                // each chunk has an ID, size and child chunks
                char[] chunkId = stream.ReadChars(4);
                int chunkSize = stream.ReadInt32();
                int childChunks = stream.ReadInt32();
                string chunkName = new string(chunkId);

                // there are only 2 chunks we only care about, and they are SIZE and XYZI
                if (chunkName == "SIZE")
                {
                    sizex = stream.ReadInt32();
                    sizey = stream.ReadInt32();
                    sizez = stream.ReadInt32();

                    //if (sizex > 32 || sizey > 32) subsample = true;

                    stream.ReadBytes(chunkSize - 4 * 3);
                }
                else if (chunkName == "XYZI")
                {
                    // XYZI contains n voxels
                    int numVoxels = stream.ReadInt32();

                    // each voxel has x, y, z and color index values
                    voxelData = new MagicaVoxelData[numVoxels];
                    for (int i = 0; i < voxelData.Length; i++)
                        voxelData[i] = new MagicaVoxelData(stream);
                }
                else if (chunkName == "RGBA")
                {
                    //colors = new float[256][];

                    for (int i = 0; i < 256; i++)
                    {
                        byte r = stream.ReadByte();
                        byte g = stream.ReadByte();
                        byte b = stream.ReadByte();
                        byte a = stream.ReadByte();

                    }
                }
                else stream.ReadBytes(chunkSize);   // read any excess bytes
            }
            if (voxelData.Length == 0) return voxelData; // failed to read any valid voxel data
        }
        return voxelData;
    }
        public static void FromMagica(BinaryReader stream, GameObject root, float voxelSize, bool centerPivot)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data

            Color32[] colors = new Color32[256];

            for (int i = 1; i < 256; i++)
            {
                uint hexval = defaultColors[i];
                byte cb     = (byte)((hexval >> 16) & 0xFF);
                byte cg     = (byte)((hexval >> 8) & 0xFF);
                byte cr     = (byte)((hexval >> 0) & 0xFF);

                colors[i - 1] = new Color32(cr, cg, cb, 255);
            }

            MagicaVoxelData[]        voxelData = null;
            List <MagicaVoxelData[]> frames    = new List <MagicaVoxelData[]>();

            //int numFrames = 1;


            string magic = new string(stream.ReadChars(4));

            //int version =
            stream.ReadInt32();


            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                int  sizex = 0, sizey = 0, sizez = 0;
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId   = stream.ReadChars(4);
                    int    chunkSize = stream.ReadInt32();
                    //int childChunks =
                    stream.ReadInt32();
                    string chunkName = new string(chunkId);

                    if (chunkName == "PACK")
                    {
                        stream.ReadInt32();
                    }
                    else if (chunkName == "SIZE")
                    {
                        sizex = stream.ReadInt32();
                        sizez = stream.ReadInt32();
                        sizey = stream.ReadInt32();

                        //if (sizex > 32 || sizey > 32) subsample = true;

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                        // int div = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                        }

                        frames.Add(voxelData);
                    }
                    else if (chunkName == "RGBA")
                    {
                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            // convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                            colors[i] = new Color32(r, g, b, a);
                        }
                    }
                    else
                    {
                        stream.ReadBytes(chunkSize);    // read any excess bytes
                    }
                }

                if (voxelData.Length == 0)
                {
                    return;                        // failed to read any valid voxel data
                }
                if (root != null)
                {
                    Volume voxelVolume = root.GetComponent <Volume>();

                    voxelVolume.XSize = sizex;
                    voxelVolume.YSize = sizey;
                    voxelVolume.ZSize = sizez;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].XSize  = sizex;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].YSize  = sizey;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].ZSize  = sizez;
                    voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels = new Voxel[sizex * sizey * sizez];
                    for (int i = 0; i < voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels.Length; i++)
                    {
                        voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels[i].Value = 128;
                    }
                    voxelVolume.VoxelSize = voxelSize;

                    if (centerPivot)
                    {
                        voxelVolume.Pivot = (new Vector3(voxelVolume.XSize, voxelVolume.YSize, voxelVolume.ZSize) * voxelVolume.VoxelSize) / 2f;
                        voxelVolume.UpdatePivot();
                    }

                    foreach (MagicaVoxelData[] d in frames)
                    {
                        foreach (MagicaVoxelData v in d)
                        {
                            try
                            {
                                voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels[v.x + sizex * (v.z + sizey * v.y)] = new Voxel()
                                {
                                    State = VoxelState.Active,
                                    Color = colors[v.color - 1],
                                    Value = 128
                                };
                            }
                            catch (Exception)
                            {
                                Debug.Log(v.x + " " + v.y + " " + v.z);
                            }
                        }

                        if (frames.IndexOf(d) < frames.Count - 1)
                        {
                            voxelVolume.AddFrame(voxelVolume.CurrentFrame + 1);
                            voxelVolume.Frames[voxelVolume.CurrentFrame].Voxels = new Voxel[sizex * sizey * sizez];
                        }
                    }

                    voxelVolume.SetFrame(0);
                    voxelVolume.CreateChunks();
                    voxelVolume.SaveForSerialize();
                }
            }
        }
Esempio n. 12
0
        public static Bitmap drawPixelsN(MagicaVoxelData[] voxels)
        {
            Bitmap   b = new Bitmap(22, 44);
            Graphics g = Graphics.FromImage((Image)b);
            //Image image = new Bitmap("cube_large.png");
            Image image = new Bitmap("cube_ortho.png");
            //Image reversed = new Bitmap("cube_reversed.png");
            ImageAttributes imageAttributes = new ImageAttributes();
            int             width           = 1;
            int             height          = 2;

            //g.DrawImage(image, 10, 10, width, height);

            float[][] colorMatrixElements =
            {
                new float[] { 1F,  0,  0,  0,  0 },
                new float[] {  0, 1F,  0,  0,  0 },
                new float[] {  0,  0, 1F,  0,  0 },
                new float[] {  0,  0,  0, 1F,  0 },
                new float[] {  0,  0,  0,  0, 1F }
            };

            ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

            imageAttributes.SetColorMatrix(
                colorMatrix,
                ColorMatrixFlag.Default,
                ColorAdjustType.Bitmap);
            MagicaVoxelData[] vls = new MagicaVoxelData[voxels.Length];
            for (int i = 0; i < voxels.Length; i++)
            {
                byte tempX = (byte)(voxels[i].x - 11);
                byte tempY = (byte)(voxels[i].y - 11);
                vls[i].x     = (byte)((tempX * -1) + 11 - 1);
                vls[i].y     = (byte)((tempY * -1) + 11 - 1);
                vls[i].z     = voxels[i].z;
                vls[i].color = voxels[i].color;
            }
            foreach (MagicaVoxelData vx in vls.OrderBy(v => v.x * 32 - v.y + v.z * 32 * 128)) //voxelData[i].x + voxelData[i].z * 32 + voxelData[i].y * 32 * 128
            {
                int current_color = 249 - vx.color;
                if (current_color > 128)
                {
                    current_color = 24;
                }

                colorMatrix = new ColorMatrix(new float[][] {
                    new float[] { colors[current_color][0], 0, 0, 0, 0 },
                    new float[] { 0, colors[current_color][1], 0, 0, 0 },
                    new float[] { 0, 0, colors[current_color][2], 0, 0 },
                    new float[] { 0, 0, 0, 1F, 0 },
                    new float[] { 0, 0, 0, 0, 1F }
                });

                imageAttributes.SetColorMatrix(
                    colorMatrix,
                    ColorMatrixFlag.Default,
                    ColorAdjustType.Bitmap);

                g.DrawImage(
                    image,
                    new Rectangle(vx.y, 44 - 1 - 20 - 2 + vx.x - vx.z, width, height), // destination rectangle
                    //                   new Rectangle((vx.x + vx.y) * 4, 128 - 6 - 32 - vx.y * 2 + vx.x * 2 - 4 * vx.z, width, height),  // destination rectangle
                    0, 0,                                                              // upper-left corner of source rectangle
                    width,                                                             // width of source rectangle
                    height,                                                            // height of source rectangle
                    GraphicsUnit.Pixel,
                    imageAttributes);
            }
            return(b);
        }
Esempio n. 13
0
        /// <summary>
        /// Load a MagicaVoxel .vox format file into a MagicaVoxelData[] that we use for voxel chunks.
        /// </summary>
        /// <param name="stream">An open BinaryReader stream that is the .vox file.</param>
        /// <param name="overrideColors">Optional color lookup table for converting RGB values into my internal engine color format.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        public static MagicaVoxelData[] FromMagica(BinaryReader stream)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data
            ushort[] data = new ushort[32 * 128 * 32];

            MagicaVoxelData[] voxelData = null;

            string magic   = new string(stream.ReadChars(4));
            int    version = stream.ReadInt32();

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId     = stream.ReadChars(4);
                    int    chunkSize   = stream.ReadInt32();
                    int    childChunks = stream.ReadInt32();
                    string chunkName   = new string(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName == "SIZE")
                    {
                        sizex = stream.ReadInt32();
                        sizey = stream.ReadInt32();
                        sizez = stream.ReadInt32();

                        if (sizex > 32 || sizey > 32)
                        {
                            subsample = true;
                        }

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                        int div       = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                        }
                    }
                    else if (chunkName == "RGBA")
                    {
//                        colors = new float[256][];

                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            //colors[i] = new float[] { r / 256.0f, g / 256.0f, b / 256.0f, a / 256.0f};
                        }
                    }
                    else
                    {
                        stream.ReadBytes(chunkSize);    // read any excess bytes
                    }
                }

                if (voxelData.Length == 0)
                {
                    return(voxelData);                       // failed to read any valid voxel data
                }
                // now push the voxel data into our voxel chunk structure
                for (int i = 0; i < voxelData.Length; i++)
                {
                    // do not store this voxel if it lies out of range of the voxel chunk (32x128x32)
                    if (voxelData[i].x > 31 || voxelData[i].y > 31 || voxelData[i].z > 127)
                    {
                        continue;
                    }

                    // use the voxColors array by default, or overrideColor if it is available
                    int voxel = (voxelData[i].x + voxelData[i].z * 32 + voxelData[i].y * 32 * 128);
                    //data[voxel] = (colors == null ? voxColors[voxelData[i].color - 1] : colors[voxelData[i].color - 1]);
                }
            }

            return(voxelData);
        }
Esempio n. 14
0
        /// <summary>
        /// Load a MagicaVoxel .vox format file into the custom ushort[] structure that we use for voxel chunks.
        /// </summary>
        /// <param name="stream">An open BinaryReader stream that is the .vox file.</param>
        /// <param name="overrideColors">Optional color lookup table for converting RGB values into my internal engine color format.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        private static Color32[] FromMagica(BinaryReader stream)
        {
            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            string magic = new string(stream.ReadChars(4));            
            if (magic != "VOX ")
                return null;

            int version = stream.ReadInt32();
            if (version != 150)
            {
                Debug.LogWarning("Vox file version does not match 150. Issues possible.");
            }

            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data
            Color32[] data = new Color32[SizeX * SizeY * SizeZ];
            Color32[] colors = null;
            MagicaVoxelData[] voxelData = null;

            bool subsample = false;

            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                // each chunk has an ID, size and child chunks
                char[] chunkId = stream.ReadChars(4);
                int chunkSize = stream.ReadInt32();
                int childChunks = stream.ReadInt32();
                if (childChunks < 0)
                {
                    Debug.LogError("childChunks < 0");
                    return null;
                }

                string chunkName = new string(chunkId);
                switch (chunkName)
                {
                    // Chunk dimensions
                    case "SIZE":
                    {
                        int sizeX = stream.ReadInt32();
                        int sizeY = stream.ReadInt32();
                        int sizeZ = stream.ReadInt32();

                        if (sizeX > SizeX || sizeZ > SizeZ || sizeY > SizeY)
                            subsample = true;

                        stream.ReadBytes(chunkSize - 4 * 3);
                        break;
                    }                        
                    // Voxel data
                    case "XYZI":
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                        if (numVoxels <= 0)
                            return null;

                        //int div = (subsample ? 2 : 1);

                        // Each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                            voxelData[i] = new MagicaVoxelData(stream, subsample);

                        break;
                    }
                    case "RGBA":
                    {
                        colors = new Color32[256];
                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            // Convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                            colors[i] = new Color32(r,g,b,a);
                                //(ushort) (((r & 0x1f) << 10) | ((g & 0x1f) << 5) | (b & 0x1f));
                        }

                        break;
                    }

                    default:
                        // Read any excess bytes
                        stream.ReadBytes(chunkSize);
                        break;
                }
            }

            // Failed to read any valid voxel data
            if (voxelData == null || voxelData.Length == 0)
                return null;

            // Push the voxel data into our voxel chunk structure
            for (int i = 0; i < voxelData.Length; i++)
            {
                // Do not store this voxel if it lies out of range of the voxel chunk (32x128x32)
                if (voxelData[i].X >= SizeX || voxelData[i].Y >= SizeY || voxelData[i].Z >= SizeZ)
                    continue;

                // Use the voxColors array by default, or overrideColor if it is available
                int voxel = (voxelData[i].X + (voxelData[i].Z << LogX) + (voxelData[i].Y << LogY << LogZ));
                if (colors == null)
                {
                    uint col = SVoxColors[voxelData[i].Color - 1];
                    data[voxel] = new Color32((byte)((col >> 16) & 0xFf), (byte)((col >> 8) & 0xFf), (byte)(col & 0xFf), 0xFf);
                }
                else
                {
                    data[voxel] = colors[voxelData[i].Color - 1];
                }
            }

            return data;
        }
        public async Task ReadMagica(Stream stream)
        {
            int[]             colors    = null;
            MagicaVoxelData[] voxelData = null;

            String magic   = new String(ReadChars(stream, 4));
            int    version = ReadInt32(stream);

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic.CompareTo("VOX ") == 0)
            {
                int  sizex = 0, sizey = 0, sizez = 0;
                bool subsample = false;

                while (stream.Position < stream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId     = ReadChars(stream, 4);
                    int    chunkSize   = ReadInt32(stream);
                    int    childChunks = ReadInt32(stream);
                    String chunkName   = new String(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName.CompareTo("SIZE") == 0)
                    {
                        sizex = ReadInt32(stream);
                        sizey = ReadInt32(stream);
                        sizez = ReadInt32(stream);

                        if (sizex > 32 || sizey > 32)
                        {
                            subsample = true;
                        }


                        stream.Seek(chunkSize - 4 * 3, SeekOrigin.Current);
                    }
                    else if (chunkName.CompareTo("XYZI") == 0)
                    {
                        // XYZI contains n voxels
                        int numVoxels = ReadInt32(stream);
                        int div       = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                        }
                    }
                    else if (chunkName.CompareTo("RGBA") == 0)
                    {
                        colors = new int[256];

                        for (int i = 0; i < 256; i++)
                        {
                            int r = stream.ReadByte() & 0xff;
                            int g = stream.ReadByte() & 0xff;
                            int b = stream.ReadByte() & 0xff;
                            int a = stream.ReadByte() & 0xff;

                            colors[i] = (a & 0xff) << 24 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff);
                        }
                    }
                    else
                    {
                        stream.Seek(chunkSize, SeekOrigin.Current);    // read any excess bytes
                    }
                }

                if (voxelData.Length == 0)
                {
                    return;
                }

                // now push the voxel data into our voxel chunk structure
                for (int i = 0; i < voxelData.Length; i++)
                {
                    // do not store this voxel if it lies out of range of the voxel chunk (32x128x32)
                    if (voxelData[i].x > 31 || voxelData[i].y > 31 || voxelData[i].z > 127)
                    {
                        continue;
                    }

                    int color = 0;

                    if (colors == null) // use default palette
                    {
                        // WTF hardcoded palette is ABGR, doing ABGR => ARGB
                        color = (int)voxColors[voxelData[i].color - 1];
                        int r = color & 0xff;
                        int g = (color >> 8) & 0xff;
                        int b = (color >> 16) & 0xff;
                        int a = (color >> 28) & 0xff;
                        color = a << 28 | r << 16 | g << 8 | b;
                    }
                    else // use palette from file
                    {
                        color = colors[voxelData[i].color - 1];
                    }

                    if (timelapse)
                    {
                        await Task.Delay(2);
                    }

                    if (BlockConstructed != null)
                    {
                        Vector3 position = new Vector3(voxelData[i].x, voxelData[i].y, voxelData[i].z);
                        BlockConstructed(new Tuple <Vector3, int>(position, color));
                    }
                }
            }
        }
Esempio n. 16
0
        private static Bitmap generateWaterMask(int facing, int variant)
        {
            setupCurrentColorsH(Color.FromArgb(100, 230, 250));
            Bitmap bmp = new Bitmap(vwidth * 16, vheight * 16, PixelFormat.Format32bppArgb);

            //            Bitmap bmp = new Bitmap(4 * 128 + 8, 2 * 128 + 8, PixelFormat.Format32bppArgb);

            // Specify a pixel format.
            PixelFormat pxf = PixelFormat.Format32bppArgb;

            // Lock the bitmap's bits.
            Rectangle  rect    = new Rectangle(0, 0, bmp.Width, bmp.Height);
            BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            // int numBytes = bmp.Width * bmp.Height * 3;
            int numBytes = bmpData.Stride * bmp.Height;

            byte[] argbValues = new byte[numBytes];
            argbValues.Fill <byte>(0);
            byte[] outlineColors = new byte[numBytes];
            outlineColors.Fill <byte>(0);
            byte[] outlineValues = new byte[numBytes];
            outlineValues.Fill <byte>(0);
            bool[] barePositions = new bool[numBytes];
            barePositions.Fill(false);

            int[] xbuffer = new int[numBytes];
            xbuffer.Fill <int>(-999);
            int[] zbuffer = new int[numBytes];
            zbuffer.Fill <int>(-999);

            for (int mvdx = 15; mvdx >= 0; mvdx--)
            {
                for (int mvdy = 0; mvdy <= 15; mvdy++)
                {
                    MagicaVoxelData vx = new MagicaVoxelData {
                        x = (byte)mvdx, y = (byte)mvdy, z = 0, color = 153
                    };
                    int current_color = hcolorcount + 19;
                    //int unshaded = VoxelLogic.WithoutShadingK(vx.color);
                    //int current_color = ((255 - vx.color) % 4 == 0) ? (255 - vx.color) / 4 + hcolorcount : ((254 - vx.color) % 4 == 0) ? (253 - clear) / 4 : (253 - vx.color) / 4;
                    int p         = 0;
                    int mod_color = current_color;

                    for (int j = 0; j < vheight; j++)
                    {
                        for (int i = 0; i < 4 * vwidth; i++)
                        {
                            //p = 4 * ((vx.x + vx.y) * 2 + 2) + i + bmpData.Stride * (128 + 2 - vx.y + vx.x + j);
                            mod_color = current_color;
                            p         = voxelToPixelH16(i, j, vx.x, vx.y, 0, current_color, bmpData.Stride, 0, true);
                            if (argbValues[p] == 0)
                            {
                                zbuffer[p] = vx.z;
                                xbuffer[p] = vx.x;
                                if (i % 4 == 3)
                                {
                                    double wave = Simplex.FindNoiseFlatWater(facing, vx.x, vx.y, variant);

                                    if (wave > 0.73)
                                    {
                                        wave = 85 * wave;
                                    }
                                    else if (wave > 0.64)
                                    {
                                        wave = 65 * wave;
                                    }
                                    else if (wave > 0.55)
                                    {
                                        wave = 50 * wave;
                                    }
                                    else if (wave < 0.45)
                                    {
                                        wave += 0.2;
                                        if (wave < 0.5)
                                        {
                                            wave       = -15 / wave;
                                            mod_color -= hcolorcount;
                                        }
                                        else if (wave < 0.55)
                                        {
                                            wave       = -11 / wave;
                                            mod_color -= hcolorcount;
                                        }
                                        else if (wave < 0.6)
                                        {
                                            wave = -7 / wave;
                                            mod_color--;
                                        }
                                        else
                                        {
                                            wave = 6.0 * (wave - 0.25);
                                        }
                                    }
                                    else
                                    {
                                        wave = 32.0 * wave;
                                    }
                                    wave      = Clamp(wave, -72.0, 72.0);
                                    mod_color = (byte)(((int)(wave / 12.2)) * 2 + mod_color);


                                    argbValues[p - 3] = hrendered[mod_color][i - 3 + j * (vwidth * 4)];
                                    argbValues[p - 2] = hrendered[mod_color][i - 2 + j * (vwidth * 4)];
                                    argbValues[p - 1] = hrendered[mod_color][i - 1 + j * (vwidth * 4)];
                                    argbValues[p - 0] = 255;
                                    if (outlineColors[p] == 0)
                                    {
                                        outlineColors[p] = hrendered[mod_color][i + (4 * vwidth * vheight)];
                                    }
                                }
                            }
                        }
                    }
                }
            }

            /*
             * bool darkOutline = false;
             * for (int i = 3; i < numBytes; i += 4)
             * {
             *  if (argbValues[i] > 255 * waver_alpha && barePositions[i] == false)
             *  {
             *
             *      if (i + 4 >= 0 && i + 4 < argbValues.Length && argbValues[i + 4] == 0 && darkOutline && outlineValues[i + 4] == 0) { outlineValues[i + 4] = 255; } else if (i + 4 >= 0 && i + 4 < argbValues.Length && barePositions[i + 4] == false && (zbuffer[i] - 1 > zbuffer[i + 4] || xbuffer[i] - 1 > xbuffer[i + 4]) && outlineValues[i + 4] == 0) { outlineValues[i + 4] = 255; outlineValues[i + 4 - 1] = outlineColors[i - 1]; outlineValues[i + 4 - 2] = outlineColors[i - 2]; outlineValues[i + 4 - 3] = outlineColors[i - 3]; }
             *      if (i - 4 >= 0 && i - 4 < argbValues.Length && argbValues[i - 4] == 0 && darkOutline && outlineValues[i - 4] == 0) { outlineValues[i - 4] = 255; } else if (i - 4 >= 0 && i - 4 < argbValues.Length && barePositions[i - 4] == false && (zbuffer[i] - 1 > zbuffer[i - 4] || xbuffer[i] - 1 > xbuffer[i - 4]) && outlineValues[i - 4] == 0) { outlineValues[i - 4] = 255; outlineValues[i - 4 - 1] = outlineColors[i - 1]; outlineValues[i - 4 - 2] = outlineColors[i - 2]; outlineValues[i - 4 - 3] = outlineColors[i - 3]; }
             *      if (i + bmpData.Stride >= 0 && i + bmpData.Stride < argbValues.Length && argbValues[i + bmpData.Stride] == 0 && darkOutline && outlineValues[i + bmpData.Stride] == 0) { outlineValues[i + bmpData.Stride] = 255; } else if (i + bmpData.Stride >= 0 && i + bmpData.Stride < argbValues.Length && barePositions[i + bmpData.Stride] == false && (zbuffer[i] - 1 > zbuffer[i + bmpData.Stride] || xbuffer[i] - 1 > xbuffer[i + bmpData.Stride]) && outlineValues[i + bmpData.Stride] == 0) { outlineValues[i + bmpData.Stride] = 255; outlineValues[i + bmpData.Stride - 1] = outlineColors[i - 1]; outlineValues[i + bmpData.Stride - 2] = outlineColors[i - 2]; outlineValues[i + bmpData.Stride - 3] = outlineColors[i - 3]; }
             *      if (i - bmpData.Stride >= 0 && i - bmpData.Stride < argbValues.Length && argbValues[i - bmpData.Stride] == 0 && darkOutline && outlineValues[i - bmpData.Stride] == 0) { outlineValues[i - bmpData.Stride] = 255; } else if (i - bmpData.Stride >= 0 && i - bmpData.Stride < argbValues.Length && barePositions[i - bmpData.Stride] == false && (zbuffer[i] - 1 > zbuffer[i - bmpData.Stride] || xbuffer[i] - 1 > xbuffer[i - bmpData.Stride]) && outlineValues[i - bmpData.Stride] == 0) { outlineValues[i - bmpData.Stride] = 255; outlineValues[i - bmpData.Stride - 1] = outlineColors[i - 1]; outlineValues[i - bmpData.Stride - 2] = outlineColors[i - 2]; outlineValues[i - bmpData.Stride - 3] = outlineColors[i - 3]; }
             *  }
             *
             * }
             */


            for (int i = 3; i < numBytes; i += 4)
            {
                if (argbValues[i] > 0)
                {
                    argbValues[i] = 255;
                }
                if (outlineValues[i] == 255)
                {
                    argbValues[i]     = 255;
                    argbValues[i - 1] = outlineValues[i - 1];
                    argbValues[i - 2] = outlineValues[i - 2];
                    argbValues[i - 3] = outlineValues[i - 3];
                }
            }

            Marshal.Copy(argbValues, 0, ptr, numBytes);

            // Unlock the bits.
            bmp.UnlockBits(bmpData);

            return(bmp);
        }
    //////loading magica voxel//////////////


    public void loadFromFile(string fileName)
    {
        //using (BinaryReader stream = new BinaryReader(new FileStream(Application.dataPath + "/StreamingAssets/"+fileName, FileMode.Open)))
        TextAsset asset = Resources.Load(fileName) as TextAsset;
        Stream    s     = new MemoryStream(asset.bytes);

        //BinaryReader br = new BinaryReader(s);

        using (BinaryReader stream = new BinaryReader(s))
        {
            MagicaVoxelData[] voxelData = null;

            string magic = new string(stream.ReadChars(4));
            //int version =
            stream.ReadInt32();


            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                int  width = 0, height = 0, depth = 0;
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId   = stream.ReadChars(4);
                    int    chunkSize = stream.ReadInt32();
                    //int childChunks =
                    stream.ReadInt32();
                    string chunkName = new string(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName == "SIZE")
                    {
                        width  = stream.ReadInt32();
                        depth  = stream.ReadInt32();
                        height = stream.ReadInt32();

                        //if (width > 32 || height > 32) subsample = true;

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                        // int div = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                        {
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                        }
                    }
                    else if (chunkName == "RGBA")
                    {
                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            // convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                            colors[i] = new Color32(r, g, b, a);
                        }
                    }
                    else
                    {
                        stream.ReadBytes(chunkSize);        // read any excess bytes
                    }
                }

                if (voxelData.Length == 0)
                {
                    return;                            // failed to read any valid voxel data
                }
                // sizes
                this.width  = width;
                this.height = height;
                this.depth  = depth;


                foreach (MagicaVoxelData v in voxelData)
                {
                    try
                    {
                        voxels.Add(new Voxel(v.x, v.z, v.y, (byte)(v.color - 1)));
                    }
                    catch (Exception)
                    {
                        // Console.WriteLine(e);
                        //Debug.Log(v.x + " " + v.y + " " + v.z);
                    }
                }
            }
        }
    }
Esempio n. 18
0
        private static void FromMagica(BinaryReader stream, string volumeName, float voxelSize, bool centerPivot)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below
            // we're going to return a voxel chunk worth of data

            Color32[] colors = new Color32[256];

            for (int i = 1; i < 256; i++)
            {
                uint hexval = defaultColors[i];
                byte cb = (byte)((hexval >> 16) & 0xFF);
                byte cg = (byte)((hexval >> 8) & 0xFF);
                byte cr = (byte)((hexval >> 0) & 0xFF);

                colors[i - 1] = new Color32(cr, cg, cb, 255);
            }

            MagicaVoxelData[] voxelData = null;

            string magic = new string(stream.ReadChars(4));
            //int version =
            stream.ReadInt32();

            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            if (magic == "VOX ")
            {
                int sizex = 0, sizey = 0, sizez = 0;
                bool subsample = false;

                while (stream.BaseStream.Position < stream.BaseStream.Length)
                {
                    // each chunk has an ID, size and child chunks
                    char[] chunkId = stream.ReadChars(4);
                    int chunkSize = stream.ReadInt32();
                    //int childChunks =
                    stream.ReadInt32();
                    string chunkName = new string(chunkId);

                    // there are only 2 chunks we only care about, and they are SIZE and XYZI
                    if (chunkName == "SIZE")
                    {
                        sizex = stream.ReadInt32();
                        sizez = stream.ReadInt32();
                        sizey = stream.ReadInt32();

                        //if (sizex > 32 || sizey > 32) subsample = true;

                        stream.ReadBytes(chunkSize - 4 * 3);
                    }
                    else if (chunkName == "XYZI")
                    {
                        // XYZI contains n voxels
                        int numVoxels = stream.ReadInt32();
                       // int div = (subsample ? 2 : 1);

                        // each voxel has x, y, z and color index values
                        voxelData = new MagicaVoxelData[numVoxels];
                        for (int i = 0; i < voxelData.Length; i++)
                            voxelData[i] = new MagicaVoxelData(stream, subsample);
                    }
                    else if (chunkName == "RGBA")
                    {

                        for (int i = 0; i < 256; i++)
                        {
                            byte r = stream.ReadByte();
                            byte g = stream.ReadByte();
                            byte b = stream.ReadByte();
                            byte a = stream.ReadByte();

                            // convert RGBA to our custom voxel format (16 bits, 0RRR RRGG GGGB BBBB)
                            colors[i] = new Color32(r, g, b, a);
                        }
                    }
                    else stream.ReadBytes(chunkSize);   // read any excess bytes
                }

                if (voxelData.Length == 0) return; // failed to read any valid voxel data

                // Quick and dirty multi-part splitter if size > 32 on any axis
                //if (sizex > MAX_VOLUME_DIMENSION || sizey > MAX_VOLUME_DIMENSION || sizez > MAX_VOLUME_DIMENSION)
                //{
                //    var parentObject = new GameObject();
                //    parentObject.name = volumeName;

                //    int xparts = (sizex/MAX_VOLUME_DIMENSION) + (sizex%MAX_VOLUME_DIMENSION > 0 ? 1 : 0);
                //    int yparts = (sizey/MAX_VOLUME_DIMENSION) + (sizey%MAX_VOLUME_DIMENSION > 0 ? 1 : 0);
                //    int zparts = (sizez/MAX_VOLUME_DIMENSION) + (sizez%MAX_VOLUME_DIMENSION > 0 ? 1 : 0);

                //    int xRem = sizex % MAX_VOLUME_DIMENSION;
                //    int yRem = sizey % MAX_VOLUME_DIMENSION;
                //    int zRem = sizez % MAX_VOLUME_DIMENSION;

                //    int totalX = xRem > 0 ? ((xparts - 1) * MAX_VOLUME_DIMENSION) + xRem : xparts * MAX_VOLUME_DIMENSION;
                //    int totalY = yRem > 0 ? ((yparts - 1) * MAX_VOLUME_DIMENSION) + yRem : yparts * MAX_VOLUME_DIMENSION;
                //    int totalZ = zRem > 0 ? ((zparts - 1) * MAX_VOLUME_DIMENSION) + zRem : zparts * MAX_VOLUME_DIMENSION;

                //    Volume[,,] volumeRefs = new Volume[xparts,yparts,zparts];

                //    for (int x = 0; x < xparts; x++)
                //        for (int y = 0; y < yparts; y++)
                //            for (int z = 0; z < zparts; z++)
                //            {
                //                var newObject =
                //                    Editor.Instantiate(EditorUtility.VoxelVolumePrefab, Vector3.zero, Quaternion.identity) as
                //                        GameObject;
                //                if (newObject != null)
                //                {
                //                    newObject.name = volumeName + " (" + x + "," + y + "," + z + ")";
                //                    newObject.GetComponent<Volume>().Material = EditorUtility.PicaVoxelDiffuseMaterial;
                //                    newObject.GetComponent<Volume>().VoxelSize = voxelSize;
                //                    newObject.GetComponent<Volume>().GenerateBasic(FillMode.None);
                //                    newObject.transform.parent = parentObject.transform;
                //                    Volume voxelVolume = newObject.GetComponent<Volume>();

                //                    voxelVolume.XSize = x < xparts - 1 ? MAX_VOLUME_DIMENSION : xRem;
                //                    voxelVolume.YSize = y < yparts - 1 ? MAX_VOLUME_DIMENSION : yRem;
                //                    voxelVolume.ZSize = z < zparts - 1 ? MAX_VOLUME_DIMENSION : zRem;
                //                    voxelVolume.Frames[0].XSize = voxelVolume.XSize;
                //                    voxelVolume.Frames[0].YSize = voxelVolume.YSize;
                //                    voxelVolume.Frames[0].ZSize = voxelVolume.ZSize;
                //                    voxelVolume.Frames[0].Voxels = new Voxel[voxelVolume.XSize* voxelVolume.YSize* voxelVolume.ZSize];
                //                    newObject.transform.parent = parentObject.transform;

                //                    if (!centerPivot)
                //                        newObject.transform.localPosition = new Vector3(x * MAX_VOLUME_DIMENSION * voxelSize, y * MAX_VOLUME_DIMENSION * voxelSize, z * MAX_VOLUME_DIMENSION * voxelSize);
                //                    else
                //                    {
                //                        newObject.GetComponent<Volume>().Pivot = (new Vector3(MAX_VOLUME_DIMENSION, MAX_VOLUME_DIMENSION, MAX_VOLUME_DIMENSION) * voxelSize) / 2f;
                //                        newObject.GetComponent<Volume>().UpdatePivot();
                //                        newObject.transform.localPosition = -(new Vector3(totalX * (voxelSize / 2f), totalY * (voxelSize / 2f), totalZ * (voxelSize / 2f)))
                //                            + new Vector3(MAX_VOLUME_DIMENSION * (voxelSize / 2f), MAX_VOLUME_DIMENSION * (voxelSize / 2f), MAX_VOLUME_DIMENSION * (voxelSize / 2f))
                //                            + new Vector3(x * MAX_VOLUME_DIMENSION * voxelSize, y * MAX_VOLUME_DIMENSION * voxelSize, z * MAX_VOLUME_DIMENSION * voxelSize);
                //                    }

                //                    volumeRefs[x, y, z] = voxelVolume;
                //                }
                //            }

                //    foreach (MagicaVoxelData v in voxelData)
                //    {
                //        try
                //        {
                //            int xpart = v.x / MAX_VOLUME_DIMENSION;
                //            int ypart = v.z / MAX_VOLUME_DIMENSION;
                //            int zpart = v.y / MAX_VOLUME_DIMENSION;

                //            volumeRefs[xpart, ypart, zpart].Frames[0].Voxels[(v.x - (MAX_VOLUME_DIMENSION * xpart)) + volumeRefs[xpart, ypart, zpart].XSize * ((v.z - (MAX_VOLUME_DIMENSION * ypart)) + volumeRefs[xpart, ypart, zpart].YSize * (v.y - (MAX_VOLUME_DIMENSION * zpart)))] = new Voxel()
                //            {
                //                Active = true,
                //                Color = colors[v.color - 1],
                //                Value = 128
                //            };
                //        }
                //        catch (Exception)
                //        {

                //            Debug.Log(v.x + " " + v.y + " " + v.z);
                //        }

                //    }

                //    foreach (Volume v in volumeRefs)
                //    {
                //        v.CreateChunks();
                //        v.SaveForSerialize();
                //    }
                //}
                //else
                //{
                    // Single volume
                    var newObject =
                        Editor.Instantiate(EditorUtility.VoxelVolumePrefab, Vector3.zero, Quaternion.identity) as
                            GameObject;
                    if (newObject != null)
                    {
                        newObject.name = volumeName;
                        newObject.GetComponent<Volume>().Material = EditorUtility.PicaVoxelDiffuseMaterial;
                        newObject.GetComponent<Volume>().GenerateBasic(FillMode.None);
                        Volume voxelVolume = newObject.GetComponent<Volume>();

                        voxelVolume.XSize = sizex;
                        voxelVolume.YSize = sizey;
                        voxelVolume.ZSize = sizez;
                        voxelVolume.Frames[0].XSize = sizex;
                        voxelVolume.Frames[0].YSize = sizey;
                        voxelVolume.Frames[0].ZSize = sizez;
                        voxelVolume.Frames[0].Voxels = new Voxel[sizex * sizey * sizez];
                        voxelVolume.VoxelSize = voxelSize;

                        if (centerPivot)
                        {
                            voxelVolume.Pivot = (new Vector3(voxelVolume.XSize, voxelVolume.YSize, voxelVolume.ZSize) * voxelVolume.VoxelSize) / 2f;
                            voxelVolume.UpdatePivot();
                        }

                        foreach (MagicaVoxelData v in voxelData)
                        {
                            try
                            {
                                voxelVolume.Frames[0].Voxels[v.x + sizex * (v.z + sizey * v.y)] = new Voxel()
                                {
                                    Active = true,
                                    Color = colors[v.color-1],
                                    Value = 128
                                };
                            }
                            catch (Exception)
                            {

                                Debug.Log(v.x + " " + v.y + " " + v.z);
                            }

                        }

                        voxelVolume.CreateChunks();
                        voxelVolume.SaveForSerialize();
                    }
               // }

            }
        }