2
\$\begingroup\$

In a planetary gravity environment objects are represented in the following way:

struct object {
    struct quaternion quat; // quaternion to represent the rotation between the object and the center of the planet
    float dist; // distance from the center of the planet
};

Here are the steps at which I position my player:

// start at center of the planet
applyQuaternion(&object.quat);
glTranslatef(0.0f, object.dist, 0.0f);
drawObject(&object);

Step 1, translate to center of planet: Step 1

Step 2, apply quaternion: Step 2

Step 3, translate outwards by distance value: enter image description here

I am also able to get the current position of the player or enemy by using this code:

struct matrix initialMatrix, resultantMatrix;
glPushMatrix();
getPositionMatrix(&initialMatrix);
applyQuaternion(&player.quat);
glTranslatef32(0, player.dist, 0);
getPositionMatrix(&resultantMatrix);
playerPosition = matrixTranslationToVector(initialMatrix, resultantMatrix);
glPopMatrix();

Given two objects:

struct object player;
struct object enemy;

How can I get the enemy to face in the direction of the player, whilst always standing upright on the planet, using quaternions?

I want the enemy to go from this:

Enemy1

To this:

Enemy2

His feet always on the planet, and head always away from planet.

I'm able to rotate on the axis which doesn't affect the position (from first enemy diagram to second enemy diagram like so):

// Rotate right
Quaternion_multiply(&player.quat, Quaternion_fromAxisAngle(vect(0.0f, 0.0f, 1.0f), degreesToAngle(2)));

// Rotate left
Quaternion_multiply(&player.quat, Quaternion_fromAxisAngle(vect(0.0f, 0.0f, 1.0f), degreesToAngle(-2)));

So I'm unsure as to why I'd need a local orientation in addition to the quaternion I already have.

\$\endgroup\$
  • \$\begingroup\$ You are representing your position as quaternion. How are you representing your local orientation, your player orientation relative to itself ? \$\endgroup\$ – concept3d Oct 30 '14 at 7:46
  • \$\begingroup\$ There is only 1 quaternion, and 1 distance value. The player is rotated by the quaternion so he is perpendicular to the planet (standing upright) and then translated outwards according to his distance from the planet. The quaternion can represent any position on the planet. The player is always facing outwards of the planet. \$\endgroup\$ – Jimmay Oct 30 '14 at 8:01
  • \$\begingroup\$ So if I understand correctly the forward vector (direction player is facing) is pointing outwards (perpendicular) of the planet? \$\endgroup\$ – concept3d Oct 30 '14 at 8:20
  • \$\begingroup\$ the struct object you mentioned only represent position. Do you have local orientation? \$\endgroup\$ – concept3d Oct 30 '14 at 8:22
  • 1
    \$\begingroup\$ Your quaternion in this case is actually position in spherical coordinates. if I understand correctly your player doesn't have a local orientation (you don't track the direction the player is facing). Otherwise your question How can I get the enemy to face in the direction of the player doesn't make much sense. \$\endgroup\$ – concept3d Oct 30 '14 at 8:45
1
\$\begingroup\$

Your task is to find the forward vector (the blue one) that is pointing towards the other player.

This vector can be approximated by finding the tangent at the player position on the shortest arc between the player and the enemy.

The tangent of the arc between the two players can be approximated using an approximated derivative (delta). So should we calculate it?

We use SLERP between P1 and P0 to find P, SLERP naturally maps to an arc, we don't need to explicitly represent an arc.

P is only a very small fraction away from P1.

P = SLERP( P1, P2, 0.001 );

Now we have two quaternions P1 and P in order to find the tangent we need to convert them to 3D vectors, in other words positions.

Once P1 and P are positions. We can now calculate deltaP.

The direction vector is actually the normalized version of deltaP

vec3 deltaP = normalize (Pvec - P1vec);

Now we have a direction vector. We only need to convert it to a rotation matrix/quaternion. In this case you need an extra matrix or quaternion to track the local orientation. You can assume your forward vector is forward=vec(0,0,1), up = vec(0,1,0) and vec(1,0,0) is your right vector.

Converting a direction vector to a quaternion (again you should have a reference) is little bit of work. You can find this function here.

enter image description here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.