Hi, I am not sure this if this is a bug or a feature…
I am tracking 3D movements of sphere meshes by projecting them down onto a “ground plane” where correspondingly colored tubes move in the ground plane tracking the Y component of the sphere meshes.
Kind of a “drop vertical shadow onto the ground” for each sphere except that the ‘shadow’ is a colored rod that ‘rolls’ back and forth ( in the Y direction only ) dependent on where the parent sphere is positioned above.
I registered a routine as callback on each sphere mesh which simply calls
sphere.registerBeforeRender(function(mesh){
var absPos = mesh.getAbsolutePosition();
mesh.metadata.spotLine.translate( newBABYLON.Vector3(0, absPos.y, -100), 1 );
}
The metadata field is used to link the sphere with its colored rod or ‘spotLine’, I am not using the usual parent-child relationship because I want the rod to only respond to changes in the Y direction.
This was working great and as expected until I noticed that if I zoomed in so that a sphere was not visible then the corresponding colored rod was not updating position anymore.
“Duhhhhh” - my callback was triggered by a Render event so of course Babylon is well written and does not waste time rendering things that will not be seen anyway - my callback stops being called as soon as a sphere moves out of view.
Ok so thenI then changed the event type to ‘registerAfterWorldMatrixUpdate’ - so that my code would be called whenever the sphere mesh was moved.
Then I had a problem, infinite recursion because my callback function uses var absPos = mesh.getAbsolutePosition();
At first glance ‘getAbsolutePosition()’ would appear to be a “read only” operation but I guess if concurrent code is a factor then it might be necessary to somehow ‘lock’ the mesh, apply any pending transformations - then read the result and ‘unlock’ the mesh in which case ‘getAbsolutePosition()’ might be considered more of a ‘read and write’ operation.
==============================
Traceback
My routine is called ‘addSpot’ - I would add that this “infinite” recursion is actually happening at the stage when I first create the sphere with my routine addSpot() and then attempt to register my callback function with “registerAfterWorldMatrixUpdate”.
10:54:15.270 too much recursion babylon.js:16:1
_update http://localhost/Babylon.js-master/dist/babylon.js:16
update http://localhost/Babylon.js-master/dist/babylon.js:16
_updateBoundingInfo http://localhost/Babylon.js-master/dist/babylon.js:16
_afterComputeWorldMatrix http://localhost/Babylon.js-master/dist/babylon.js:16
computeWorldMatrix http://localhost/Babylon.js-master/dist/babylon.js:16
getAbsolutePosition http://localhost/Babylon.js-master/dist/babylon.js:16
addSpot http://localhost/Babylon.js-master/sandbox/skeletonBone1.12.js:281
notifyObservers http://localhost/Babylon.js-master/dist/babylon.js:16
computeWorldMatrix http://localhost/Babylon.js-master/dist/babylon.js:16
getAbsolutePosition http://localhost/Babylon.js-master/dist/babylon.js:16
addSpot http://localhost/Babylon.js-master/sandbox/skeletonBone1.12.js:281
notifyObservers http://localhost/Babylon.js-master/dist/babylon.js:16
computeWorldMatrix http://localhost/Babylon.js-master/dist/babylon.js:16
getAbsolutePosition http://localhost/Babylon.js-master/dist/babylon.js:16
addSpot http://localhost/Babylon.js-master/sandbox/skeletonBone1.12.js:281
notifyObservers http://localhost/Babylon.js-master/dist/babylon.js:16
computeWorldMatrix http://localhost/Babylon.js-master/dist/babylon.js:16
getAbsolutePosition http://localhost/Babylon.js-master/dist/babylon.js:16
addSpot http://localhost/Babylon.js-master/sandbox/skeletonBone1.12.js:281
I am having a little difficultly expressing the question behind all of this but I will have a go…
I guess it boils down to asking something about the nature of concurrent operations, it is possible for getAbsolutePosition to trigger meaningful (by meaningful I mean real positional change has been written) to the matrix for the mesh in question in the sense that the mesh has been transformed during the call - OR - is the mesh position unchanging for the duration of the getAbsolutePosition call and hence it is not strictly necessary for BabylonJS to issue an event that will fire up registerAfterWorldMatrixUpdate and so lead to infinite recursion?