So after a lot of researching about quaternions I almost got the quaternion camera working. Almost, cause it rotates in a proper way only in a vertical axis. Other rotations stretches and deforms the view (like on a picture below).
- Wobbling horizontal moves makes only Z axis stretched
I don't like to post topics like "Please, debug my brain", but I'm in a dead end right now, and I don't know how to fix it.
My implementation looks like this:
- I Convert an axis-angle rotation to a quaternion and normalize it.
- Then multiply it with a camera identity quaternion.
- And then multiply a position of a camera (which is a 4x4 model-view matrix) by a product of above multiplication converted to matrix.
My free quaternion camera class looks like this (for now):
function QuaternionCamera() {
// Fake 4x4 Matrix
this.position = new Matrix4x3();
this.rotation = new Quaternion();
}
QuaternionCamera.prototype = {
verticalRotation: function(angle) {
this.rotation.multiply(new Quaternion().axisToQuaternion(angle, 0, 1, 0));
this.position.multiply(this.rotation.quaternionToMatrix());
this.rotation.makeIdentity();
},
horizontalRotation: function(angle) {
this.rotation.multiply(new Quaternion().axisToQuaternion(angle, 1, 0, 0));
this.position.multiply(this.rotation.quaternionToMatrix());
this.rotation.makeIdentity();
}
};
And on mouse movement, it runs this:
camera.verticalRotation(degToRad(deltaX / 6));
camera.horizontalRotation(degToRad(deltaY / 6));
I believe that this is a proper way to do it, so I'll just dump my math library, maybe you could find a typo in there (cause I have checked it a hunderd of times and found nothing): http://pastebin.com/0zYLaR1V
PS How to get rid off an additional little roll when rotating camera around, so it will move in a game fashion way?
PS2 And where did the imaginery numbers gone when implementing quaternion math to programming language?? ^^ This is a true mystery for me.
rotateCamera: function(angleX, angleY) { var quatX = new Quaternion(); var quatY = new Quaternion(); quatX = (new Quaternion().axisToQuaternion(angleY, 1, 0, 0)); quatY = (new Quaternion().axisToQuaternion(angleX, 0, 1, 0)); this.rotation.multiply(quatX.multiply(quatY)); this.position.multiply(this.rotation.quaternionToMatrix()); this.rotation.makeIdentity(); },
\$\endgroup\$