This page hosts a formal specification of MagicaVoxel File using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
digraph {
rankdir=LR;
node [shape=plaintext];
subgraph cluster__magicavoxel_vox {
label="MagicavoxelVox";
graph[style=dotted];
magicavoxel_vox__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="magic_pos">0</TD><TD PORT="magic_size">4</TD><TD></TD><TD PORT="magic_type">magic</TD></TR>
<TR><TD PORT="version_pos">4</TD><TD PORT="version_size">4</TD><TD>u4le</TD><TD PORT="version_type">version</TD></TR>
<TR><TD PORT="main_pos">8</TD><TD PORT="main_size">...</TD><TD>Chunk</TD><TD PORT="main_type">main</TD></TR>
</TABLE>>];
subgraph cluster__chunk {
label="MagicavoxelVox::Chunk";
graph[style=dotted];
chunk__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="chunk_id_pos">0</TD><TD PORT="chunk_id_size">4</TD><TD>u4be→ChunkType</TD><TD PORT="chunk_id_type">chunk_id</TD></TR>
<TR><TD PORT="num_bytes_of_chunk_content_pos">4</TD><TD PORT="num_bytes_of_chunk_content_size">4</TD><TD>u4le</TD><TD PORT="num_bytes_of_chunk_content_type">num_bytes_of_chunk_content</TD></TR>
<TR><TD PORT="num_bytes_of_children_chunks_pos">8</TD><TD PORT="num_bytes_of_children_chunks_size">4</TD><TD>u4le</TD><TD PORT="num_bytes_of_children_chunks_type">num_bytes_of_children_chunks</TD></TR>
<TR><TD PORT="chunk_content_pos">12</TD><TD PORT="chunk_content_size">...</TD><TD>switch (chunk_id)</TD><TD PORT="chunk_content_type">chunk_content</TD></TR>
<TR><TD PORT="children_chunks_pos">...</TD><TD PORT="children_chunks_size">...</TD><TD>Chunk</TD><TD PORT="children_chunks_type">children_chunks</TD></TR>
<TR><TD COLSPAN="4" PORT="children_chunks__repeat">repeat to end of stream</TD></TR>
</TABLE>>];
chunk__seq_chunk_content_switch [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#F0F2E4">case</TD><TD BGCOLOR="#F0F2E4">type</TD></TR>
<TR><TD>:chunk_type_size</TD><TD PORT="case0">Size</TD></TR>
<TR><TD>:chunk_type_matt</TD><TD PORT="case1">Matt</TD></TR>
<TR><TD>:chunk_type_rgba</TD><TD PORT="case2">Rgba</TD></TR>
<TR><TD>:chunk_type_xyzi</TD><TD PORT="case3">Xyzi</TD></TR>
<TR><TD>:chunk_type_pack</TD><TD PORT="case4">Pack</TD></TR>
</TABLE>>];
}
subgraph cluster__size {
label="MagicavoxelVox::Size";
graph[style=dotted];
size__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="size_x_pos">0</TD><TD PORT="size_x_size">4</TD><TD>u4le</TD><TD PORT="size_x_type">size_x</TD></TR>
<TR><TD PORT="size_y_pos">4</TD><TD PORT="size_y_size">4</TD><TD>u4le</TD><TD PORT="size_y_type">size_y</TD></TR>
<TR><TD PORT="size_z_pos">8</TD><TD PORT="size_z_size">4</TD><TD>u4le</TD><TD PORT="size_z_type">size_z</TD></TR>
</TABLE>>];
}
subgraph cluster__rgba {
label="MagicavoxelVox::Rgba";
graph[style=dotted];
rgba__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="colors_pos">0</TD><TD PORT="colors_size">4</TD><TD>Color</TD><TD PORT="colors_type">colors</TD></TR>
<TR><TD COLSPAN="4" PORT="colors__repeat">repeat 256 times</TD></TR>
</TABLE>>];
}
subgraph cluster__pack {
label="MagicavoxelVox::Pack";
graph[style=dotted];
pack__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="num_models_pos">0</TD><TD PORT="num_models_size">4</TD><TD>u4le</TD><TD PORT="num_models_type">num_models</TD></TR>
</TABLE>>];
}
subgraph cluster__matt {
label="MagicavoxelVox::Matt";
graph[style=dotted];
matt__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="id_pos">0</TD><TD PORT="id_size">4</TD><TD>u4le</TD><TD PORT="id_type">id</TD></TR>
<TR><TD PORT="material_type_pos">4</TD><TD PORT="material_type_size">4</TD><TD>u4le→MaterialType</TD><TD PORT="material_type_type">material_type</TD></TR>
<TR><TD PORT="material_weight_pos">8</TD><TD PORT="material_weight_size">4</TD><TD>f4le</TD><TD PORT="material_weight_type">material_weight</TD></TR>
<TR><TD PORT="property_bits_pos">12</TD><TD PORT="property_bits_size">4</TD><TD>u4le</TD><TD PORT="property_bits_type">property_bits</TD></TR>
<TR><TD PORT="plastic_pos">16</TD><TD PORT="plastic_size">4</TD><TD>f4le</TD><TD PORT="plastic_type">plastic</TD></TR>
<TR><TD PORT="roughness_pos">20</TD><TD PORT="roughness_size">4</TD><TD>f4le</TD><TD PORT="roughness_type">roughness</TD></TR>
<TR><TD PORT="specular_pos">24</TD><TD PORT="specular_size">4</TD><TD>f4le</TD><TD PORT="specular_type">specular</TD></TR>
<TR><TD PORT="ior_pos">28</TD><TD PORT="ior_size">4</TD><TD>f4le</TD><TD PORT="ior_type">ior</TD></TR>
<TR><TD PORT="attenuation_pos">32</TD><TD PORT="attenuation_size">4</TD><TD>f4le</TD><TD PORT="attenuation_type">attenuation</TD></TR>
<TR><TD PORT="power_pos">36</TD><TD PORT="power_size">4</TD><TD>f4le</TD><TD PORT="power_type">power</TD></TR>
<TR><TD PORT="glow_pos">40</TD><TD PORT="glow_size">4</TD><TD>f4le</TD><TD PORT="glow_type">glow</TD></TR>
<TR><TD PORT="is_total_power_pos">44</TD><TD PORT="is_total_power_size">4</TD><TD>f4le</TD><TD PORT="is_total_power_type">is_total_power</TD></TR>
</TABLE>>];
matt__inst__has_is_total_power [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_is_total_power</TD><TD>(property_bits & 128) != 0</TD></TR>
</TABLE>>];
matt__inst__has_plastic [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_plastic</TD><TD>(property_bits & 1) != 0</TD></TR>
</TABLE>>];
matt__inst__has_attenuation [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_attenuation</TD><TD>(property_bits & 16) != 0</TD></TR>
</TABLE>>];
matt__inst__has_power [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_power</TD><TD>(property_bits & 32) != 0</TD></TR>
</TABLE>>];
matt__inst__has_roughness [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_roughness</TD><TD>(property_bits & 2) != 0</TD></TR>
</TABLE>>];
matt__inst__has_specular [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_specular</TD><TD>(property_bits & 4) != 0</TD></TR>
</TABLE>>];
matt__inst__has_ior [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_ior</TD><TD>(property_bits & 8) != 0</TD></TR>
</TABLE>>];
matt__inst__has_glow [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>has_glow</TD><TD>(property_bits & 64) != 0</TD></TR>
</TABLE>>];
}
subgraph cluster__xyzi {
label="MagicavoxelVox::Xyzi";
graph[style=dotted];
xyzi__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="num_voxels_pos">0</TD><TD PORT="num_voxels_size">4</TD><TD>u4le</TD><TD PORT="num_voxels_type">num_voxels</TD></TR>
<TR><TD PORT="voxels_pos">4</TD><TD PORT="voxels_size">4</TD><TD>Voxel</TD><TD PORT="voxels_type">voxels</TD></TR>
<TR><TD COLSPAN="4" PORT="voxels__repeat">repeat num_voxels times</TD></TR>
</TABLE>>];
}
subgraph cluster__color {
label="MagicavoxelVox::Color";
graph[style=dotted];
color__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="r_pos">0</TD><TD PORT="r_size">1</TD><TD>u1</TD><TD PORT="r_type">r</TD></TR>
<TR><TD PORT="g_pos">1</TD><TD PORT="g_size">1</TD><TD>u1</TD><TD PORT="g_type">g</TD></TR>
<TR><TD PORT="b_pos">2</TD><TD PORT="b_size">1</TD><TD>u1</TD><TD PORT="b_type">b</TD></TR>
<TR><TD PORT="a_pos">3</TD><TD PORT="a_size">1</TD><TD>u1</TD><TD PORT="a_type">a</TD></TR>
</TABLE>>];
}
subgraph cluster__voxel {
label="MagicavoxelVox::Voxel";
graph[style=dotted];
voxel__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="x_pos">0</TD><TD PORT="x_size">1</TD><TD>u1</TD><TD PORT="x_type">x</TD></TR>
<TR><TD PORT="y_pos">1</TD><TD PORT="y_size">1</TD><TD>u1</TD><TD PORT="y_type">y</TD></TR>
<TR><TD PORT="z_pos">2</TD><TD PORT="z_size">1</TD><TD>u1</TD><TD PORT="z_type">z</TD></TR>
<TR><TD PORT="color_index_pos">3</TD><TD PORT="color_index_size">1</TD><TD>u1</TD><TD PORT="color_index_type">color_index</TD></TR>
</TABLE>>];
}
}
magicavoxel_vox__seq:main_type -> chunk__seq [style=bold];
chunk__seq:chunk_content_type -> chunk__seq_chunk_content_switch [style=bold];
chunk__seq_chunk_content_switch:case0 -> size__seq [style=bold];
chunk__seq_chunk_content_switch:case1 -> matt__seq [style=bold];
chunk__seq_chunk_content_switch:case2 -> rgba__seq [style=bold];
chunk__seq_chunk_content_switch:case3 -> xyzi__seq [style=bold];
chunk__seq_chunk_content_switch:case4 -> pack__seq [style=bold];
chunk__seq:chunk_id_type -> chunk__seq:chunk_content_type [color="#404040"];
chunk__seq:children_chunks_type -> chunk__seq [style=bold];
rgba__seq:colors_type -> color__seq [style=bold];
matt__seq:property_bits_type -> matt__inst__has_is_total_power [color="#404040"];
matt__seq:property_bits_type -> matt__inst__has_plastic [color="#404040"];
matt__seq:property_bits_type -> matt__inst__has_attenuation [color="#404040"];
matt__seq:property_bits_type -> matt__inst__has_power [color="#404040"];
matt__seq:property_bits_type -> matt__inst__has_roughness [color="#404040"];
matt__seq:property_bits_type -> matt__inst__has_specular [color="#404040"];
matt__seq:property_bits_type -> matt__inst__has_ior [color="#404040"];
matt__seq:property_bits_type -> matt__inst__has_glow [color="#404040"];
xyzi__seq:voxels_type -> voxel__seq [style=bold];
xyzi__seq:num_voxels_type -> xyzi__seq:voxels__repeat [color="#404040"];
}