跳转至

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)

Godot 4.3 License: MIT

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 .vox reader (MAIN/PACK/SIZE/XYZI/RGBA/MATL/nTRN/nGRP/nSHP/FRAM).
  • Scene graph — decodes the nTRN/nGRP/nSHP hierarchy into instances with per-instance transform, rotation (_r) and hidden flags.
  • Animation — reads nTRN keyframes (_f frame dict) into per-instance per-frame world transforms; the runtime viewer can play them.
  • Writer — serialize a VoxDocument back 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 .vox as an importable Mesh resource in the editor (one surface per model, pickable frame via import option).
  • Runtime viewer — drop-in Node3D that builds meshes for every visible instance and plays .vox animations.

Installation

Option A — From the Godot Asset Library

  1. Open the Asset Library in the Godot editor (AssetLib tab).
  2. Search "Voxel Tool", install it.
  3. Enable the Voxel Tool plugin in Project → Project Settings → Plugins.

Option B — Manual (copy the addon)

  1. Download / clone this repository.
  2. Copy addons/voxel_tool/ into your project's addons/ folder.
  3. Enable the Voxel Tool plugin in Project → Project Settings → Plugins.

The addons/voxel_tool/ folder is all you need at runtime. The demo/, test/ and tools/ 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.