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); }
/// <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); }