3
\$\begingroup\$

Variants of this question might have been asked on this site, but none of the answers I found worked in my case.

I am trying to make a Camera look at a point. The camera has a world transformation matrix, which is used to calculate the front vector, the eye position when making the view matrix finally. My camera is treated like any other object in the scene and thus has a world transform. I want to be able to modify this world transform, and that should automatically affect the camera.I want to actually modify the world transform of this camera so that it will "LookAt" a point.

For this, I modify the Rotation term of the world transform (R in T * S * R) like this:

WorldTransform::SetLookAt( float x, float y, float z ) {

    vec3 lookPoint = vec3 ( x, y, z );

    vec3 lookDir = normalize( lookPoint - m_position  );

    float lookLengthOnXZ = sqrtf( lookDir.z*lookDir.z + lookDir.x*lookDir.x );
    m_rotationX = degrees(atan2f( lookDir.y, lookLengthOnXZ ));
    m_rotationY = degrees(atan2f( lookDir.x, lookDir.z ));

    RotateAbs( m_rotationX, m_rotationY, m_rotationZ );

    UpdateMatLocal( );
}

Basically, I already have a function that can set the rotation (RotateAbs()), so I calculate the pitch, yaw and roll angles and pass them to there.

While calculating the view matrix, I just do:

void Camera::Update( ) {
    if (m_pTransform.m_pointer == nullptr) return;

    vec3& position = m_pTransform->GetPosition( );
    m_look         = m_pTransform->GetForward( );
    m_lookAt       = position + m_look;

    //Calculate the new matrix
    m_view = glm::lookAt( position, m_lookAt, glm::vec3( 0.0f, 1.f, 0.0f ));


}

This sort of works, the camera starts deviating from where it should be looking at after a while. What am I doing wrong?

\$\endgroup\$
0
\$\begingroup\$

Found what was wrong. The overall system works perfectly, its just that

  • The m_rotationX angle was being calculated incorrectly. instead of

    m_rotationX = degrees(atan2f( lookDir.y, lookLengthOnXZ ));

    it should have been

    m_rotationX = -degrees(atan2f( lookDir.y, lookLengthOnXZ )); //(missed the minus sign.)

and

  • The order in which the rotations should be applied must be Rz * Ry * Rx, where Rx is the Rotation matrix along x-axis, and so on. I was doing it the other way round. Remember, matrix multiplication is not commutative...

Hope that helps somebody out there like me.

\$\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.