public static void processTerrainH(string unit, string subfolder, Color basis, bool still, bool autoshade, bool addFloor)
        {
            string colorName = basis.ToString();

            colorName = System.Text.RegularExpressions.Regex.Match(colorName, "(?<=\\[)[^\\]]+").Value;

            Console.WriteLine("Processing: " + unit + ", base color " + colorName);
            List <MagicaVoxelData> voxes;

            if (addFloor)
            {
                BinaryReader bin      = new BinaryReader(File.Open("Forays/" + subfolder + "/" + unit + "_H.vox", FileMode.Open));
                BinaryReader binFloor = new BinaryReader(File.Open("Forays/" + subfolder + "/Floor_H.vox", FileMode.Open));
                IEnumerable <MagicaVoxelData> structure = ((autoshade) ? VoxelLogic.AutoShadeH(VoxelLogic.FromMagicaRaw(bin), 16, 16, 16) : VoxelLogic.FromMagicaRaw(bin))
                                                          .Select(v => VoxelLogic.AlterVoxel(v, 0, 0, 1, v.color));
                voxes = structure.Concat((autoshade) ? VoxelLogic.AutoShadeH(VoxelLogic.FromMagicaRaw(binFloor), 16, 16, 16) : VoxelLogic.FromMagicaRaw(binFloor)).ToList();
            }
            else
            {
                BinaryReader bin = new BinaryReader(File.Open("Forays/" + subfolder + "/" + unit + "_H.vox", FileMode.Open));
                voxes = VoxelLogic.PlaceShadowsH((autoshade) ? VoxelLogic.AutoShadeH(VoxelLogic.FromMagicaRaw(bin), 16, 16, 16) : VoxelLogic.FromMagicaRaw(bin));
            }

            Directory.CreateDirectory("vox/Forays/" + altFolder + subfolder + "/");
            WriteVOX("vox/Forays/" + altFolder + subfolder + "/" + unit + "_" + colorName + ".vox", voxes, 16, 16, 20, basis);
            MagicaVoxelData[] parsed = voxes.ToArray();

            int framelimit = 1;


            string folder = (altFolder + subfolder + "/");

            Directory.CreateDirectory(folder);
            for (int f = 0; f < framelimit; f++)
            { //
                for (int dir = 0; dir < 4; dir++)
                {
                    Bitmap b = processHFrame(parsed, dir, f, framelimit, still, false);
                    b.Save(folder + unit + "_" + colorName + "_face" + dir + "_" + f + ".png", ImageFormat.Png);
                    b.Dispose();
                }
            }
            Directory.CreateDirectory("gifs/Forays/" + altFolder + subfolder + "/");
            ProcessStartInfo startInfo = new ProcessStartInfo(@"convert.exe");

            startInfo.UseShellExecute = false;
            string s = "";

            s = folder + unit + "_" + colorName + "_face* ";
            startInfo.Arguments = "-dispose background -delay 25 -loop 0 " + s + " gifs/Forays/" + altFolder + subfolder + "/" + unit + "_" + colorName + "_animated.gif";
            Process.Start(startInfo).WaitForExit();
        }
        public static void processUnitH(string unit, Color basis, bool autoshade)
        {
            string colorName = basis.ToString();

            colorName = System.Text.RegularExpressions.Regex.Match(colorName, "(?<=\\[)[^\\]]+").Value;
            Console.WriteLine("Processing: " + unit + ", base color " + colorName);
            BinaryReader           bin   = new BinaryReader(File.Open("Forays/" + unit + "_H.vox", FileMode.Open));
            List <MagicaVoxelData> voxes = VoxelLogic.PlaceShadowsH(VoxelLogic.FromMagicaRaw(bin));

            setupCurrentColorsH(basis);
            Directory.CreateDirectory("vox/Forays/" + altFolder);
            WriteVOX("vox/Forays/" + altFolder + unit + "_" + colorName + ".vox", voxes, 16, 16, 20, basis);
            MagicaVoxelData[] parsed = voxes.ToArray();

            int framelimit = 1;

            string folder = (altFolder);       //"color" + i;

            Directory.CreateDirectory(folder); //("color" + i);
            for (int f = 0; f < framelimit; f++)
            {                                  //
                for (int dir = 0; dir < 4; dir++)
                {
                    Bitmap b = processHFrame(parsed, dir, f, framelimit, true, true);
                    b.Save(folder + unit + "_" + colorName + "_face" + dir + "_" + f + ".png", ImageFormat.Png);
                    b.Dispose();
                }
            }


            Directory.CreateDirectory("gifs/Forays/" + altFolder);
            ProcessStartInfo startInfo = new ProcessStartInfo(@"convert.exe");

            startInfo.UseShellExecute = false;
            string s = "";

            s = folder + unit + "_" + colorName + "_face* ";
            startInfo.Arguments = "-dispose background -delay 25 -loop 0 " + s + " gifs/Forays/" + altFolder + unit + "_" + colorName + "_animated.gif";
            Process.Start(startInfo).WaitForExit();
        }
        static void Main(string[] args)
        {
            VoxelLogic.Initialize();
            altFolder = "Forays/";
            Directory.CreateDirectory("Forays/" + altFolder + "Caves/");

            VoxelLogic.hpalettecount = hpalettecount = 1;
            VoxelLogic.hcolorcount   = hcolorcount = 62;
            VoxelLogic.clear         = (byte)(253 - (VoxelLogic.hcolorcount - 1) * 4);

            hrendered            = storeColorCubesH(Color.Honeydew);
            VoxelLogic.hrendered = hrendered;


            processUnitH("Human_Male", Color.DarkSlateBlue, false);
            processUnitH("Human_Female", Color.Magenta, false);

            processUnitH("Warrior_Male", Color.DimGray, false);
            processUnitH("Warrior_Female", Color.Gray, false);
            processUnitH("Mage_Male", Color.Chartreuse, false);
            processUnitH("Mage_Female", Color.HotPink, false);
            processUnitH("Rogue_Male", Color.Goldenrod, false);
            processUnitH("Rogue_Female", Color.Goldenrod, false);
            processUnitH("Priest_Male", Color.GhostWhite, false);
            processUnitH("Priest_Female", Color.DarkGray, false);

            processWaterH("Caves");


            processTerrainH("Floor", "Caves", Color.LightGray, true, false, false);
            processTerrainH("Wall_Straight", "Caves", Color.LightGray, true, false, false);
            processTerrainH("Wall_Corner", "Caves", Color.LightGray, true, false, false);
            processTerrainH("Wall_Tee", "Caves", Color.LightGray, true, false, false);
            processTerrainH("Wall_Cross", "Caves", Color.LightGray, true, false, false);
            processTerrainH("Door_Closed", "Caves", Color.SaddleBrown, true, false, false);
            processTerrainH("Door_Open", "Caves", Color.SaddleBrown, true, false, false);
        }
        /// <summary>
        /// Write a MagicaVoxel .vox format file from a List of MagicaVoxelData and a palette from this program to use.
        /// </summary>
        /// <param name="filename">Name of the file to write.</param>
        /// <param name="voxelData">The voxels in indexed-color mode.</param>
        /// <returns>The voxel chunk data for the MagicaVoxel .vox file.</returns>
        public static void WriteVOX(string filename, List <MagicaVoxelData> voxelData, int xSize, int ySize, int zSize, Color basis)
        {
            // check out http://voxel.codeplex.com/wikipage?title=VOX%20Format&referringTitle=Home for the file format used below

            Stream       stream = File.OpenWrite(filename);
            BinaryWriter bin    = new BinaryWriter(stream);

            bool[,,] taken = new bool[xSize, ySize, zSize].Fill(false);

            List <byte> voxelsRaw = new List <byte>(voxelData.Count * 4);
            string      colorName = basis.ToString();

            colorName = System.Text.RegularExpressions.Regex.Match(colorName, "(?<=\\[)[^\\]]+").Value;

            byte[] colors = new byte[1024];
            hrendered = storeColorCubesH(basis);
            foreach (MagicaVoxelData mvd in voxelData)
            {
                int unshaded = VoxelLogic.WithoutShadingK(mvd.color);
                if (mvd.x < xSize && mvd.y < ySize && mvd.z < zSize && !taken[mvd.x, mvd.y, mvd.z] && unshaded != hcolorcount - 2 && mvd.color > 253 - hcolorcount * 4)
                {
                    int current_color = ((255 - mvd.color) % 4 == 0) ? unshaded + hcolorcount : unshaded;
                    if ((255 - mvd.color) % 4 != 0 && current_color >= hcolorcount)
                    {
                        continue;
                    }

                    voxelsRaw.Add((byte)(mvd.x));
                    voxelsRaw.Add((byte)(mvd.y));
                    voxelsRaw.Add((byte)(mvd.z));
                    voxelsRaw.Add((byte)(mvd.color));
                    taken[mvd.x, mvd.y, mvd.z] = true;
                }
            }
            for (int i = 1; i < 256; i++)
            {
                if ((253 - i) % 4 == 0 && (253 - i) / 4 < hcolorcount)
                {
                    colors[(i - 1) * 4]     = hrendered[(253 - i) / 4][2 + rowWidthBytes];
                    colors[(i - 1) * 4 + 1] = hrendered[(253 - i) / 4][1 + rowWidthBytes];
                    colors[(i - 1) * 4 + 2] = hrendered[(253 - i) / 4][0 + rowWidthBytes];
                    colors[(i - 1) * 4 + 3] = hrendered[(253 - i) / 4][3 + rowWidthBytes];
                }
                else if ((255 - i) % 4 == 0 && hcolorcount + (255 - i) / 4 < hrendered.Length)
                {
                    colors[(i - 1) * 4]     = hrendered[(255 - i) / 4 + hcolorcount][2 + rowWidthBytes];
                    colors[(i - 1) * 4 + 1] = hrendered[(255 - i) / 4 + hcolorcount][1 + rowWidthBytes];
                    colors[(i - 1) * 4 + 2] = hrendered[(255 - i) / 4 + hcolorcount][0 + rowWidthBytes];
                    colors[(i - 1) * 4 + 3] = hrendered[(255 - i) / 4 + hcolorcount][3 + rowWidthBytes];
                }
                else
                {
                    colors[(i - 1) * 4]     = (byte)(VoxelLogic.mv_default_palette[i] & 0xff);
                    colors[(i - 1) * 4 + 1] = (byte)((VoxelLogic.mv_default_palette[i] >> 8) & 0xff);
                    colors[(i - 1) * 4 + 2] = (byte)((VoxelLogic.mv_default_palette[i] >> 16) & 0xff);
                    colors[(i - 1) * 4 + 3] = (byte)((VoxelLogic.mv_default_palette[i] >> 24) & 0xff);
                }
            }


            // a MagicaVoxel .vox file starts with a 'magic' 4 character 'VOX ' identifier
            bin.Write("VOX ".ToCharArray());
            // current version?
            bin.Write((int)150);

            bin.Write("MAIN".ToCharArray());
            bin.Write((int)0);
            bin.Write((int)12 + 12 + 12 + 4 + voxelsRaw.Count + 12 + 1024);

            bin.Write("SIZE".ToCharArray());
            bin.Write((int)12);
            bin.Write((int)0);
            bin.Write(xSize);
            bin.Write(ySize);
            bin.Write(zSize);

            bin.Write("XYZI".ToCharArray());
            bin.Write((int)(4 + voxelsRaw.Count));
            bin.Write((int)0);
            bin.Write((int)(voxelsRaw.Count / 4));
            bin.Write(voxelsRaw.ToArray());

            bin.Write("RGBA".ToCharArray());
            bin.Write((int)1024);
            bin.Write((int)0);
            bin.Write(colors);

            bin.Flush();
            bin.Close();
        }
        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);
        }
Example #6
0
        /// <summary>
        /// WAS PITCH originally, then ROLL
        /// </summary>
        /// <param name="q"></param>
        /// <returns></returns>
        public static float Yaw(this Quaternion q)
        {
            int pole = q.GimbalPole();

            return((pole == 0 ? (float)Math.Asin(VoxelLogic.Clamp(2 * (q.W * q.X - q.Z * q.Y), -1, 1)) : (float)(pole * Math.PI * 0.5)) * RadiansToDegrees);
        }