Page 1 of 1

Rotating entity to face another entity

Posted: Wed Nov 30, 2011 10:24 pm
by al9191
I have dynamic entities that are modelled in the physics space as ConvexHulls.

I want one of the entities to rotate and face towards the other entity. I am however struggling to work out the angle it needs to turn and actually apply this rotation to the entity.

I can apply rotations by applying angular velocities to the entity. I can:

1) Find position of the entity it needs to face
2) Calculate vector between the entity and the entity it needs to face
3) Has orientation of the entity

I now need to rotate the entity from it's current orientation to face in the direction of the vector between the two entities.
I am really struggling to work out this angle that it needs to turn and actually getting it to rotate that exact angle to face the other entity.

Re: Rotating entity to face another entity

Posted: Wed Nov 30, 2011 10:46 pm
by Norbo
The first question would be, what direction is the entity's 'face' in local space? In other words, which direction on the entity will end up pointing at the other object?

Once you choose that direction, you can compute the rotation needed to make the entity face the object. So, if you choose the local forward direction as the face, then you could use the Toolbox.GetQuaternionBetweenNormalizedVectors method with parameters of entity.OrientationMatrix.Forward and the offset to the target location, normalized.

If you want to maintain an up vector, then you could do something like the Matrix.CreateLookAt helper method.

To reach the new orientation, you could use the EntityRotator or do what it does internally. It has a static helper method to compute the angular velocity needed to get from one orientation to another in a given time frame if you wanted to go that route.

Re: Rotating entity to face another entity

Posted: Wed Nov 30, 2011 11:29 pm
by al9191
Ok thanks very much.

How would you go about using an EntityRotator to rotate the entity?

Re: Rotating entity to face another entity

Posted: Wed Nov 30, 2011 11:37 pm
by Norbo
You can construct an EntityRotator with an entity. Then, every frame, set the EntityRotator's TargetOrientation state to the current goal. For dynamic entities, this uses a single entity angular motor. If the motion seems too fast or rigid, you can soften the motor in its settings (reduce and fiddle with entityRotator.AngularMotor.Settings.Servo.SpringSettings.Damping and Stiffness).

As long as the entity rotator is active and in the space, it will control the entity's rotation.

If the type of preferred control is different, let me know what it is and I'll see if another option fits more closely.

Re: Rotating entity to face another entity

Posted: Thu Dec 01, 2011 1:58 am
by al9191
*EDIT* Posted by mistake. Read next post.

Re: Rotating entity to face another entity

Posted: Thu Dec 01, 2011 2:02 am
by al9191
I just can't get the entity to rotate towards the other correctly.

Code: Select all

Vector3 currentDirection = Body.OrientationMatrix.Forward;
Vector3 currentPosition   = Body.Position;
Vector3 positionToFace = OtherEntity.Body.Position;
Vector3 difference = Vector3.Normalize(positionToFace - currentPositon);
Quaternion rot;
Toolbox.GetQuaternionBetweenNormalizedVectors(ref currentDirection, ref difference, out rot);
mover.TargetOrientation = rot;
Also, mover is a global in the Game class so is exists always (for testing atm to get it working.)

Code: Select all

EntityRotator mover = new EntityRotator(Entity.Body); //Entity is the entity mentioned above
space.Add(mover);
However, the entity barely rotates at all when it's target moves around it. It certainly doesn't rotate to face it.

Re: Rotating entity to face another entity

Posted: Thu Dec 01, 2011 2:14 am
by Norbo
The target orientation must be the actual orientation, not the rotation needed to reach that orientation. So instead of using mover.TargetOrientation = rot, use mover.TargetOrientation = Quaternion.Concatenate(currentOrientation, rot);

Re: Rotating entity to face another entity

Posted: Thu Dec 01, 2011 9:49 am
by al9191
Excellent thanks very much. That nearly works.
However, when the entity turns around it seems to sink into the floor slightly / tilts down slightly. My entities all move around on flat surface so can only rotate around y axis. What may be the reason for this?

(I was thinking that it might be tilting down slightly when it faces the other entity if the other entity is close.) Therefore, I was wondering if there was a way to make the Quaternion only rotate around y axis or something along those lines?

Although that may not be the problem. It seems to tip onto its side or sink into the floor. But then the model still rotates around to face the other entity.


*EDIT* I managed to get it to stop doing it. Just set the X and Z variables of the Quaternion to 0.

Re: Rotating entity to face another entity

Posted: Thu Dec 01, 2011 10:07 pm
by Norbo
A slightly more intuitive way to think about it is to ensure that the rotation between the two vectors only needs to go around the Y axis. This means projecting both directions onto the horizontal plane before creating the rotation. Presumably, the entity's forward vector is already aligned with the horizontal plane, but the target offset needs to be projected. Since it's the world horizontal, all you need to do is set the direction's Y component to 0 and normalize.