Search code examples
openglcameralockingquaternionsglm-math

how do you prevent gimbal lock using glm quat


I am trying to implement an opengl camera that rotates the position of the camera around a specified world coordinate. I am trying to do this using glm math library; my code is as follows

void Camera::dolly(double angle_x, double angle_y, const double& loc_x, const double& loc_y, const double& loc_z, const double& dt) {

  glm::vec3 target = glm::vec3(loc_x,loc_y,loc_z);

  glm::quat Q;glm::vec3 axis0(0.0f,1.0f,0.0f);
  glm::quat R;glm::vec3 axis1(1.0f,0.0f,0.0f);

  position = position - target;

  //glm::normalize(axis0);
  glm::normalize(axis1);

  Q = glm::gtx::quaternion::angleAxis( float(angle_x ), axis0 );;
  R = glm::gtx::quaternion::angleAxis( float(andl_y ), axis1 );;

  glm::quat final =  R*Q;

  position =  final * position;

  position = position + target;
  cout << "\tPosition: " << position.x << " " << position.y << " " << position.z <<endl;
}

When I test the code, rotation using quat Q works fine, but quat R causes "choppy" rotation. What am I doing wrong?


Solution

  • note: copied from my answer here.

    All you have done is effectively implement Euler angles with quaternions. That's not helping.

    The problem with Euler angles is that, when you compute the matrices, each angle is relative to the rotation of the matrix that came before it. What you want is to take an object's current orientation, and apply a rotation along some axis, producing a new orientation.

    You can't do that with Euler angles. You can with matrices, and you can with quaternions (as they're just the rotation part of a matrix). But you can't do it by pretending they are Euler angles.

    This is done by not storing angles at all. Instead, you just have a quaternion which represents the current orientation of the object. When you decide to apply a rotation to it (of some angle by some axis), you construct a quaternion that represents that rotation by an angle around that axis. Then you right-multiply that quaternion with the current orientation quaternion, producing a new current orientation.

    When you render the object, you use the current orientation as... the orientation.