I’m trying to get an object to rotate so that it is always “looking ahead” as it moves. I’m doing so like this:

``````float Transform[16];

// cross
Transform[0] = 1.0f;
Transform[1] = 0.0f;
Transform[2] = 0.0f;
Transform[3] = 0;

// up
Transform[4] = 0.0f;
Transform[5] = 1.0f;
Transform[6] = 0.0f;
Transform[7] = 0;

// dir
Vector3 dir( m_Position - m_OldPosition );
dir.Normalize();
Transform[8] = dir.x;
Transform[9] = dir.y;
Transform[10] = dir.z;
Transform[11] = 0;

// pos
Transform[12] = m_Position.x;
Transform[13] = m_Position.y;
Transform[14] = m_Position.z;
Transform[15] = 1;

glPushMatrix();
glMultMatrixf( &Transform[0] );

// draw it

glPopMatrix();
``````

It’s working, but it can get distorted, with what looks like the normals getting screwed up.

Any ideas?

Okay, I looked around and came up with another way to do it (see end of post if you’re interested), but I’d still like to know what’s going wrong with this method.

Here’s my working alternative:

``````Vector3 lookahead( 0.0f, 0.0f, 1.0f );
Vector3 dir( pA->m_Position - pA->m_OldPosition );
dir.Normalize();

Vector3 up = lookahead.Cross( dir );
float cosangle = lookahead.Dot( dir );

glTranslatef( pA->m_Position.x, pA->m_Position.y, pA->m_Position.z );
glRotatef( Rad2Deg( acos(cosangle) ), up.x, up.y, up.z );
``````

Your coordinate system in the first case was non-ortho-normal. I.e. the vector dir was not necessarily orthogonal to up and cross.

What you should have done:

``````  Vector p;     // your position
Vector front; // your movement direction
Vector up;    // your world's up vector (0, 1, 0)

// construct ortho-normal coordinate system from movement and world-y
Vector z = normalize(front);
Vector x = normalize(cross(z, up));
Vector y = cross(x, z); // already unit length

// construct transformation matrix from base vectors
float tf[16] = {
x.x, x.y, x.z, 0,
y.x, y.y, y.z, 0,
z.x, z.y, z.z, 0,
p.x, p.y, p.z, 1
};

glMultMatrixf(tf);
``````

EDIT: Keep in mind that “front” must not be collinear (parallel or anti-parallel) to “up”.