问题
I have what I think is a fairly simple scenario for a camera, but my caveman brain refuses to think in anything more than two dimensions.
My 3D camera needs to be aligned behind an object. This object can stick to any surface, and thus the camera's idea of what "up" is can be any arbitrary vector. It's very similar to this question, but since I'm not directly controlling the 'player' object and am instead trying to use CreateLookAt, I'm having trouble making sense of the solution: How can I calculate the rotation when using a quaternion camera?
For the sake of simplified testing, let's assume that the object is on a sphere.
I currently have:
- The target object's absolute position in 3D space.
- A unit vector representing the normal of the surface the object is presently on. In this case, the normal of the triangle on the sphere.
- The X and Y angles describing how the camera should be orbiting the object.
I believe that this is all that's required, but I'm not sure how to put it all together in a way that works. I know that I need to transform the angle'd camera by the object's norMy best attempt is as follows:
Matrix orientation = Matrix.CreateRotationY(OrbitYaw) * Matrix.CreateRotationX(OrbitPitch);
orientation.Up = CurrentNormal;
orientation.Right = Vector3.Cross(orientation.Forward, orientation.Up);
orientation.Right = Vector3.Normalize(orientation.Right);
orientation.Forward = Vector3.Cross(orientation.Up, orientation.Right);
orientation.Forward = Vector3.Normalize(orientation.Forward);
Vector3 Target = ObjectPosition;
Vector3 Position = Vector3.Transform(new Vector3(0,50,0), orientation);
Matrix View = Matrix.CreateLookAt(Position, Target, CurrentNormal);
The positioning code seems to be correct, but it's very difficult to tell because of the second problem: the camera appears to "roll" as the position changes. This makes sense - all the camera knows is its position and where to look, and I'm not explicitly telling it how it itself should be rotated. This is what I need to do, so that the camera maintains a constant alignment (aside from what's necessary to keep it in the same relative position) while following the object.
回答1:
Expanding a little on what Tim S said in his comment, you can borrow some aspects of the orientation from the object the camera is following to get the camera's orientation going.
cameraPosition = objectPosition + (objectOrientation.Backward * 50);
cameraTarget = objectPosition;
Matrix cameraArc = Matrix.CreateFromAxisAngle(objectOrientation.Up, orbitYaw) * Matrix.CreateFromAxisAngle(objectOrientation.Right, orbitPitch);//assumes objectOriention is a ortho-normal matrix
cameraPosition = Vector3.Transform(cameraPosition - cameraTarget, cameraArc) + cameraTarget;
view = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);
Despite plugging Vector3.Up
into the last line (which you should do in your case), the view matrix's up vector will be in alignment with the object's up vector.
来源:https://stackoverflow.com/questions/15499922/camera-rotation-aligned-to-arbitrary-plane