# Strange quaternion camera streching in WebGL

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:

1. I Convert an axis-angle rotation to a quaternion and normalize it.
2. Then multiply it with a camera identity quaternion.
3. 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));


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.

• If you're applying your rotations strictly sequentially like this, separated by axis, and converting to a matrix every time you need to transform a vector, then I'm not sure that you're gaining anything by using a quaternion representation in the first place. I love quaternions, but for the code you've shown above Euler angles would have the same effect and be easier to read/debug. In fact, Euler angles are often useful for camera movement in games, since they give a clear mapping for axis-selective constraints (John Nesky gave a talk on this at this year's GDC). – DMGregory Apr 2 '14 at 21:33
• @DMGregory By saying "separated by axis" you mean that I have got two functions, one for vertical and one for horizontal rotation? If so, is in this case this function appropiate for quaternions? 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(); }, – Winged Apr 3 '14 at 8:10
• The code above is 'taken' from this post stackoverflow.com/questions/7938373/… and in OP's opinion it should work just fine. And in my case, it still suffers the same problem. And the reason why I want to implement quaternion camera is LERP and SLERP. – Winged Apr 3 '14 at 9:15
• If your quaternion is always normalized and your quaterion to matrix code is correct, than you can not have any stretching or slanting. I would check where your quaternion starts to get unnormalized. – rioki Apr 3 '14 at 9:31

Ahahaha, problem solved, I'm such a math genius ^^: my math library had a typo in function that converts quaternion to a matrix : 1 - 2 * (this.y * this.y - this.z * this.z); - minus times minus makes plus, not minus, as in here: http://www.gameprogrammer.net/delphi3dArchive/quaternions_bestanden/quat1.gif