Skip to content
mikera edited this page Dec 13, 2012 · 13 revisions

Welcome to the enlight wiki!

Scene Description Language Ideas

Rough objectives:

  • Allow an intuitive, declarative definition of a 3D scene
  • Allow parts of the scene to be generated programatically (e.g. randomly duplicating objects!)
  • Allow substitution, i.e. object can be let-bound and re-used
  • Allow mathematical functions and textures to be expressed (probably using clisk - https://github.com/mikera/clisk)
  • Enable the scene to be compiled down to an optimised scene graph for rendering
  • Be reasonably concise as a DSL

Maps or vectors?

Something nice and intuitive about maps: {:camera {:position [10 10 0]}}

But probably makes more sense to allow sequential transformations via vectors:

[:union 
 [:box  ....]
 [:sphere :radius 10 :translate [10 10 -10]]
 :scale 20       ;; scale applies to entire union so far
 :texture [ ....] ;; texture everything in union
]

Modifiers / defaults

Should we also allow primitives / modifiers with no arguments?

[:union 
 [:sphere :translate [5 5]]  ;; sphere with args
 :sphere    ;; no-arg sphere, use all defaults
]

Seems like a good idea, makes DSL more expressive. But could there be problems with ambiguity?

How should we express functions?

  • can probably embed clisk functions - this gets us function compilation for free

  • would be nice to give friendly operators (*, + etc. for vectors and scalars)

  • need a small library of standard functions, can probably leverage clisk

  • maybe need a macro e.g.

    (function (+ x [1 0 1]))

Performance considerations

  • Need to avoid any memory allocations / expensive lookups in inner tracing loop
  • Should support structural sharing, e.g. many translated instances of same object
  • Maybe we can dispose of temporary structures once compiled -> memory win?

Primitive description

Initial idea to put primitive keyword before vector of arguments (POVRay style)

:sphere [:radius 10 :translate [5 5 5]]
:box [ [0 0 0] [1 1 1] ]

Problem: not easy to substitute if primitives expressed as two forms!

So maybe this should be:

[:box [0 0 0] [1 1 1]]

This also allows primitives to be generated by functions:

(build-special-box :foo :bar :baz)

Transformations

Can we have a general language for transformations?

[:box]
[:box [:translate [1 1 1]]]  ;; simple translation
[:box [:rotate :angle 120 :axis [0 1 0]]]  ;; axis/angle rotation
[:box [:rotate [1 2 3]])]]  ;; direction / magnitude rotation? degrees?
[:box [:scale 2]]  ;; scaling by scalar
[:box [:scale [1 2 3]]]  ;; stretch/scaling by vector

Are transformations OK to flatten outside vectors, i.e. take implicit args?

    [:box [:translate [1 1 1]]]
 => [:box :translate [1 1 1]]

Compilation mappings

A single keyword should compile to its default object

:sphere -> Sphere

A vector should be compiled based on its first keyword

[:sphere] -> Sphere

Once first keyword is compiled following keywords act as sequential transformations?

[:sphere :translate [1 1 1]] -> Translated(Sphere)