• Advertisement
Sign in to follow this  

how to rotate camera to new orientation?

This topic is 2348 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I've been playing with a new idea that I had and I need help with the math, as I only have a basic understanding of linear algebra. I have a first-person camera in a hollow cube. I can adjust the gravity so that a wall becomes the new floor, and the camera falls appropriately. I can orient the camera to any side of the cube and the camera rotates correctly with mouse movements. Now I want a smooth transition from one orientation to another and I haven't quite figured it out. For example, if the current orientation is (0, 1, 0) = up, how do I get a smooth camera rotation if it changes to (-1, 0 0) = up? Is there a general solution to this problem or will I have to handle special cases?

Currently I accumulate the mouse's X and Y movements in yaw and pitch variables. Every frame I use yaw and pitch to build a quaternion which is then used to transform the camera's up and forward vectors for the view matrix. Is this sufficient for what I'm trying to accomplish or should I be doing something different?

Here is an example I found of what I'm trying to accomplish. The relevant part starts about 1:20.

Share this post

Link to post
Share on other sites
I found this thread that seems to describe what I'm after. This is from the first reply:

[color=#1C2837][size=2]1. Construct a quaternion that rotates (over the shortest arc) the player's current up vector into alignment with the target up vector.[color=#1C2837][size=2]
2. Multiply this quaternion with your current orientation quaternion to yield your target orientation.

3. Slerp between the current and target orientations as you're doing currently.[/quote]

How do I do find the quaternion that rotates the current up vector to match the new up vector?

Share this post

Link to post
Share on other sites

How do I do find the quaternion that rotates the current up vector to match the new up vector?

Find rotation axis - if your up vectors are V1 and V2, then

[font="Courier New"]Vaxis = V1 X V2[/font]

Find rotation angle

[font="Courier New"]cos(angle) = normalize (V1) . normalize (V2)[/font]

Now you can either use rotation axis-angle directly for interpolation, or convert it to quaternion.

Read more from The Matrix and Quaternions FAQ

Share this post

Link to post
Share on other sites
I found this solution here that works perfectly for my purposes, although I don't quite understand why the world matrices work for this. Here's my XNA/C# code:

// create a quaternion to represent the old orientation
// oldForward and oldUp are the current camera orientation
Matrix oldOrientation = Matrix.CreateWorld(Vector3.Zero, oldForward, oldUp);
Quaternion oq = Quaternion.CreateFromRotationMatrix(oldOrientation);

// create another quaterion to represent the new orientation
// camForward and camUp are the new orientation
Matrix newOrientation= Matrix.CreateWorld(Vector3.Zero, camForward, camUp);
Quaternion nq = Quaternion.CreateFromRotationMatrix(newOrientation);

// interpolate from old to new orientation
// s now represents the intermediate orientation
// slerpAmount ranges from 0 to 1
Quaternion s = Quaternion.Slerp(oq, nq, slerpAmount);

// turn the intermediate quaternion into a matrix
Matrix rm = Matrix.CreateFromQuaternion(s);

// extract vectors from the matrix
Vector3 up = rm.Up;
Vector3 forward = rm.Forward;
Vector3 right = rm.Right;

// use the extracted vectors to create a rotation quaternion for the camera this frame
Quaternion rotation = Quaternion.CreateFromAxisAngle(up, yaw);
rotation = rotation * Quaternion.CreateFromAxisAngle(right, pitch);

// use the extracted vectors and the rotation quaternion to construct our view matrix for this frame

forward = Vector3.Transform(forward, rotation);
Vector3 cameraLookat = forward + cameraPosition;
up = Vector3.Transform(up, rotation);

viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraLookat, up);

Hope this helps someone else.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement