Making Draggable Objects without independent children

First I should specify that I am working with a 2D camera and 2D objects, and the entire thing is an Angular Project with one page using three.js. The intended behavior I want is:

  1. Only some objects in the scene are draggable.
  2. Only the parent object is draggable (i.e. if you try to drag a child object or descendants of a draggable object, the draggable object as a whole is the one that moves.
  3. If multiple draggable objects are overlayed and you start dragging somewhere in their intersection, only one of them moves.

Currently, I have two approaches, both of which use DragControls, neither of which accomplishes all 3:

  1. Putting all the objects in the object array of a single DragControl. This accomplishes 1 and 3, but allows you to drag child objects without moving the parent.
  2. Putting each draggable object in its own DragControl and setting transformGroup to true. This accomplishes 1 and 2, but now if I drag at some spot where multiple draggable objects are overlayed, all of them move.

What is the best way to accomplish all 3? Am I missing something?

Maybe it is possible to tickle DragControls (e.g. deactivating, changing target object, rectivating) … but what about making your own dragging? I’m not sure whether this is the best way, but for sure it is the vanilliest one!

Here is a quick-and-dirty demo. The squarish objects are draggable, the circular are not. All of them are groups with subobjects.

https://codepen.io/boytchev/full/eYQxGvr

image

3 Likes

The problem with DragControl is that the raycaster hard-coded recursive to true.

_raycaster.intersectObjects( _objects, true, _intersections );

So any object with children would allow the child to be dragged.

Perhaps a pull request where the constructor takes a fourth, recursive argument that defaults to true for compatibility. Then modify the two places where true is passed to use the variable

constructor( _objects, _camera, _domElement, recursive = true ) {
...
_raycaster.intersectObjects( _objects, recursive, _intersections );

2 Likes

Thank you for the effort that you put into this. I tested a version of this in my project. Unfortunately, I also have to support zooming behavior and window resizing, and I am unable to get it to work with both. I will keep looking for other workarounds in the meantime.

Interesting, I never thought to check the source code. I’ll try to do this. Thanks.

I hope you will find what you need.

Sometimes it will be faster to make something manually, instead of looking for the perfect solution. In the example above, all the items from your initial request are done manually. In a similar way all extra things, like zooming and resizing can also be done manually.

You can also try @anidivr’s suggestion by having own modified copy of the DragControls.js file.

The PR of @ssk4988 has been merged so a new recursive property will be available with r157:

2 Likes

Will this have similar functionality to the recursive property of the intersectsObjects method in TransformControls if so that’d be amazing.

Hi, I have written a library that is useful in these types of cases.

I rewrote @PavelBoytchev’s example using it:

1 Like

This is pretty neat. One small nitpick is that when you hover over the circular objects, the cursor changes to appear like you can click it when it does nothing. I don’t know your library at all so I don’t know if that is a thing your library can turn off and you just decided not to use it. I just wanted to let you know about it since you could go either way in terms of whether the object should appear to be clickable.

Thank you :slight_smile:

Each mesh can have a different cursor.
Indeed it would be better to change the default one when an object is not draggable, I will do that in future versions.

I have modified the example.

PS. I wrote the same example in typescript on stackblitz, more convenient for writing examples with my library.

1 Like

The PR adding the recursive property did not allow me to move groups of objects.

Code pen demonstrating the dragControls.recursive property

This PR 26134 (still pending) did:

Code pen demonstrating the new DragControls.js

The recursive property is not meant to work with groups of objects, just when there is a clear hierarchy of objects with parent-child relationships and the raycasting affects multiple draggable objects. It does not handle this use case and I agree that the new PR is useful (See the more recent comments on that PR). Perhaps the old PR was not completely accurate in its description.