I’ve got a question about quaternions in my WebGL application.
How can I rotate an object only around two axes? For example, how can I exclude/nullify rotation about the Y axis?
The problem is that when I rotate something around X axis, and then around Y axis, it rotates around Z axis slightly as well. I have read whole piles of posts about it (for example) but none of them really helped me. Reversal order of multiplication operations doesn’t work for me. My actual code below:
// Main rotation function:
rotateCamera: function(angleX, angleY) {
if (angleY !== 0) {
this.yawRotation.axisToQuaternion(angleY, this.tempVec.make(1, 0, 0)));
this.rotation.multiply(this.yawRotation);
}
if (angleX !== 0) {
this.pitchRotation.axisToQuaternion(angleX, this.tempVec.make(0, 1, 0)));
this.rotation.multiply(this.pitchRotation);
}
this.rotation.normalize();
MVMatrix.setRotation(this.rotation.quaternionToMatrix());
// Matrix setRotation function:
setRotation: function(m) {
this.element[0] = m.element[0];
(... some code omitted ...)
this.element[10] = m.element[10];
},
And the ought-to-be-working code based on other posts (which is not working):
rotateCamera: function(angleX, angleY) {
if (angleY !== 0) {
this.yawRotation.axisToQuaternion(angleY, this.tempVec.make(1, 0, 0));
}
if (angleX !== 0) {
this.pitchRotation.axisToQuaternion(angleX, this.tempVec.make(0, 1, 0));
}
this.yawRotation.multiply(this.rotation);
this.rotation.copy(this.yawRotation);
this.rotation.multiply(this.pitchRotation);
this.rotation.normalize();
MVMatrix.setRotation(this.rotation.quaternionToMatrix());
},
EDIT: I have added more info about the actual code.
EDIT2: Okeeeey, I almost found a working answer for my problem (adapted it from Rick Hoskinson’s post). My updated code below:
rotateCamera: function(radX, radY) {
// Pitch (vertical rotation)
if (radY !== 0) {
this.pitch += radY;
// Prevent camera from flipping upside-down (constrained by vertical "plane")
this.pitch = Math.clamp(this.pitch, -Math.PI/2, Math.PI/2);
this.rotation.axisToQuaternion(this.yaw, this.tempVec.make(0, 1, 0));
this.rotation.multiply(this.tempQuat.axisToQuaternion(this.pitch, this.tempVec.make(1, 0, 0)));
}
// Yaw (horizontal rotation)
if (radX !== 0) {
this.yaw += radX;
this.rotation.axisToQuaternion(this.yaw, this.tempVec.make(0, 1, 0));
this.rotation.multiply(this.tempQuat.axisToQuaternion(this.pitch, this.tempVec.make(1, 0, 0)));
}
MVMatrix.setRotation(this.rotation.quaternionToMatrix());
}
Camera’s roll has been eliminated using this method, but strange camera motion appears when rotating from one of the sides and then looking below (or I should say trying to look below, cause it curves away from this direction).