(2017-01-30, 0:07)Santeri Piippo Wrote: Alright so I've recently taken back to work on LDForge so that we can finally have something better than MLCad and text editors to make bricks with.
And by doing so I'm back to the ages old problem of breaking the gimbal lock. I've surfed around the web for years now looking for the solution and it generally is to use quaternions instead of euler angles. But I absolutely cannot wrap my head around: how exactly does 2D screen turning translate into a 4D quaternion?
I've been bashing my head against a wall regarding this for so long that I'm not even sure at this point that quaternions are the way to go. Maybe I'm supposed to use a rotation matrix instead? Or multiple quaternions? Or a mix of both? How am I supposed to model the camera?
LDView uses quaternions for its camera, but not for model rotation. Model rotation is performed via a separate rotation matrix. In Lat/Long mode, LDView has gimbal lock, and this is expected. When Lat/Long mode is disabled, it doesn't have gimbal lock. All I do there is determine how fast the mouse is moving in both X and Y (scaled), and then apply rotations based on that and how long a frame takes to draw. I actually use GL to do the rotation, but that could easily be done other ways also. Here is the pertinent code:
Code:
glPushMatrix();
glLoadIdentity();
glRotatef(rotationSpeed, xRotate, yRotate, zRotate);
glMultMatrixf(rotationMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX, rotationMatrix);
glPopMatrix();
glMultMatrixf(rotationMatrix);
The above code simply updates my rotationMatrix variable based on the current rotation settings, then applies that matrix to the GL transform prior to drawing the model. Note that zRotate in LDView is done via two keys on the keyboard, not the mouse. It effectively spins the camera around its own axis (although not really, since as I said, what I'm really doing is applying a transform to the model before I draw it.
To be honest, the way LDView does things could likely lead to problems in an editor, so I'm not really sure it's appropriate there. But I suspect that with a little work, the calculations I use above to figure out the model's rotation could be reverse applied to the camera, and end up with the same end result, but with known camera position. (The zRotate would obviously be trivial from the camera's perspective.)