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)?
Restricting Camera
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:
How can I get up/down angle in this case?
// 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
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
@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.
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
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
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.
}
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
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
@L. Spiro: The code I'm using to change "Pitch":
?I'm not sure how I can use the way you mentioned, maybe you can explain more programmatically instead of mathematically.
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
Popular Topics
Advertisement