How to get mesh in manually PointerDragBehavior.onDragObservable

Hi guys!
I was messing around a bit with BJs Drag and Drop features and found the PointerDragBehavior.
Now I want to implement an own drag-event with custom behaviour.
I don’t want the smothing effect and so the sphere.position in my example will be set like:
sphere.position.x += event.delta.x;

Now I am wondering how to generalize the onDragObservable in such a way, that I can use it like:
attachedMesh.position.x += event.delta.x

The only properties I can access are event.delta, event.dragdistance,…and so on!
Here is a playground example:
https://www.babylonjs-playground.com/#9UFEBE#43

I found also another way in the Babylon.JS How-To section with the following example:
https://playground.babylonjs.com/#279FW9

Is the PointerDragBehavoir more “straightforward” or which way should I choose?

Any advice appreciated!

Hello and welcome to the forum!

I’ve often used the code from the second playground example to pick and drag objects. However, from this point forward, I much prefer your elegant example in the first playground scene. Less code is almost always better… unless there is residual elements which slow down a scene; which is not the case here.:slightly_smiling_face:

Galen

Pinging @trevordev

Hey @wulf11,

Yea, I’d use whatever you feel more natural with, babylon provides a lot of helpers like this but its always a trade off. I typically use a helper like pointerDragBehavior when I’m doing something simple to save time but might switch to implementing it myself if i’m doing something more complicated and want to know exactly what is happening internally.

Thanks for the warm welcome guys!

Ok, I really like the way pointerDragBehavoir works, I got some problems with the Picking solution…
In some cases the camera moves just a bit before it gets detached from the canvas…

@trevordev
May I ask you to provide a public getter for the mesh that fires the event? I took a look into the pointerDragBehavior.ts and would guess that the _attachedNode field is what I am looking for!
Maybe like event.attachedMesh or something like that…

Have to say also that I am a bloody beginner in Javascript (having just a few years C# and WPF background) so I hope that my thoughts make sense :slight_smile:

No worries, I think it makes sense, I can make that property public in my next PR.

As for the camera moving is this just in your code or do you have a repro playground showing this behavior, I don’t see that happening the links you provided so far.

Thank you very much for the commit!

The camera moving issue is in my project code, will try to post a PG if I can replicate it there!

For the attachedNode problem…I feel a bit silly now, because my fallacy was to think that I could handle multiple meshes now with this behavoir…:sweat_smile:You can checkout my PG example here:
https://www.babylonjs-playground.com/#9UFEBE#45

My idea was to define one behavoir, that can be attached to multiple meshes. The mesh that fires the drag event should be referenceable and then moved with my custom positioning …but now the PointerDragBehavoir holds just the mesh which has been attached last. :thinking:

Yea, I believe behaviors can only be attached to one object at a time. I think its recommended to have a behavior per object that needs to be dragged. I find a decent pattern is to wrap all your scene objects in a custom class for your scenario and add optional behaviors or other components to that class to make it easier to keep track of behavior ownership.

1 Like

Thanks for the help so far!
Will try your tips while I am diving deeper into Javascript! This is what I got so far and it works in the moment for me: https://www.babylonjs-playground.com/#9UFEBE#47

Not quite sure which ‘pattern’ I use here :sweat_smile: maybe someone can show me are more straightforward solution, because always interested in best practise stuff :blush:

1 Like

Hello,

I’m certainly no expert at JavaScript or web development in general, but I think I just found another way to create a PointerDragBehavior for each object: deep cloning. For my (personal) project, I’m using cloneDeep from lodash. I create the default PointerDragBehavior as normal:

dragMesh = new BABYLON.PointerDragBehavior({dragPlaneNormal: new BABYLON.Vector3(0,1,0)});

And then I just deep clone it for use with a given mesh:

const dragWizard = _.cloneDeep(dragMesh);

I can set properties on my initial PointerDragBehavior, and they appear in each clone. I’m just using lodash because it’s the first library with deep cloning that I learned about. cloneDeep requires the full build (528 KB), not the core build, so I might look for a lighter cloning library, not that it will be that noticeable in my project.

I’m creating a low-poly virtual tabletop for a pencil, paper and dice game from the late '70s and early '80s that was reprinted last year. There are other tabletops, of course, mostly 2D, but I like the idea of browser 3D that works on a desktop or a mobile device. Naturally, the game master and players will have a variable number and mix of models on the tabletop in each session, so I was looking for an easy way to clone the drag functionality for each loaded asset, especially multiple instances of the same asset.

I’m solving all kinds of problems by using the great Babylon documentation and Googling my way into this forum all the time. Thanks for all the resources!