Skip to content

feat: Lua table DSL for scene description#6

Open
mtao wants to merge 5 commits into
feature/raycastingfrom
feature/lua-scene
Open

feat: Lua table DSL for scene description#6
mtao wants to merge 5 commits into
feature/raycastingfrom
feature/lua-scene

Conversation

@mtao
Copy link
Copy Markdown
Owner

@mtao mtao commented Mar 29, 2026

Summary

  • Adds a Lua-based scene description system using sol2 bindings (new lua meson option, default off)
  • Scene scripts return declarative tables that C++ parses into the existing scene graph — combining programmability (loops, functions, require()) with clean declarative syntax
  • Includes art-lua CLI runner, 4 example scenes, and 13 test cases (37 assertions)
  • Adds PBRT <-> Lua converter tools for importing real PBRT scene files

New Components

Component Files
Lua bindings src/lua/bind_{geometry,scene,camera,image,transform}.cpp, src/lua/bindings.cpp, src/lua/bind_internal.hpp
Scene loader src/lua/scene_loader.cpp, include/art/lua/scene_loader.hpp
Scene serializer src/lua/scene_serializer.cpp, include/art/lua/scene_serializer.hpp
CLI runner src/art_lua.cppart-lua scene.lua [--output path] [--width N] [--height N] [--accel bvh|linear]
Public API include/art/lua/bindings.hppload_bindings()
Example scenes scenes/{sphere,transforms,cornell_box,mesh_demo}.lua
Tests tests/test_scene_loader.cpp — 13 Catch2 test cases
Build system meson_options.txt (lua option), subprojects/sol2.wrap, subprojects/lua.wrap
PBRT tools tools/pbrt_to_lua.lua, tools/lua_to_pbrt.lua, tools/validate_roundtrip.lua

Scene DSL Format

return {
    render = { width = 800, height = 600, output = "scene.ppm", accelerator = "bvh" },
    camera = { position = {0,0,5}, target = {0,0,0}, up = {0,1,0} },
    scene = {
        { type = "sphere", transform = { translate = {1,0,0}, scale = 2 } },
        { type = "group", children = { { type = "box" }, { type = "disk" } } },
    },
}

PBRT Converter Tools

Three standalone Lua modules under tools/ (enabled via meson -Dtools=true, default on):

  • pbrt_to_lua.lua — Parses PBRT v3/v4 scene files and converts to ART Lua table DSL. Handles all major directives (LookAt, Camera, Film, Shape, Transform, ObjectBegin/End, Include/Import). Supports gzipped Include files (.pbrt.gz). Unsupported features (materials, lights, textures) are consumed gracefully and emitted as TODO comments. Can be used as a module (require("pbrt_to_lua")) or CLI script.

  • lua_to_pbrt.lua — Reverse converter from ART Lua scene tables to PBRT v3 format. Supports all ART geometry types with appropriate PBRT mappings.

  • validate_roundtrip.lua — Batch validator for testing PBRT->Lua conversion across scene file directories. Supports --max-size, --roundtrip, --verbose, --stop-on-error, --pbrt=<path> flags.

Validation Results

Full test corpus: 386 PBRT files (v3 + v4, under 5MB — files over 5MB are geometry fragments, not standalone scenes).

Validation Pass Fail Skipped
PBRT -> Lua syntax 386 0 0
pbrt --format verify 370 0 16

The 16 skipped files are curve-heavy scenes (hair, bunny-fur) where placeholder spheres generate >50MB PBRT output. All 370 verified files produce PBRT output that the official pbrt-v4 binary accepts without error.

Build & Test

git clone --depth=1 git@github.com:mtao/quiver.git subprojects/quiver  # required for wrap-redirect
meson setup build-debug --buildtype=debug -Dlua=true
meson compile -C build-debug
meson test -C build-debug -v

Future Work

  • PLY mesh loading via quiver I/O (currently emits placeholder sphere)
  • Matrix transform support in ART's parse_transform() (preserved in Lua output)
  • Material / light / texture support

mtao added 5 commits March 29, 2026 14:15
Add a Lua-based scene description system using sol2 bindings. Scene
scripts return declarative tables that C++ parses into the existing
scene graph, combining programmability (loops, functions, require())
with clean declarative syntax.

New components:
- Lua bindings for all geometry types, scene nodes, camera, image,
  and transforms (src/lua/bind_*.cpp)
- Scene loader that parses Lua table DSL into SceneDescription
  (src/lua/scene_loader.cpp)
- art-lua CLI runner with --output/--width/--height/--accel options
- 4 example scenes (sphere, transforms, cornell box, mesh demo)
- 13 test cases covering table parsing, transform composition,
  geometry construction, error handling, and end-to-end rendering

Build system:
- New 'lua' meson option (default false)
- sol2 v3.5.0 wrap file (pulls lua internally)
- lua.wrap redirect for quiver subproject compatibility
- Conditional compilation: lua bindings only built when -Dlua=true
Serialize SceneDescription back to Lua table DSL strings that can be
re-loaded by load_scene_from_string(), enabling introspection and
round-trip scene description.

- Add scene_serializer.hpp/cpp with serialize_scene() function
- Geometry dispatch via dynamic_cast (Sphere, Box, Plane, Disk,
  Cylinder, Triangle, MeshGeometry)
- Transform serialization via TRS decomposition (identity omitted)
- Camera serialization by decomposing inverse isometry
- Add Triangle accessors (vertices, normals, uvs) for serialization
- 11 new serializer round-trip test cases (90 total assertions)
Add three standalone Lua modules under tools/:
- pbrt_to_lua.lua: PBRT v3/v4 parser that converts scene files to ART's
  Lua table DSL. Handles LookAt, Camera, Film, Shape (sphere, trianglemesh,
  disk, cylinder, plymesh, bilinearmesh, loopsubdiv, curve, cone, paraboloid,
  hyperboloid), Transform/ConcatTransform, ObjectBegin/End, Include/Import.
  Unsupported directives (Material, Light, Texture, etc.) are consumed
  gracefully and emitted as TODO comments.
- lua_to_pbrt.lua: reverse converter from ART Lua scene tables to PBRT v3
  format, supporting sphere, disk, cylinder, box (tessellated), plane,
  triangle, mesh, and group node types.
- validate_roundtrip.lua: batch validator that tests PBRT->Lua conversion
  (and optionally Lua->PBRT->Lua round-trip) across scene file directories.
  Supports --max-size, --roundtrip, --verbose, --stop-on-error flags.

All three are require()-able modules with CLI entry points guarded by
arg[0] pattern matching. Meson integration via 'tools' build option
(default: true) installs scripts to datadir/art/tools.

Validated against 60+ PBRT v3/v4 scene files with zero failures.
Large scenes (landscape, sanmiguel) with millions of curve/mesh directives
parse correctly but are slow in pure Lua.
Add --pbrt=<path> option that runs 'pbrt --format' on the generated PBRT
output to verify it parses correctly with the actual pbrt-v4 binary.
This validates the full PBRT -> Lua -> PBRT -> pbrt pipeline.

Tested with 45+ scenes across v3 (figures, simple, white-room) and
v4 (kroken) directories: all pass pbrt --format verification.
- Add Parser:warn() method with dedup (same warning printed at most 3 times,
  then suppressed with count summary at end of parse)
- Support gzipped Include files (.pbrt.gz) via gzip -dc decompression
- Skip very large compressed includes (>10MB) to avoid OOM on hair/fur scenes
- Add MAX_PBRT_VALIDATE_SIZE (50MB) to skip pbrt --format on huge outputs
- Decode signal-based exit codes (SIGSEGV etc.) in pbrt validation
- Track and report skipped pbrt verifications in summary

Validation results: 386/386 files pass Lua validation, 370/370 pass
pbrt --format verification (16 skipped due to large curve placeholder output).
Zero failures across entire PBRT v3+v4 test corpus.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant