public static RiffChunk CreateLayrChunk(int number)
        {
            RiffChunk chunkResult = new RiffChunk("LAYR");

            chunkResult.addData(new IntChunkData(number));
            List <(string, string)> dict = new List <(string, string)>();

            dict.Add(("name_", number.ToString()));
            chunkResult.addData(new DictChunkData(dict)); //presumably has to include dictionary with name
            chunkResult.addData(new IntChunkData(-1));    //Reserved field
            return(chunkResult);
        }
        //Might not be needed. Create 256 identical material chunks
        public static RiffChunk CreateMatlChunk(int matlID)
        {
            RiffChunk matlChunk = new RiffChunk("MATL");

            matlChunk.addData(new IntChunkData(matlID));
            List <(string, string)> dict = new List <(string, string)>();

            dict.Add(("_type", "_diffuse")); //Copy of what the 3x3x3 file has
            dict.Add(("_weight", "1"));
            dict.Add(("_rough", "0.1"));
            dict.Add(("_spec", "0.5"));
            dict.Add(("_spec_p", "0.5"));
            dict.Add(("_ior", "0.3"));
            dict.Add(("_att", "0"));
            dict.Add(("_g0", "-0.5"));
            dict.Add(("_g1", "0.8"));
            dict.Add(("_gw", "0.7"));
            dict.Add(("_flux", "0"));
            dict.Add(("_idr", "0"));
            matlChunk.addData(new DictChunkData(dict));
            return(matlChunk);
        }
Exemple #3
0
        public RiffChunk getPaletteChunk()
        {
            RiffChunk resultChunk = new RiffChunk("RGBA");

            for (int i = 1; i < paletteOffset; i++)
            {
                //Add completely white pixels for the reserved indexes
                resultChunk.addData(new ByteChunkData(255));
                resultChunk.addData(new ByteChunkData(255));
                resultChunk.addData(new ByteChunkData(255));
                resultChunk.addData(new ByteChunkData(255));
            }
            foreach (RGBColor color in palette)
            {
                //RGBA
                resultChunk.addData(new ByteChunkData(color.red));
                resultChunk.addData(new ByteChunkData(color.green));
                resultChunk.addData(new ByteChunkData(color.blue));
                resultChunk.addData(new ByteChunkData(255)); //Magicavoxel doesn't seem to use this, but keeps all of them at 255
            }
            for (int i = paletteOffset + palette.Count; i < 255; i++)
            {
                //Add completely white pixels to the rest of the palette
                resultChunk.addData(new ByteChunkData(255));
                resultChunk.addData(new ByteChunkData(255));
                resultChunk.addData(new ByteChunkData(255));
                resultChunk.addData(new ByteChunkData(255));
            }
            //Let number 256 be 0 0 0 0 as in example
            resultChunk.addData(new ByteChunkData(0));
            resultChunk.addData(new ByteChunkData(0));
            resultChunk.addData(new ByteChunkData(0));
            resultChunk.addData(new ByteChunkData(0));

            return(resultChunk);
        }
        //This method is a mess. But no reason to waste time cleaning it.
        public static List <RiffChunk> CreateROBJChunks()
        {
            List <RiffChunk> chunksResult = new List <RiffChunk>();

            //Completely copied from the 3x3x3 model file

            RiffChunk robjchunkenv          = new RiffChunk("rOBJ");
            List <(string, string)> dictenv = new List <(string, string)>();

            dictenv.Add(("_type", "_env"));
            dictenv.Add(("_mode", "0"));
            robjchunkenv.addData(new DictChunkData(dictenv));
            chunksResult.Add(robjchunkenv);

            RiffChunk robjchunkinf          = new RiffChunk("rOBJ");
            List <(string, string)> dictinf = new List <(string, string)>();

            dictinf.Add(("_type", "_inf"));
            dictinf.Add(("_i", "0.7"));
            dictinf.Add(("_k", "255 255 255"));
            dictinf.Add(("_angle", "50 50"));
            dictinf.Add(("_area", "0.07"));
            dictinf.Add(("_disk", "0"));
            robjchunkinf.addData(new DictChunkData(dictinf));
            chunksResult.Add(robjchunkinf);

            RiffChunk robjchunk2          = new RiffChunk("rOBJ");
            List <(string, string)> dict2 = new List <(string, string)>();

            dict2.Add(("_type", "_uni"));
            dict2.Add(("_i", "0.7"));
            dict2.Add(("_k", "255 255 255"));
            robjchunk2.addData(new DictChunkData(dict2));
            chunksResult.Add(robjchunk2);

            RiffChunk robjchunkibl          = new RiffChunk("rOBJ");
            List <(string, string)> dictibl = new List <(string, string)>();

            dictibl.Add(("_type", "_ibl"));
            dictibl.Add(("_i", "1"));
            dictibl.Add(("_rot", "0"));
            robjchunkibl.addData(new DictChunkData(dictibl));
            chunksResult.Add(robjchunkibl);

            RiffChunk robjchunkatm          = new RiffChunk("rOBJ");
            List <(string, string)> dictatm = new List <(string, string)>();

            dictatm.Add(("_type", "_atm"));
            dictatm.Add(("_ray_d", "0.4"));
            dictatm.Add(("_ray_k", "45 104 255"));
            dictatm.Add(("_mie_d", "0.4"));
            dictatm.Add(("_mie_k", "255 255 255"));
            dictatm.Add(("_mie_g", "0.85"));
            dictatm.Add(("_o3_d", "0"));
            dictatm.Add(("_o3_k", "105 255 110"));
            robjchunkatm.addData(new DictChunkData(dictatm));
            chunksResult.Add(robjchunkatm);

            RiffChunk robjchunkfoguni          = new RiffChunk("rOBJ");
            List <(string, string)> dictfoguni = new List <(string, string)>();

            dictfoguni.Add(("_type", "_fog_uni"));
            dictfoguni.Add(("_d", "0"));
            dictfoguni.Add(("_k", "255 255 255"));
            dictfoguni.Add(("_g", "0"));
            robjchunkfoguni.addData(new DictChunkData(dictfoguni));
            chunksResult.Add(robjchunkfoguni);

            RiffChunk robjchunklens          = new RiffChunk("rOBJ");
            List <(string, string)> dictlens = new List <(string, string)>();

            dictlens.Add(("_type", "_lens"));
            dictlens.Add(("_prof", "0"));
            dictlens.Add(("_fov", "45"));
            dictlens.Add(("_aperture", "0.25"));
            dictlens.Add(("_blade_n", "0"));
            dictlens.Add(("_blade_r", "0"));
            robjchunklens.addData(new DictChunkData(dictlens));
            chunksResult.Add(robjchunklens);

            RiffChunk robjchunkfilm          = new RiffChunk("rOBJ");
            List <(string, string)> dictfilm = new List <(string, string)>();

            dictfilm.Add(("_type", "_film"));
            dictfilm.Add(("_expo", "1"));
            dictfilm.Add(("_vig", "0"));
            dictfilm.Add(("_aces", "0"));
            dictfilm.Add(("_gam", "2.2"));
            robjchunkfilm.addData(new DictChunkData(dictfilm));
            chunksResult.Add(robjchunkfilm);

            RiffChunk robjchunk7          = new RiffChunk("rOBJ");
            List <(string, string)> dict7 = new List <(string, string)>();

            dict7.Add(("_type", "_bloom"));
            dict7.Add(("_mix", "0.5"));
            dict7.Add(("_scale", "0"));
            dict7.Add(("_aspect", "0"));
            dict7.Add(("_treshhold", "1"));
            robjchunk7.addData(new DictChunkData(dict7));
            chunksResult.Add(robjchunk7);

            RiffChunk robjchunk8          = new RiffChunk("rOBJ");
            List <(string, string)> dict8 = new List <(string, string)>();

            dict8.Add(("_type", "_ground"));
            dict8.Add(("_color", "80 80 80"));
            dict8.Add(("_hor", "0.1"));
            robjchunk8.addData(new DictChunkData(dict8));
            chunksResult.Add(robjchunk8);

            RiffChunk robjchunk9          = new RiffChunk("rOBJ");
            List <(string, string)> dict9 = new List <(string, string)>();

            dict9.Add(("_type", "_bg"));
            dict9.Add(("_color", "0 0 0"));
            robjchunk9.addData(new DictChunkData(dict9));
            chunksResult.Add(robjchunk9);

            RiffChunk robjchunk10          = new RiffChunk("rOBJ");
            List <(string, string)> dict10 = new List <(string, string)>();

            dict10.Add(("_type", "_edge"));
            dict10.Add(("_color", "0 0 0"));
            dict10.Add(("_width", "0.2"));
            robjchunk10.addData(new DictChunkData(dict10));
            chunksResult.Add(robjchunk10);

            RiffChunk robjchunk11          = new RiffChunk("rOBJ");
            List <(string, string)> dict11 = new List <(string, string)>();

            dict11.Add(("_type", "_grid"));
            dict11.Add(("_color", "0 0 0"));
            dict11.Add(("_spacing", "1"));
            dict11.Add(("_width", "0.02"));
            dict11.Add(("_display", "0"));
            robjchunk11.addData(new DictChunkData(dict11));
            chunksResult.Add(robjchunk11);

            RiffChunk robjchunksetting          = new RiffChunk("rOBJ");
            List <(string, string)> dictsetting = new List <(string, string)>();

            dictsetting.Add(("_type", "_setting"));
            dictsetting.Add(("_ground", "1"));
            dictsetting.Add(("_grid", "0"));
            dictsetting.Add(("_edge", "0"));
            dictsetting.Add(("_bg_c", "0"));
            dictsetting.Add(("_bg_a", "0"));
            dictsetting.Add(("_scale", "1 1 1"));
            dictsetting.Add(("_cell", "1"));
            robjchunksetting.addData(new DictChunkData(dictsetting));
            chunksResult.Add(robjchunksetting);

            return(chunksResult);
        }
        public static void IMToVoxel(IntermediateMap map, string outfileName, int modelSizeX, int modelSizeY, int modelSizeZ)
        {
            FileStream stream = new FileStream(outfileName, FileMode.Create, FileAccess.Write,
                                               FileShare.Write);
            BinaryWriter writer = new BinaryWriter(stream);

            //Standard opening
            writer.Write("VOX ".ToCharArray());
            writer.Write(150); //Version
            writer.Write("MAIN".ToCharArray());
            writer.Write(0);   //No chunk data in main

            //List of chunks
            List <RiffChunk> chunks = new List <RiffChunk>();

            Palette palette = map.palette;

            //Setup for staging nodes
            ResetNodeID();
            IDForGroup = new List <int>();
            int masterGRPID = GetNextNodeID(); //Pass to master Translate
            List <RiffChunk> modelStagings = new List <RiffChunk>();
            int modelID = 0;

            //Seperate the world into regions that become a model each
            int mapheight = map.sizeZ;

            for (int x = 0; x < map.sizeX; x += modelSizeX)
            {
                Console.Write("|");
                for (int y = 0; y < map.sizeY; y += modelSizeY)
                {
                    for (int z = 0; z < mapheight + modelSizeZ; z += modelSizeZ) //Map may not be that high, but getListOfVoxels will just return nothing for out of bounds values.
                    {
                        //The function will limit sizes to actual map boundaries
                        List <Voxel> voxels = map.getListOfVoxels(x, x + modelSizeX, y, y + modelSizeY, z, z + modelSizeZ);
                        //Find out if chunk even has any voxels
                        if (voxels.Count == 0)
                        {
                            //Don't create the object if there are no voxels
                            continue;
                        }

                        //I've not checked that this is just xyz, assuming it is
                        RiffChunk size = new RiffChunk("SIZE");
                        size.addData(new IntChunkData(modelSizeX));
                        size.addData(new IntChunkData(modelSizeY));
                        size.addData(new IntChunkData(modelSizeZ));
                        chunks.Add(size);

                        //Get a region of voxels and make them a model
                        RiffChunk xyzi = new RiffChunk("XYZI");
                        xyzi.addData(new IntChunkData(voxels.Count));
                        foreach (Voxel voxel in voxels)
                        {
                            try
                            {
                                xyzi.addData(new VoxelChunkData(Convert.ToByte(voxel.x - x), Convert.ToByte(voxel.y - y), Convert.ToByte(voxel.z - z), Convert.ToByte(voxel.colorIndex)));
                            } catch (Exception e)
                            {
                                Console.WriteLine("Byte overflow with voxel " + voxel.x + ", " + voxel.y + ", " + voxel.z + ". With object xyz being " + x + ", " + y + "," + z);
                                Console.WriteLine("Color index of " + voxel.colorIndex);
                                throw e;
                            }
                        }
                        chunks.Add(xyzi);

                        //Create shape and translate node for the model
                        modelStagings.AddRange(CreateStagingChunksForModel(x, y, z, modelID, modelSizeX, modelSizeY, modelSizeZ)); //Create translate and shape noded for model
                        //ModelID isn't written to file, it's just the order the models appear
                        modelID++;
                    }
                }
            }

            //Master group node
            RiffChunk masterGRP = new RiffChunk("nGRP");

            masterGRP.addData(new IntChunkData(masterGRPID));
            masterGRP.addData(new DictChunkData());       //empty dict
            masterGRP.addData(new IntChunkData(modelID)); //Number of models
            foreach (int nodeID in IDForGroup)
            {
                masterGRP.addData(new IntChunkData(nodeID));
            }

            //Master translate node
            RiffChunk masterTRN = new RiffChunk("nTRN");

            masterTRN.addData(new IntChunkData(0));  //Assuming top node has to be number 0
            masterTRN.addData(new DictChunkData());  //Empty dict
            masterTRN.addData(new IntChunkData(masterGRPID));
            masterTRN.addData(new IntChunkData(-1)); //Reserved
            masterTRN.addData(new IntChunkData(-1)); //Layer ID
            masterTRN.addData(new IntChunkData(1));  //Number of frames is always 1
            masterTRN.addData(new DictChunkData());  //Empty dict. No translation of master

            //Put in all the staging chunks
            chunks.Add(masterTRN);
            chunks.Add(masterGRP);
            chunks.AddRange(modelStagings);


            //Add in all the layer chunks. This may be unneeded
            chunks.AddRange(CreateLayrChunks());

            //RGBA palette chunk
            chunks.Add(palette.getPaletteChunk());

            //Material chunks. May be unneeded
            for (int i = 1; i <= 256; i++)
            {
                chunks.Add(CreateMatlChunk(i));
            }

            //Whatever the robj chunks are...
            chunks.AddRange(CreateROBJChunks());

            //Write in the main chunk child size field
            int mainChunkChildDataSize = 0;

            foreach (RiffChunk chunk in chunks)
            {
                mainChunkChildDataSize += chunk.getChunkSize();
            }
            writer.Write(mainChunkChildDataSize);

            Console.Write("|");
            //Write all those chunks
            foreach (RiffChunk chunk in chunks)
            {
                chunk.writeChunk(writer);
            }
            Console.Write("|");

            //Done
            writer.Close();
            stream.Close();
            Console.WriteLine("");
        }