Search code examples
c#xnaquaternions

XNA / C# - Making the Z component of a Quaternion a fixed angle value? Or is there another way?


I've spent about maybe 3 hours trying to get this to work... In my developing 3D game, I already have a camera and a world matrix space. What I want to do is to make it so when you turn the camera left or right, the camera also tilts/banks left or right. However, all the methods I have tried (Slerp, making new matrix & Concatenate, setting quaternion.Z directly, etc) all failed.

Fortunately, my roll is calculated as a angle that WOULD be returned if you got the Z angle of the quaternion (It increases/decreases and goes back to 0 as you move mouse.) I'm wondering if you can set the angle for the local angle space for the camera directly with no problems. I'm inputting values between 13 and -13 which I can change to radians.

Thanks in advance :)


Solution

  • Let's say that your current perspective of the scene can be represented by q_c. When the mouse moves to the right, you want q_c to begin rotating around its own y axis (assuming here that y is up, x is right and -z is forward) by an amount possibly proportional to the mouse displacement. So you'll typically form a new quaternion from the axis/angle representation q_y = quatFromAxisAngle(turnRate,0,1,0): rotate by turnRate around the y axis. Then you apply that transformation to your quaternion to get your new perspective on the scene: q_c' = q_y*q_c (using quaternion multiplication, of course).

    Now, if you want to then add some local "roll" to the perspective, you just need to do the same thing around the z axis, but keep a copy of the 'un-rolled' perspective:
    q_z = quatFromAxisAngle(roll,0,0,-1)
    q_d = q_z*q_c'.

    Then you use q_d to display the scene, but you throw it away afterward and always work with q_c. That way, you maintain a consistent up axis to spin around and when you're done 'rolling' you just stop applying that final rotation around the local 'z' axis.