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\$