Restricting Camera

Started by
17 comments, last by Tom Sloper 11 years, 3 months ago
I'm rotating the camera with the cursor up, down, right and left, I'm trying to restrict the up and down rotation.

How can I calculate the camera up/down angle from (m_vRight, m_vUp, m_vLook) so I can stop the rotation If the up/down reaches 90 degree / -90 degree (FPS Camera)?
Advertisement
What I usually do is I store rotations about the X and Y axis as single floats, and then every frame I build a world and view matrix from those values. If you do it that way it's trivial to clamp the rotations to a certain range.
I'm using the following to change the rotation up and down according to the cursor:


// nYDiff = difference between current cursor position and last cursor position
D3DXMatrixRotationAxis( &matRotation, &m_vRight, D3DXToRadian((float)nYDiff / 6.0f));
D3DXVec3TransformCoord( &m_vLook, &m_vLook, &matRotation );
D3DXVec3TransformCoord( &m_up, &m_vUp, &matRotation );


How can I get up/down angle in this case?
Store the direction your character is facing in spherical coordinates.
You only need to store the inclination ? and azimuth ?, since r will always be 1.
The inclination is the amount up you are facing. Cap it between (0.001) and (pi - 0.001) (or so).

Convert to a forward direction via a Cartesian coordinate system conversion:
m_vLook.x = sin( ? ) * cos( ? )
m_vLook.z = sin( ? ) * sin( ? )
m_vLook.y = cos( ? )

Notice that z and y are swapped compared to the Wikipedia page, which assumes Z to be up.

With the forward (“look” as you call it) vector created you can easily determine the up and right vectors and compose the rest of the matrix.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

@L. Spiro: I think you didn't understand my question well, I'm basically trying to restrict the camera up/down rotation, the camera should never rotate more than 90 degrees or less than -90 degree.

So I want to get the angle of the camera up/down rotation, so I can do something like.


int angle = ???; // I'm trying to get the camera up/down angle here...
if (angle < 90 && angle > -90)
{
// Rotate the camera up and down according to the cursor Y axis.
}
I think you did not understand my answer well. I told you exactly how to do it.
Inclination ? = angle up and down.
Cap it between (0.001) and (? - 0.001) (or so).
If ? is 0.0, angle = 90 degrees.
If ? is ?, angle = -90 degrees.

Read my reply again until you get it.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

D3DXVECTOR3 V = m_vUp;
D3DXVECTOR3 Y = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXVec3Normalize( &V, &V );
D3DXVec3Normalize( &Y, &Y );
float angle = acos( D3DXVec3Dot( &V, &Y ) ) * 180.0f / M_PI;
if (angle < 90)
{
// Rotate the camera up and down according to the cursor Y axis.
}
Okay, the problem is resolved, but now I have another problem, when the rotation reach 90 degree on pitch, if the player kept trying to move the mouse up, Right/Left rotation will mess up, it will make the camera show like the character is rotating around himself.
That is probably because you are clamping between -90° and 90° instead of using an epsilon as I suggested (you didn’t provide any code so who can know?).
Clamp between -89° and 89°. You can’t look straight up if your math is hard-coded to use (0.0, 1.0, 0.0) for up in your cross products. You can’t calculate a right vector if both your forward (“look”) and world up vectors are the same.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

@L. Spiro: The code I'm using to change "Pitch":

void Camera::pitch(float radians)
{
radians = (m_invertY) ? -radians : radians;
m_pitch -= radians;
if (m_pitch > m_maxPitch)
{
radians += m_pitch - m_maxPitch;
}
else if (m_pitch < -m_maxPitch)
{
radians += m_pitch + m_maxPitch;
}

D3DXMATRIX matRotation;
D3DXMatrixRotationAxis( &matRotation, &m_right, radians );
D3DXVec3TransformNormal( &m_up, &m_up, &matRotation );
D3DXVec3TransformNormal( &m_look, &m_look, &matRotation );
}


?I'm not sure how I can use the way you mentioned, maybe you can explain more programmatically instead of mathematically.

This topic is closed to new replies.

Advertisement