I have tried desperately to reproduce the exact series of events that lead to this outside our application, but I have been unable to. However, i can tell you what is happening from a code standpoint.
We are using a number of meshes with PointerDragBehaviors on them. If both meshes are at the same location, the following occurs.
- a PointerInfo gets generated
- This calls .pickInfo, and since there is no _pickInfo yet, that calls _generatePickInfo
- this line gets called: this._pickInfo = this._inputManager._pickMove(this.event);
- The pickMove callback ends up triggering more behaviors which ends up calling .pickInfo AGAIN
- Since we’re still in the callstack of this._inputManager._pickMove(this.event), this._pickInfo has not been assigned yet, so it drops into _generatePickInfo AGAIN (effectively recursion)
- This completes… which then sets _inputManager to null.
- The recursion is done, and so the first call of this._inputManager._pickMove completes and assigns to this._pickInfo.
- It then attempts to call this._inputManager._setRayOnPointerInfo(this._pickInfo, this.event);… but inputManager has been set to null and everything breaks.
We have tried and tried to figure out how we are causing this “double calling” of .pickInfo, and it only seems to happen when two items are directly on top of each other.
- Does anyone have any tips on how to find the culprit based on your knowledge of how babylonjs creates these PointerInfo and drag behaviors?
- We patched locally by doing the following, is that a viable solution for us to put into babylonjs to safeguard against these situations?:
_generatePickInfo() {
if (this._inputManager) {
this._pickInfo = this._inputManager._pickMove(this.event);
if(!this._inputManager) {
return;
}
this._inputManager._setRayOnPointerInfo(this._pickInfo, this.event);
this._inputManager = null;
}
}
Stack trace below
pointerEvents.js:124
Uncaught TypeError: Cannot read properties of null (reading '_setRayOnPointerInfo')
at PointerInfo._generatePickInfo (pointerEvents.js:124:32)
at get meshUnderPointer (scene.inputManager.js:107:35)
at get meshUnderPointer (scene.js:1495:35)
at ActionEvent.CreateNew (actionEvent.js:47:78)
at InputManager._processPointerUp (scene.inputManager.js:393:114)
at eval (scene.inputManager.js:805:22)
at InputManager._initClickEvent (scene.inputManager.js:537:29)
at InputManager._onPointerUp (scene.inputManager.js:743:18)
at Observer.eval [as callback] (scene.inputManager.js:861:34)
at Observable.notifyObservers (observable.js:294:49)