Stardreamer
Stardreamer

Reputation: 83

Camera looking at a sphere - pole wrapping

I have a 3D camera that is centered on a point on a sphere's surface. It follows and rotates around it perfectly, except at the poles of the sphere. Note that the sphere is actually a cube projected to a sphere for easier management of position coordinates.

If the object moves horizontally around the sphere, the camera works as intended. But, if the object traverses towards the top or bottom pole of the sphere, the camera wraps around the pole. If it goes straight through the pole, it will appear to do a 180 degree turn as it passes through.

I understand why this is happening - there must be a global Up vector for the camera to know how to orient itself. If I change it's Up vector to a different direction, such as Right, the camera no longer flips around the top or bottom poles, but instead exhibits the same behavior on the left and right poles of the sphere.

My question is how to change my camera's behavior so that this doesn't happen. What I would like is for my camera to feel as though the camera was in a constant position, looking at the sphere, and the sphere rotating on its X and Z axis.

I realize that this could result in "wrong" orientations - eg, if the user starts at the front face of the sphere, goes up, then left, they'll end up on the left side of the sphere but the camera is rotated 90 degrees on its Z axis, whereas if they started at the front face and moved directly to the left face there would be no rotation. This is fine, since I can detect when the camera crosses a face and slowly "fix" the camera's local rotation, or allow the user to unlock the camera and they can handle the camera's angle themselves.

For reference, my camera is presently being calculated using the solution in this question: Camera rotation aligned to arbitrary plane

Any insight would be appreciated!

Upvotes: 2

Views: 464

Answers (1)

comingstorm
comingstorm

Reputation: 26097

If you want the sphere to act like a trackball, apply incremental rotations (say, x-axis and y-axis) to the rotation matrix as specified by the user control.

You will still need to "re-normalize" the rotation matrix after updates -- otherwise, numerical error will creep in, and your rotation matrix will eventually not be a rotation matrix. The computation should go something like this:

update =  RotX(userInput.dX) * RotY(userInput.dY)
rawUpdatedRot = userRot * update
newZ = Normalize( Cross(rawUpdatedRot.x, rawUpdatedRot.y) )
newY = Normalize( Cross(newZ, rawUpdatedRot.x) )
newX = Normalize( rawUpdatedRot.x )
userRot = Matrix(newX, newY, newZ)

Upvotes: 1

Related Questions