I am trying to use an onDragEndObserbvale on pointer drag behavior to execute code after the mesh was moved. I have found that this event fires as soon as the pointer up occurs on an attached mesh, whether the mesh was moved or not. I only want to execute code if the mesh actually moved. There is an internal property on PointerDragBehavior _dragDelta, but I can’t find any public way on the event or behavior to know if the mesh moved. I could listen for onWorldMatrixUpdate and only execute my code on drag end if the world matrix changed, but is there an easier way to detect a mesh was moved as part of a drag behavior?
There is an easier way; event that is sent for observable contains the delta. Just accumulate its value and when drag ends, the length of the delta vector will tell you the distance moved.
It seems that way of accumulating the delta only works reliably if dragDeltaRatio is set to 1 thou. Otherwise after abruptly releasing a quick drag the accumulated delta can be substantially larger than the actual change in the mesh’s position (since releaseDrag() sets _moving to false, which causes _beforeRenderObserver to not animate the mesh’s position any farther, even thou it may not have reached the target position yet).
If you instead copy the mesh’s position on drag start and then subtract that position from the mesh’s position on drag end, that should reliably calculate the total distance moved in any case since the position won’t be animated any farther after the drag ends…
Here’s a little adaption of the above PG to show the difference between the two methods. For example, the accumulated delta is off by about 2.5 when testing fast drags on my MacBook. (Also you can set a timeout to verify that the animation stops after the drag ends without realizing the full delta).
Yes, you are right. Small errors accumulate each frame and after a few seconds of dragging, the total error might be noticeable.
Computing delta position of mesh looks like a great idea.