Skip to content

Instantly share code, notes, and snippets.

@sixones
Created March 11, 2025 21:54
Show Gist options
  • Save sixones/bea04953646557e19e76358ec7e560cc to your computer and use it in GitHub Desktop.
Save sixones/bea04953646557e19e76358ec7e560cc to your computer and use it in GitHub Desktop.
/**
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* Version 2, December 2004
*
* Everyone is permitted to copy and distribute verbatim or modified
* copies of this license document, and changing it is allowed as long
* as the name is changed.
*
* DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
* TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
*
* 0. You just DO WHAT THE FUCK YOU WANT TO.
**/
public static class VoxelExporter
{
public static void ExportToVoxFile(NativeList<VoxelBlock> voxelBlocks, NativeArray<PlanetBodySettings.BiomeColourSettings.Material> materials, string filePath)
{
if (File.Exists(filePath))
File.Delete(filePath);
Debug.Log($"Starting export with {voxelBlocks.Length} blocks");
var minPos = new float3(float.MaxValue);
var maxPos = new float3(float.MinValue);
// Find our actual bounds
foreach (VoxelBlock block in voxelBlocks)
{
minPos = math.min(minPos, block.position);
maxPos = math.max(maxPos, block.position);
}
// Ensure we include the final column block in the bounds.
maxPos += new float3(1);
using var writer = new BinaryWriter(File.Open(filePath, FileMode.Create));
writer.Write("VOX ".ToCharArray());
writer.Write(150);
writer.Write("MAIN".ToCharArray());
writer.Write(0);
long childrenSizePosition = writer.BaseStream.Position;
writer.Write(0);
var size = new int3(
(int)((maxPos.x - minPos.x + 1)),
(int)((maxPos.y - minPos.y + 1)),
(int)((maxPos.z - minPos.z + 1))
);
writer.Write("SIZE".ToCharArray());
writer.Write(12);
writer.Write(0);
writer.Write(size.x);
writer.Write(size.y);
writer.Write(size.z);
writer.Write("XYZI".ToCharArray());
writer.Write(4 + voxelBlocks.Length * 4);
writer.Write(0);
writer.Write(voxelBlocks.Length);
foreach (VoxelBlock block in voxelBlocks)
{
var blockPos = new int3(
(int)(block.position.x - minPos.x),
(int)(block.position.y - minPos.y),
(int)(block.position.z - minPos.z)
);
writer.Write((byte)blockPos.x);
writer.Write((byte)blockPos.y);
writer.Write((byte)blockPos.z);
writer.Write((byte)block.material);
}
// Simple palette
writer.Write("RGBA".ToCharArray());
writer.Write(256 * 4); // RGBA chunk content size
writer.Write(0);
// Write the palette
for (var i = 0; i < 256; i++)
{
if (i < materials.Length)
{
PlanetBodySettings.BiomeColourSettings.Material material = materials[i];
writer.Write((byte)(material.material.color.r * 255)); // R
writer.Write((byte)(material.material.color.g * 255)); // G
writer.Write((byte)(material.material.color.b * 255)); // B
writer.Write((byte)(material.material.color.a * 255)); // A
}
else
{
writer.Write(0); // R
writer.Write(0); // G
writer.Write(0); // B
writer.Write(0); // A
}
}
writer.Write("MATL");
writer.Write(materials.Length);
writer.Write(0);
for (var i = 0; i < materials.Length; i++)
{
writer.Write(i + 1);
writer.Write(0);
}
long endPosition = writer.BaseStream.Position;
writer.BaseStream.Position = childrenSizePosition;
writer.Write((int)(endPosition - childrenSizePosition - 4));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment