Docs/Modules/mc3togltf

Purpose

mc3togltf is a standalone command-line binary — separate from the editor — that takes an MC3 XML scene as input and writes a glTF 2.0 file (JSON + external .bin) or a GLB (self-contained binary). It is required for the editor's File → Export GLB command (Ctrl+E).

Usage

# Export to GLB (binary, self-contained)
./cmake-build-debug/mc3togltf/mc3togltf test/house.mc3.xml /tmp/house.glb

# Export to glTF JSON (+ external .bin)
./cmake-build-debug/mc3togltf/mc3togltf test/house.mc3.xml /tmp/house.gltf

# Allow approximate CSG export (children as separate meshes)
./cmake-build-debug/mc3togltf/mc3togltf --allow-approximate-csg scene.mc3.xml out.glb

Building

mc3togltf is included in the top-level build and builds automatically with ninja -C cmake-build-debug. The binary lands at cmake-build-debug/mc3togltf/mc3togltf.

The converter has no dependency on CNA, ImGui, or any graphics library — only the core mc3 library and tinyxml2.

Export Support Matrix

FeatureExportedNotes
Box, Cube
Sphere
Cylinder, Cone
Planesize is vec2 (W × D)
Torus, Capsule, Disk
Grid, Ico-sphere
Extrude (all path types)
Mesh (src= OBJ)OBJ loaded at export time
Materials (PBR, textures)
Lights, Cameras
Instances (definitions)Expanded to meshes at export
Animation: position/rotation/scaleExported as glTF animations[]
Animation: visible, deform.*, material.*No glTF equivalent; silently skipped
CSG (union/difference/intersection)⚠️Hard fail by default; use --allow-approximate-csg to export children as separate meshes

Key Source Files

FileRole
src/main.cppCLI entry point: parse args, call Mc3Document::loadFromFile(), call GltfExporter, write output.
src/GltfExporter.hpp/.cppConverts an MC3 document to glTF JSON or GLB. Handles geometry, materials, textures, and animations.
src/MeshBuilder.hpp/.cppTessellates MC3 objects (primitives, extrusions, groups) into triangle meshes for glTF accessors.
src/MathUtils.hppInline math: Euler → quaternion, matrix operations.
test/gltf_test.pyPython test suite: 39 assertions on the output glTF/GLB JSON.

Export Pipeline

.mc3.xml
  │
  ▼ Mc3Document::loadFromFile()   (shared core mc3 library)
MC3 Document (in-memory)
  │
  ▼ GltfExporter::exportDocument()
  │
  ├── For each object: MeshBuilder → triangulated geometry
  │     → glTF mesh / primitive / accessor / bufferView
  │
  ├── For each material → glTF material (PBR metallic-roughness)
  │
  ├── For each texture → glTF image + sampler + texture
  │
  ├── For each Mc3Action → glTF animation
  │     channels: position (VEC3), rotation (VEC4 quaternion), scale (VEC3)
  │     cubic bezier → sampled at 30 fps → LINEAR glTF interpolation
  │
  └── Write JSON header + binary buffer
        .gltf → JSON file + separate .bin
        .glb  → single binary envelope (JSON chunk + BIN chunk)

Animation Export Notes

Test Suite

mc3togltf/test/gltf_test.py contains 39 Python assertions. Registered as a CTest test (top-level build includes mc3togltf):

# Run via CTest (from the main cmake-build-debug)
ctest --test-dir cmake-build-debug -V -R mc3togltf

# Run directly
python3 mc3togltf/test/gltf_test.py \
    cmake-build-debug/mc3togltf/mc3togltf \
    test/animation_test.mc3.xml \
    test/house.mc3.xml

Known Limitations

📋
  • CSG boolean geometry is not evaluated during export (Manifold not linked). By default, any CSG node causes an error. Pass --allow-approximate-csg to export child primitives as separate meshes instead (geometrically incorrect).
  • UV mapping overrides from <uv_mapping> are not yet applied during mesh tessellation.
  • visible, deform.*, and material.* animation channels are silently skipped — no glTF equivalent.