Sign in to follow this  
sqpat

camera jumps around?

Recommended Posts

I have a camera looking at a point, and a spherical coordinate system to allow for easy camera rotations (so i'm not using transformations, i actually move the camera around.) When i hit certain points (around pi and 0 for the phi and theta angles for the coordinate system) , the camera kind of flips around, rotating 180 degrees while still looking at the same point. I don't want it to have this behavior. I thought it was an up vector issue so i tried negating the camera's up vector as these conditions come up, but that doesn't change anything. I'm sure its a newbie mistake but i can't seem to fix it or find anything on google, anyway. Any help would be appreciated.

Share this post


Link to post
Share on other sites
here's the code



D3DXMatrixLookAtLH(&m_View, &D3DXVECTOR3(pX + (rho*cos(theta)*sin(phi)),pY + (rho*sin(theta)*sin(phi)),pZ + (rho*cos(phi))),
&D3DXVECTOR3(pX, pY, pZ),
&upVect);




Basically pX, pY, and pZ are the coordinates of where you are looking at. theta, phi, and rho are spherical coordinates for the location of the camera relative to px, py, pz. When phi or theta pass multiples of pi, the flip happens.

(Rotations are just done by changing phi/theta, while zooming is done by changing rho.)

I never change the up vector which remains as (0,0,1). However i've tried negating it when the problem occurs, but the view doesn't change.

Share this post


Link to post
Share on other sites
At thoes angles, your up vector would be in the same direction as your lookat vector.

Lookat vector is LookAtPoint - EyePoint;

when phi and theta values are a multiple of PI, you get

EyePoint = (pX, pY, pZ +/- rho)
LookAtPoint = (pX, pY, pZ)

I think the up vector cannot be in the same direction as the Lookat direction.

For me I always ensure the up vector to be perpendicular to the Lookat direction, as I maintain the camera's internal axis in a camera class. I am not sure if this is the best way to go about doing though. E.g

class CCamera
{
D3DXVECTOR3 Eye;
D3DXVECTOR3 LocalAxisX;
D3DXVECTOR3 LocalAxisY;
D3DXVECTOR3 LocalAxisZ;

public:
void MakeViewMatrix(D3DXMATRIX &View)
{
D3DXMatrixLookAtLH(&View, &Eye, &(Eye + LocalAxisZ), &LocalAxisY);
}

... Other camera functions ...
};

Share this post


Link to post
Share on other sites
well, you see, when it doesnt just flip when its equal to a multiple of pi. It stays flipped until another interval is crossed. so if you rotate in a full circle, half the time it is spent in one orientation, the other half it is spent in the other orientation.

I've tried changing the up vector before it becomes equal but the same thing happens. I'll investigate your method though.

Share this post


Link to post
Share on other sites
Silly question but would just subtracting by all those values to "reset" to the starting position fix this?

For instance if you were going from 0 - 2 Pi once you reach 2 Pi you just subtract 2 Pi so that once you come a complete circle your co-ordinates reset to the beginning since 0 is = 2 Pi for that sort of rotation. I know thats a hacked up way to do things but if it works its not really much of a perf hit to reset some floats once every rotation.

Share this post


Link to post
Share on other sites
littlekid is correct. You can't have the "look" vector and the "up" vector the same.

The D3DXMatrixLookAt function calculates "normal(cross(Up, At-Eye))" for one of the matrix axes. When Up is parallel with At-Eye, the result of the cross product is 0. It's a case of gimbal lock.

One solution is, as suggested, limit your pitch angle.

Another solution, as suggested, is to recalculate your up vector each time you move the camera.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this