Third person quaternion camera.

Started by
4 comments, last by Zakwayda 18 years, 6 months ago
I'm currently trying to create a a third person camera that uses quaternions for all of it's rotations. The system I have right now works (or doesn't) by detecting mouse movement in the x and y directions. I then scale the numbers down to reasonable numbers then rotate about the vector (0,1,0)T for the x direction and the vector formed by normalize(View.cross(Up)) for the y direction. Each rotation is done as follows: I form the first quaternion q with q = cos(theta / 2) + sin(theta / 2) * axis. Then the second quaternion p is p = 0 + xi + yj + zk where x = CameraPosition.x - PointCameraIsTrailing.x ... I'm sure you can see what y and z are. I then get result = qinv*p*q (though I believe I could use q*p*qconjugate at less cost, I'll check the math once the labs with maple open later today). Finally I set the camera position equal to result + PointCameraIsTrailing and calculate the view vector as PointCameraIsTrailing - CameraPosition. I then give Position, View, and Up to the lookAt transformation. The problem is that rather then rotating around the object I seem to be rotating in a small circle in front of the object. I should also note that the camera doesn't keep the object in the center of the screen as I would expect. Does anyone see anything wrong with my logic? Thanks in advance for your help.
Advertisement
I tried to sort out your example there, but wasn't clear on exactly what the different variables represent. I will say to make sure the axis for your quaternion is normalized. Given this constraint, you can in fact use conjugate instead of inverse. But, in your example you give two orders for the vector rotation formula, conj(q)*p*q and q*p*conj*(q). The first is only correct if you're using 'reversed' quaternion multiplication. However, I don't think getting that wrong would cause the problems you mention.

Anyway, just some thoughts. Sorry I don't have a better answer for you.
The first order was qinverse*p*q which I'm confident is also a rotation. I am getting the same error with both cases so you were right that it doesn't matter anyhow.

I can imagine how one could get lost in all of those variable names I was throwing out. Perhaps this code will help (not the actual code since I'm writing this at the library, but I'm pretty sure it's what I have at home):
// axis will always be normalizedvoid Camera::RotateCameraAboutAxis(float radians, Vector axis){   float sintheta = sin(radians / 2);   Quaternion p = Quaternion(0, CameraPosition[0] - PointToTrail[0], CameraPosition[1] - PointToTrail[1], CameraPosition[2] - PointToTrail[2]);   Quaternion q = Quaternion(cos(radians / 2), axis.x * sintheta, axis.y * sintheta, axis.z * sintheta);   Quaternion result = Quaternion::multiply(Quaternion::multiply(q, p), Quaternion::conjugate(q));    // I define my quaternions as q = q0 + q1*i + q2*j + q3*k    CameraPosition[0] = result.q1 + PointToTrail[0];    CameraPosition[1] = result.q2 + PointToTrail[1];    CameraPosition[2] = result.q3 + PointToTrail[2];    View[0] = PointToTrail[0] - CameraPosition[0];    View[0] = PointToTrail[1] - CameraPosition[1];    View[0] = PointToTrail[2] - CameraPosition[2];}


(Note to the staff: If you don't already know, plus signs are not showing in the preview window. I assume you have my browser info, but feel free to email me if you don't.)
Ah, I finally got it! (I think.) 'PointToTrail' is the camera's target :)

Given that, at first glance your code looks it should do what you want it to do. (The indices for 'view' are wrong, but I assume they're right in the actual code.) But, you're not showing what axes you're rotating around, or where you're computing the arguments for the 'look at' function. Could the problem be in one of those places?

Also, nobody gets plus signs as far as I know - I know I don't on either my Mac (OSX, Safari) or PC (IE). I suppose we could mention it in the 'suggestions' forum, but I'm guessing no one really wants to be the 'squeaky wheel' :-)
Hrm, I was pretty sure that the error was there. I must have spent a few hours staring at that function. Oh well. Because I prefer to find my own errors I'm going to spend a bit of time checking out the rest of the code to see if I can find the problem somewhere else. I'll come back here if I can't find the problem. Thanks a bunch for your help. Rating++ if I havn't already.

Edit: Looks like I've already rated you as highly as I can. I suppose you'll just have to imagine a higher number there ;).
Well, the error could still be in the code you posted, and I could have just missed it. But it looked right to me. You're taking the difference vector from the target to the camera position, rotating this vector, and then recalculating the camera position from the target and the rotated vector. Then, the view vector is the vector from the camera to the target. I noticed that you're not normalizing that vector, but presumably you're normalizing it elsewhere.

Anyway, 'hope you get it figured out :)

This topic is closed to new replies.

Advertisement