Пример #1
0
        private static int ReadXYZI(BinaryReader br, MagicaVoxelMainChunk mainChunk)
        {
            int chunkSize    = br.ReadInt32();
            int childrenSize = br.ReadInt32();

            if (childrenSize > 0)
            {
                br.ReadBytes(childrenSize);
                Debug.LogWarning("MV: Nested chunks not supported");
                return(-1);
            }

            MagicaVoxelChunk chunk = mainChunk.chunk;

            int numVoxels = br.ReadInt32();

            for (int i = 0; i < numVoxels; ++i)
            {
                int x = br.ReadByte();
                int z = br.ReadByte(); // Magica has Z and Y swapped
                int y = br.ReadByte();

                chunk.data[Helpers.GetIndex1DFrom3D(x, y, z, chunk.sizeX, chunk.sizeZ)] = br.ReadByte();
            }

            return(chunkSize + childrenSize + 4 * 3);
        }
Пример #2
0
        private static int ReadSize(BinaryReader br, MagicaVoxelMainChunk mainChunk)
        {
            int chunkSize    = br.ReadInt32();
            int childrenSize = br.ReadInt32();

            if (childrenSize > 0)
            {
                br.ReadBytes(childrenSize);
                Debug.LogError("MV: Nested chunks not supported");
                return(-1);
            }

            MagicaVoxelChunk chunk = mainChunk.chunk = new MagicaVoxelChunk();

            chunk.sizeX = br.ReadInt32();
            chunk.sizeZ = br.ReadInt32(); // Magica has Z and Y swapped
            chunk.sizeY = br.ReadInt32();
            chunk.data  = new byte[chunk.sizeX * chunk.sizeY * chunk.sizeZ];

            return(chunkSize + childrenSize + 4 * 3);
        }
Пример #3
0
        private static int ReadRGBA(BinaryReader br, MagicaVoxelMainChunk mainChunk)
        {
            int chunkSize    = br.ReadInt32();
            int childrenSize = br.ReadInt32();

            if (childrenSize > 0)
            {
                br.ReadBytes(childrenSize);
                Debug.LogError("MV: Nested chunks not supported");
                return(-1);
            }

            mainChunk.palette    = new Color32[256];
            mainChunk.palette[0] = new Color32(0, 0, 0, 0);
            for (int i = 1; i < 256; ++i)
            {
                mainChunk.palette[i] = new Color32(
                    br.ReadByte(), br.ReadByte(), br.ReadByte(), br.ReadByte()
                    );
            }

            return(chunkSize + childrenSize + 4 * 3);
        }
Пример #4
0
        /// <summary>
        /// Load a MagicaVoxel .vox format file into the custom ushort[] structure that we use for voxel chunks.
        /// </summary>
        /// <param name="br">An open BinaryReader stream that is the .vox file.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        public static MagicaVoxelMainChunk FromMagica(BinaryReader br)
        {
            // VOX file starts with 'VOX '
            char[] chars = br.ReadChars(4);
            if (chars[0] != 'V' || chars[1] != 'O' || chars[2] != 'X' || chars[3] != ' ')
            {
                Debug.LogError("MV: Invalid file format. It does not start with 'VOX '");
                return(null);
            }

            int version = br.ReadInt32();

            if (version != 150)
            {
                Debug.LogWarning("MV: File version does not match 150. Issues possible.");
            }

            chars = br.ReadChars(4);
            if (chars[0] != 'M' || chars[1] != 'A' || chars[2] != 'I' || chars[3] != 'N')
            {
                Debug.LogError("MV: Invalid ChunkID, 'MAIN' expected");
                return(null);
            }

            chars = br.ReadChars(4);
            if (chars[0] == 'P' && chars[1] == 'A' && chars[2] == 'C' && chars[3] == 'K')
            {
                Debug.LogError("MV: Multiple models for VOX not supported");
                return(null);
            }

            // Main chunk data size in bytes
            int chunkSize = (chars[3] >> 24) | chars[2] >> 16 | chars[1] >> 8 | chars[0];
            // Children chunk data size in bytes
            int childrenSize = br.ReadInt32();

            if (childrenSize < 0)
            {
                Debug.LogError("MV: childrenSize < 0");
                return(null);
            }

            // Main chunk should be empty. Let's skip it
            br.ReadBytes(chunkSize);

            MagicaVoxelMainChunk mainChunk = new MagicaVoxelMainChunk();

            int readSize = 0;

            while (readSize < childrenSize)
            {
                // each chunk has an ID, size and child chunks
                chars = br.ReadChars(4);

                if (chars[0] == 'S' && chars[1] == 'I' && chars[2] == 'Z' && chars[3] == 'E')
                {
                    int size = ReadSize(br, mainChunk);
                    if (size < 0)
                    {
                        return(null);
                    }

                    readSize += size;
                }
                else if (chars[0] == 'X' && chars[1] == 'Y' && chars[2] == 'Z' && chars[3] == 'I')
                {
                    int size = ReadXYZI(br, mainChunk);
                    if (size < 0)
                    {
                        return(null);
                    }

                    readSize += size;
                }
                else if (chars[0] == 'R' && chars[1] == 'G' && chars[2] == 'B' && chars[3] == 'A')
                {
                    int size = ReadRGBA(br, mainChunk);
                    if (size < 0)
                    {
                        return(null);
                    }

                    readSize += size;
                }
                else
                {
                    Debug.LogError("MV: Unrecognized file format");
                    return(null);
                }
            }

            // Use default palette if there is none in the file
            if (mainChunk.palette == null)
            {
                mainChunk.palette = new Color32[256];
                for (int i = 0; i < 256; i++)
                {
                    uint color = defaultPalette[i];
                    byte r     = (byte)(color & 0xFF);
                    byte g     = (byte)((color >> 8) & 0xFF);
                    byte b     = (byte)((color >> 16) & 0xFF);
                    byte a     = (byte)((color >> 24) & 0xFF);

                    mainChunk.palette[i] = new Color32(r, g, b, a);
                }
            }

            return(mainChunk);
        }