How to grab and move entity in "hands"?

I would like to know how to move and orientate one entity when another one moves.

Obviously I know that I can make one entity the child of another so that when the parent moves the child moves in response but how do you do it manually without making it a child.

I started working on the problem like this but I think I am on the wrong track.

When I first grab objects I store an offset which is the difference between the controller and the grabbed object

this.grabbedPosOffset.sub2(this.controller.getPosition(),this.grabbedEntity.getPosition())

and whenever the controller moves I add this offset back in

var pos = this.controller.getPosition().add(this.grabbedPosOffset);
this.grabbedEntity.setPosition(pos.x,pos.y,pos.z);

which seems to work ok for the position but I don’t think is the right way to move it. My gut feeling is that you store the orientation of the controller and the relative position of the grabbed entity. And then when the controller moves you rotate the grabbedEntity around the controller somehow. I am just not sure how to go about it. Can anyone show me and example or give me a steer in the right direction (pun not intended)

Why you simply don’t set position on every update without storing difference?

this.grabbedEntity.setPosition(this.controller.getPosition());

Hi Max,
lol, thats how I am currently doing it but I was hoping for something a little bit better because that snaps the entity to the centre of the controller.

The kind of effect I was going for is that I could pick up and object by it’s edge say and move it around more naturally. That’s why I was calculating the offset value. Hope that makes sense.

I am trying to avoid making it a child of the controller because hopefully in the future I can move it by physics rather than by absolute position making it more natural again.

Sometimes I struggle to understand exactly what you are asking :smiley:

Principle is like this:

  1. Get target position.
  2. Get current position of an object.
  3. If distance is too far of minimum (probably few centimeters).
  4. Then copy current position, subtract target position.
  5. Normalize that vector, and scale to speed of moving * dt.
  6. If vector is longer than distance, then normalize it and scale by distance.
  7. Add current position to that vector.
  8. Set position of grabbed object to that vector.

This will do linear speed grabbing.
Target position shall be probably in front of your camera.
If you want eased “elastic” dragging, then change option 5 to possibly: scale by 0.95. Or play with that number. You need to do that dt dependant as well, to prevent different speeds on different FPS’s.

Hi Max,
Sorry I am not making myself very well understood. The problem is one of both position and orientation.

Imagine that you have a parent model and a child model. The parent is the torch and the child is the flame. Moving the torch should also move the flame so that it stays at the top of the torch and the flame needs to always be in the correct orientation to the torch. Basically I want to do manually what the PlayCanvas engine does automatically when you create a child entity.

If you don’t need elastic move, but immediate.

Then:

  1. Store local rotation and local position somewhere.

// position
2. Get position of target, add local position.
3. Set object to that position.

// rotation
4. get rotation of target, invert it.
5. copy local rotation of object
6. multiply a copy by inverted target rotation.
7. set rotation of an object by that result.

that sound interesting , I will give that a try, thank you. :smile:

It’s still not quite right for some reason but it’s definitely better than what I had originally, thank you.

It certainly helped me to understand how quat maths work and to watch out for functions that modify in place :slight_smile:

One important thing to remember is that Vec’s, Mat’s and Quat’s are mutable - means that they are actual references, not copies. Making copy - is expensive in real-time it pollutes GC. So you want to prepare some Vec’s in advance, and copy values to them - reuse them.

3D Maths experience comes with experimentation. I still get confused sometimes with all those transformations etc, but it gets better when you play and experiment with it.