Hello all!
I am working on implementing a custom, performance-critical setParent framework layer inside the minimalist @babylonjs/lite ecosystem.
The core objective is allowing both standard primitive meshes and custom text geometry paragraphs to seamlessly inherit transformations from parent nodes (like a tracking mesh or an animated background panel) while allowing them to animate and rotate cleanly around their own custom local pivot centers
I have created two distinct implementation approaches and ran into a few interesting spatial mathematical anomalies that I need help resolving.
Approach A: Custom Row/Column Transposed setParent (v0.0.6b Beta)
-
Playground Sandbox Live: Babylon Lite Playground
-
Behavior Profile: This implementation transforms standard primitives (e.g., matching a box child to a sphere parent) exactly as designed!
-
The Issue: The calculations break down when passing a custom pivot offset (centerXOffset / centerYOffset) for left-aligned typography blocks.
The text mesh fails to resolve the correct values, causing an orbital spiral rotation anomaly instead of a local central spin.
Mathematical Quirk Discovered: Inside this custom invertParentWorld iteration logic, the matrix layout transposes strangely.
Translation components map directly to indices 3, 7, and 11 instead of the expected column-major terminal indices 12, 13, and 14.
Interestingly, modifying the child’s relative Z-coordinate causes index 15 to dynamically shift (e.g., matching values like -15, -29, -49),
yet standard meshes translate and rotate perfectly here.
Another example of setParent 6b Beta
The exact visible request of what i try to do is in this Playground.
- Playground Sandbox Live: Babylon Lite Playground
Approach B: Built-in mat4 Mathematical Suite (v0.0.7 Beta)
To align cleanly with native framework transformations, I built a secondary iteration path leveraging the built-in mat4Invert and mat4Decompose utilities
-
Playground Sandbox Live: Babylon Lite Playground
-
The Issue: I am unable to make the lifecycle updates bind correctly. Right after the “AFTER Decomposed simulation World” pass executes, the engine logs the decomposed local coordinate translation as _x: -15, yet the actual visible mesh rendering position remains locked directly in the canvas center!
Log Output:
--- DEBUG INITIAL setParent ID: test2 ---
parentMesh id: sphere2_parent position: {"_x":15,"_y":2,"_z":0}
childMesh id: simulation-paragraph position: {"_x":0,"_y":1,"_z":0}
childMesh expected to transform into this position: {"x":0,"y":0,"z":0}
childMesh centerXOffset: 0 centerYOffset: 0
parentWorld [1,0,0,0,0,1,0,0,0,0,1,0,15,2,0,1]
invParentWorldDefault: {"0":1,"1":0,"2":0,"3":0,"4":0,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":0,"12":-15,"13":-2,"14":0,"15":1}
is normal mesh POS: NORMAL X: 0 Y: 0 Z: 0
childWorldPivotMatrix: [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
bakedLocalMatrix?: [1,0,0,0,0,1,0,0,0,0,1,0,-15,-2,0,1]
Decomposed TRS: {"translation":{"x":-15,"y":-2,"z":0},"rotation":{"x":0,"y":0,"z":0,"w":1},"scale":{"x":1,"y":1,"z":1}}
AFTER Decomposed simulation World: [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
simulation possition: {"_x":-15,"_y":-2,"_z":0}
It seems like the mesh’s reactive ObservableVec3 registers receive the values,
but the underlying matrix cache isn’t invalidating or updating correctly after decomposition.
4. Technical Constraints & Framework Visibility Notes
While digging into the architecture to resolve these translation mismatches, I noticed that a significant portion of the core mathematical optimization classes are not currently exposed in the package public exports list.
-
mat4-transform.ts (e.g., transformCoordinatesToRef, transformNormalToRef) are not exposed
github: Babylon-Lite/packages/babylon-lite/src/math/mat4-transform.ts at master · BabylonJS/Babylon-Lite · GitHub -
mat4-multiply-into.ts (mat4MultiplyInto) is completely unexposed:
github: Babylon-Lite/packages/babylon-lite/src/math/mat4-multiply-into.ts at master · BabylonJS/Babylon-Lite · GitHub
Because these high-performance, unrolled, zero-allocation utilities are hidden, writing custom framework matrix workarounds forces code duplication.
What is the recommended approach in Babylon Lite to bake a permanent custom pivot matrix into a child mesh during setParent() initialization without breaking the reactive TRS observables or creating a rendering lag?
Any insights or assistance on these math loops would be highly appreciated!
Thank you!