# Get enemy/chaser object to face player object - OpenGL

My chaser object will not face the player object. It simply keeps spinning around and won't face the player.

void chaser::Move() {
vec3 plannedFacingDirection = normalize(p->GetPosition() - GetPosition());

vec3 currentFacingDirection = normalize(vec3(0.0f, 0.0f, -1.0f)); //yes i know it's already normalized

vec3 axisOfRotation = normalize(cross(currentFacingDirection, plannedFacingDirection));

float dotProductOfVectors = dot(currentFacingDirection, plannedFacingDirection);

clamp(dotProductOfVectors, -1.0f, 1.0f);

float angle = acos(dotProductOfVectors);
if (plannedFacingDirection != currentFacingDirection) {
if (dotProductOfVectors != -1.0f && dotProductOfVectors != 1.0f) {
transform = rotate(transform, angle, axisOfRotation);
}
}

transform = translate(transform, normalize(currentFacingDirection) * speed);
}


Move() is called in the render() function. pis the player object. transformis a mat4 object. I will be eyeing this question like a hawk. It's really bugging me that I can't figure this out. Please comment with any questions of your own and I will answer them ASAP.

• You don't compute the sign of the angle: you always rotate counter clockwise, never clockwise. acos() returns a value 0 .. π – Bram Dec 6 '17 at 20:33
• Sometimes adding an animated gif helps illustrate the issue at hand. – Alexandre Vaillancourt Dec 7 '17 at 1:47
• I managed to fix this by setting a new variable, originalTransform, where the chaser is spawned, and setting the current transform to be equal to rotate(originalTransform, angle, axisOfRotation) and then applying the translation- which is why I didn't get back until now! The result was satisfactory for what I needed, as the chasers orientation didn't really matter, as long as it moved and faced toward the player. – DCON Dec 8 '17 at 3:40

To face a certain direction, I find that a much better approach is to built a new matrix, instead of transforming an old one with a rotation.

Let's say you want the chaser X axis to point at the target, and world Z is up:

vec3 x = ( tgt - chaserpos );
x.normalize();
// y is z cross x.
vec3 y = vec3(0,0,1).crossProd( x );
y.normalize();
// z is x cross y.
z = x.crossProd( y );

mat44 chasermat;
chasermat.setRow( 0, x );
chasermat.setRow( 1, y );
chasermat.setRow( 2, z );
chasermat.setRow( 3, chaserpos );


This code creates three axes that are perpendicular to each other. The x points to the target, the y points to the left, the z points up.

The resulting matrix will have pan, tilt, but no roll (horizon stays horizontal.)

NOTE: This code does not work if the chaser needs to look perfectly straight up or perfectly straight down.

NOTE: Your matrix library may have a LookAt() function that does just this. But described here is how to do this manually. After the LookAt() don't forget to set the translation.

PS: Your original code does not work because you determine an angle, but not the sign of the angle: do you need to turn clock wise or counter clockwise?