voxel-tool-godot¶
Pure GDScript MagicaVoxel .vox toolkit for Godot 4: parser, writer, greedy meshing, import plugin and runtime viewer.
| 项目信息 | |
|---|---|
| 仓库 | https://github.com/Maicarons/voxel-tool-godot |
| 主要语言 | GDScript |
| Stars | 0 |
| 类型 | 原创项目 |
| 许可证 | MIT |
| 最近更新 | 2026-08-12 |
Voxel Tool (Godot)¶
A MagicaVoxel .vox toolkit for Godot 4.3 — read, write, mesh, import and view
.vox voxel models directly inside the engine. This is the Godot port of
voxel-tool (the framework-agnostic
.vox library).
Features¶
- Parser — full MagicaVoxel
.voxreader (MAIN/PACK/SIZE/XYZI/RGBA/MATL/nTRN/nGRP/nSHP/FRAM). - Scene graph — decodes the
nTRN/nGRP/nSHPhierarchy into instances with per-instance transform, rotation (_r) and hidden flags. - Animation — reads
nTRNkeyframes (_fframe dict) into per-instance per-frame world transforms; the runtime viewer can play them. - Writer — serialize a
VoxDocumentback to.vox(round-trips the palette, materials and scene graph). - Greedy meshing — merges coplanar, same-colour, exposed faces into maximal rectangles, so mesh size scales with surface area, not voxel count.
- Import plugin — register
.voxas an importable Mesh resource in the editor (one surface per model, pickable frame via import option). - Runtime viewer — drop-in
Node3Dthat builds meshes for every visible instance and plays.voxanimations.
Installation¶
Option A — From the Godot Asset Library¶
- Open the Asset Library in the Godot editor (AssetLib tab).
- Search "Voxel Tool", install it.
- Enable the Voxel Tool plugin in Project → Project Settings → Plugins.
Option B — Manual (copy the addon)¶
- Download / clone this repository.
- Copy
addons/voxel_tool/into your project'saddons/folder. - Enable the Voxel Tool plugin in Project → Project Settings → Plugins.
The
addons/voxel_tool/folder is all you need at runtime. Thedemo/,test/andtools/folders are only for development.
Quick start¶
Runtime API (singleton VoxelTool)¶
Once the plugin is enabled, the global singleton VoxelTool is available everywhere:
## Parse a .vox file
var doc := VoxelTool.parse_file("res://models/my_scene.vox")
## Load as a Mesh (frame 0)
var mesh: ArrayMesh = VoxelTool.build_document_mesh(doc, 0)
## Write it back / round-trip
var bytes: PackedByteArray = VoxelTool.write(doc)
VoxelTool.write_file("user://out.vox", doc)
## Default MagicaVoxel palette (Array of 256 Color)
var palette: Array = VoxelTool.default_palette()
Runtime viewer (with animation)¶
extends Node3D
func _ready() -> void:
var doc := VoxelTool.parse_file("res://models/animated.vox")
var viewer := VoxelTool.create_viewer(doc) # returns a VoxelViewer (Node3D)
add_child(viewer)
if viewer.get_frame_count() > 1:
viewer.set_frame_rate(12)
viewer.play()
VoxelViewer exposes:
set_document(doc), play(), pause(), stop(), set_frame(i),
set_frame_rate(fps), is_playing(), get_frame_count().
Editor import¶
After enabling the plugin, select a .vox file in the FileSystem dock →
Import tab. Set the Frame option (default 0) and click Reimport.
The resource becomes a Mesh you can drop onto a MeshInstance3D.
API reference¶
| Class | Key methods |
|---|---|
VoxParser |
parse_file(path) -> VoxDocument, parse(bytes) -> VoxDocument |
VoxWriter |
write_file(path, doc) -> bool, write(doc) -> PackedByteArray |
VoxelMeshBuilder |
build_mesh(voxels, palette) -> ArrayMesh, build_document(doc, frame=0) -> ArrayMesh |
VoxPalette |
default_palette() -> Array[Color], from_rgba_bytes(stream), to_rgba_bytes(pal) |
VoxDocument |
version, models, palette, scene, materials, frame_count, get_palette(), model_count() |
VoxModel |
size: Vector3i, voxels: Array[Vector4i] (x, y, z, color_index) |
VoxInstance |
model_index, translation: Vector3i, rotation_index, hidden, name, frames |
VoxMaterial |
from_dict(dict) -> VoxMaterial |
VoxelViewer |
set_document, play, pause, stop, set_frame, set_frame_rate, is_playing, get_frame_count |
Data model:
VoxDocument
├─ models: Array[VoxModel] # geometry, each a list of (x,y,z,ci)
├─ palette: Array[Color] (256) # empty -> default MagicaVoxel palette
├─ scene: Array[VoxInstance] # placed instances (transform + animation)
├─ materials:Dictionary[int, VoxMaterial]
└─ frame_count: int
Coordinate system¶
VOX uses z-up; Godot uses y-up. The viewer and import mesh bake geometry
into VOX local space and apply a -90° rotation about X on the parent node so the
model stands upright in Godot. Vertex colours are converted from sRGB to linear
(Color.srgb_to_linear()) to match Godot's linear rendering pipeline.
Project structure¶
voxel-tool-godot/
├─ addons/voxel_tool/ # ← the plugin (copy this into your project)
│ ├─ vox/ # parser, writer, palette, document, model, instance, material
│ ├─ mesh/ # greedy meshing -> ArrayMesh
│ ├─ import/ # EditorImportPlugin (.vox -> Mesh)
│ ├─ editor/ # EditorPlugin entry (registers import + autoload)
│ ├─ VoxelTool.gd # runtime singleton API
│ ├─ VoxelViewer.gd # Node3D viewer with animation playback
│ └─ plugin.cfg
├─ demo/ # example project (scenes/scripts/models)
├─ test/ # headless self-test (run_tests.gd)
├─ tools/ # make_sample_vox.py fixture generator
├─ .github/workflows/ # CI (Godot 4.3 syntax check + self-test)
├─ project.godot
├─ README.md / README_zh.md
├─ LICENSE / CHANGELOG.md / CONTRIBUTING.md
Development & testing¶
Requires Godot 4.3 (stable) on PATH (or set GODOT_BIN to the executable).
## Headless self-test: parse fixture, assert, round-trip, build mesh
godot --headless --path . -s test/run_tests.gd
## Regenerate the sample fixture (needs Python 3)
python tools/make_sample_vox.py
CI (.github/workflows/ci.yml) downloads Godot 4.3, syntax-checks all .gd files
and runs the self-test on every push/PR.
License¶
MIT — see LICENSE. © 2026 Maicarons.