Reputation: 9
I'm trying to make a free orbiting camera for a spaceship game. I'm having some trouble with the rotations however. I started by using euler angles, but my implementation kept failing because of gimbal lock, which I want to avoid. I am now trying to use quaternions to solve this problem. I have defined a camera class using this guide https://moddb.fandom.com/wiki/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation.
It seems to work halfway. The author's rotateX() and rotateY() methods for rotating the orientation seems to make sense for an FPS, and for a free cam spaceship, I set both of them to rotate about the spaceship's local x and y axes. The problem is that when I multiply the matrices with these two lines of code
void Camera::rotatex(float xrmod) { Quaternion nrot(Vector3(1.0f, 0.0f, 0.0f), xrmod * PIOVER180); rotation = rotation * nrot; }
void Camera::rotatey(float yrmod) { Quaternion nrot(Vector3(0.0f, 1.0f, 0.0f), yrmod * PIOVER180); rotation = rotation * nrot; }
The quaternions keeps getting flipped/reversed/something IDK. Here's an output for the rotation after applying a rotateX.
rotxr: 0.115017, -0.582758, -0.616199, -0.517168,
rotxr: -0.512880, -0.617420, -0.584486, -0.118837,
rotxr: -0.122204, -0.586019, -0.618506, 0.509016,
rotxr: 0.504829, -0.619667, -0.587657, 0.125778,
rotxr: 0.129351, -0.589305, -0.620836, -0.500551,
If anyone has an idea what's causing this flip that would be great, or if there's a better guide to implement a free moving spaceship cam please link it.
Here's the code for my quaternion multiplication:
Quaternion operator*(const Quaternion& other) {
float x_ = q.x * other.q.w + q.w * other.q.x + q.y * other.q.z - q.z * other.q.y;
float y_ = q.y * other.q.w + q.w * other.q.y + q.z * other.q.x - q.x * other.q.z;
float z_ = q.z * other.q.w + q.w * other.q.z + q.y * other.q.x - q.x * other.q.y;
float w_ = q.w * other.q.w - q.x * other.q.x - q.y * other.q.y - q.z * other.q.z;
return Quaternion(x_, y_, z_, w_);
}
Upvotes: 0
Views: 281
Reputation: 9
Figured out the problem. I was using q = (1, 0, 0, xrmod) for nrot instead of calculating the quaternion using the sin theta/2 and cos theta/2 unit rotation. So nrot was (1, 0, 0, 0.1) when it was supposeod to be (0.0499792, 0, 0, 0.9987503).
Upvotes: 0