This page details how nodes are placed in the world coordinate system.
Overview
Nodes with attribute type Spatial can be positioned in the world coordinate system. By default, the spatial properties position, rotation, and scale are used:
If the Node has any parent objects, the world matrix of it is updated by (Default)Spatial::updateWorld(). If a Node does not have a parent, the world matrix will simply be its model matrix. If it does have a parent, the world matrix will be the model matrix, multiplied with the parent's world matrix, such that hierarchical transforms become possible.
Update cycle
An important aspect to know about model and world matrices is the update cycle. Updates to the world and model matrix are handled asynchronously by scenery. This means any changes e.g. to the position, rotation, and scale properties will not be reflected immediately in the model and world matrix. Both matrices are updated in the background by scenery such that they are available to the renderer with the next frame rendered after the change of properties occurred:
v.spatial().scale =Vector3f(3.0f, 10.0f, 1.0f)System.out.println("v.model: "+ v.spatial().model)// Output (Matrix is not immediately updated and is still unity):// 1.000E+0 0.000E+0 0.000E+0 0.000E+0// 0.000E+0 1.000E+0 0.000E+0 0.000E+0// 0.000E+0 0.000E+0 1.000E+0 0.000E+0// 0.000E+0 0.000E+0 0.000E+0 1.000E+0
Any manual changes to the world and model matrix will be overwritten by composeModel().
Again, do not rely on the model and world matrices to be up-to-date after changing transform properties.
Overriding default matrix composition behaviour
As stated above, scenery by default takes the position, rotation, and scale properties into account when constructing a Node's model matrix. These properties were chosen as they are the most common ones used. However, you might feel the need to introduce additional transforms into the world matrix, such as skew. This is possible in two ways:
Setting wantsComposeModel = false: This will cause scenery to not run the composeModel() routine, but it will use whatever matrix you have provided as the Node's model matrix property. The world matrix will still be the parent's world matrix times your custom model matrix.
Overriding composeModel(): This is possible when introducing a new Attribute type, and will integrate your custom composeModel() routine within scenery's default update cycle.
Manually updating the model and world matrices
As said, the model and world matrices are only updated before the next frame is rendered. This behaviour can be overridden as well, but is discouraged, as it goes outside of scenery's expected update cycle (inconsistencies should not be expected though, as the updateWorld() method is only called as @Synchronized method). Only use if strictly necessary, or for debug purposes.
The above example then changes to:
Which is what would be expected if updates to the matrices happed immediately.