0
\$\begingroup\$

First, I know there's a question exactly like mine, and some ohter really close, but my implementation of the solutions didn't work at all. Ok, now to the question.

I created some forms of camera based on quaternions, however, for my orbit/chase camera every quaternion I create will roll the camera in an uncontrollable manner. What I want is a function like Unity's Quaternion.LookRotation where you can pass an up vector. This is a simplification current attempt of implementation:

Vector3 target = -Position; //Because we're looking at the origin
target.Normalize();

float cosine = Vector3.Dot(Vector3.Forward, target);
Vector3 axis = Vector3.Cross(Vector3.Forward, target);
Rotation = Quaternion.CreateFromAxisAngle(axis, (float)Math.Acos(cosine));

//Trying to unroll up vector to Vector3.Up
//based on the other answer but results were unchanged
Vector3 rolledUp = Vector3.Transform(Vector3.Up, Rotation);
Vector3 right = Vector3.Cross(target, Vector3.Up);
Vector3 newUp = Vector3.Cross(right, target);

Vector3 axis2 = Vector3.Cross(rolledUp, newUp);
float angle2 = (float) Math.Acos(Vector3.Dot(rolledUp,newUp));

Rotation = Quaternion.CreateFromAxisAngle(axis2, angle2) * Rotation;

return Matrix.CreateLookAt(
    cameraPosition: Position,
    cameraTarget: Vector3.Transform(Vector3.Forward, Rotation),
    cameraUpVector: Vector3.Transform(Vector3.Up, Rotation));

If my sleepiness got in the way of my clarity, here's what I have: quaternion result

and here's what I want: rotation matrix based result

\$\endgroup\$
0
\$\begingroup\$

you should only need to rotate around the y axis or you can just say to look at the point on the y-axis at the same height of the camera

target.y=0; 
target.normalize();

of course then you can start to optimize because axis is (0,1,0) and all the other ups will be the same again (do double check that though)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy