18 replies to this topic

Posted 18 December 2012 - 07:59 PM

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)?

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)?

Posted 18 December 2012 - 09:03 PM

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?

Posted 18 December 2012 - 09:15 PM

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

My Art: http://l-spiro.deviantart.com/gallery/4844241/Realism My Music: https://soundcloud.com/l-spiro

L. Spiro Engine: http://lspiroengine.com

L. Spiro Engine Forums: http://lspiroengine.com/forums

L. Spiro Engine: http://lspiroengine.com

L. Spiro Engine Forums: http://lspiroengine.com/forums

Posted 18 December 2012 - 09:26 PM

@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. }

Posted 18 December 2012 - 09:55 PM

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

**Edited by L. Spiro, 18 December 2012 - 10:01 PM.**

My Art: http://l-spiro.deviantart.com/gallery/4844241/Realism My Music: https://soundcloud.com/l-spiro

L. Spiro Engine: http://lspiroengine.com

L. Spiro Engine Forums: http://lspiroengine.com/forums

L. Spiro Engine: http://lspiroengine.com

L. Spiro Engine Forums: http://lspiroengine.com/forums

Posted 18 December 2012 - 10:41 PM

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.

}

Posted 18 December 2012 - 10:56 PM

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.

Posted 18 December 2012 - 11:58 PM

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

**Edited by L. Spiro, 19 December 2012 - 07:32 AM.**

My Art: http://l-spiro.deviantart.com/gallery/4844241/Realism My Music: https://soundcloud.com/l-spiro

L. Spiro Engine: http://lspiroengine.com

L. Spiro Engine Forums: http://lspiroengine.com/forums

L. Spiro Engine: http://lspiroengine.com

L. Spiro Engine Forums: http://lspiroengine.com/forums

Posted 19 December 2012 - 12:22 AM

@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

Posted 19 December 2012 - 04:59 AM

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

We are actually doing you a favor by explaining the theory, instead of just giving you code. L. Spiro has told you several times to clamp your pitch, so do that. You cannot have your look-vector be the same as the up-vector and calculate a right vector the way you are doing. Because the vectors are the same, you cannot do a cross product on them (or you can, but it will be zero). This means that you have limit the pitch to something smaller than 90 degrees, if your up-vector is 90 degrees (eg. upwards).

Posted 19 December 2012 - 06:31 AM

I want to mention that the my camera update code is probably different than what you expect, please take a look over here:

The FPS camera is working**perfectly**, except the little problem that I mentioned (When the up angle is 90 degree and the player try to rotate the mouse up more, right/left start to work which show that the player is rotating around himself).

I have uploaded a video to explain the problem better:

http://www.youtube.com/watch?v=ytiuA9jQDmY

void updateCamera() { if ( D3DXVec3Length( &m_velocity ) > m_maxVelocity ) { m_velocity = *(D3DXVec3Normalize( &m_velocity, &m_velocity )) * m_maxVelocity; } m_position += m_velocity; m_velocity = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); m_lookAt = m_position + m_look; // Calculate the new view matrix D3DXVECTOR3 up = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtLH( &m_view, &m_position, &m_lookAt, &up ); // Set the camera axes from the view matrix m_right.x = m_view._11; m_right.y = m_view._21; m_right.z = m_view._31; m_up.x = m_view._12; m_up.y = m_view._22; m_up.z = m_view._32; m_look.x = m_view._13; m_look.y = m_view._23; m_look.z = m_view._33; // Calculate yaw and pitch float lookLengthOnXZ = sqrtf( m_look.z * m_look.z + m_look.x * m_look.x ); m_pitch = atan2f( m_look.y, lookLengthOnXZ ); }

The FPS camera is working

I have uploaded a video to explain the problem better:

http://www.youtube.com/watch?v=ytiuA9jQDmY

Posted 19 December 2012 - 06:59 AM

Are you seriously unable to add semicolons for yourself?

I said this:

**It was code from the first time I posted it.**

Pick your variable for θ (I chose i but it could be anything), pick your variable for φ (I chose a but it could be anything), and add semicolons. Seriously?

You already know that θ is the vertical angle and φ is the horizontal angle. Moving the mouse up and down changes θ and moving it sideways changes φ. Cap vertical movement? Cap θ.

I am sorry, but how am I supposed to make this any more obvious?

I gave you the code from the start. You took one glance, saw a single symbol that was not C++, and decided it was a useless post. “Please give me code,” you instantly replied, yet the code was already there.

This is exactly what almost every book is going to give you, so if you can only handle to be spoon-fed I am not sure how far you will be able to go as a programmer.

L. Spiro

I said this:

m_vLook.x = sin( θ ) * cos( φ ) m_vLook.z = sin( θ ) * sin( φ ) m_vLook.y = cos( θ )Which becomes this in code:

m_vLook.x = sin( i ) * cos( a ); m_vLook.z = sin( i ) * sin( a ); m_vLook.y = cos( i );Where i was “inclination” (the radians up or down your player faces) (notice how I said it was “inclination” and then gave the variable “i” as a substitute) and “a” is azimuth (the radians horizontally your player faces) and you weren’t able to figure out how to convert symbols to letters and add semicolons?

Pick your variable for θ (I chose i but it could be anything), pick your variable for φ (I chose a but it could be anything), and add semicolons. Seriously?

You already know that θ is the vertical angle and φ is the horizontal angle. Moving the mouse up and down changes θ and moving it sideways changes φ. Cap vertical movement? Cap θ.

I am sorry, but how am I supposed to make this any more obvious?

I gave you the code from the start. You took one glance, saw a single symbol that was not C++, and decided it was a useless post. “Please give me code,” you instantly replied, yet the code was already there.

This is exactly what almost every book is going to give you, so if you can only handle to be spoon-fed I am not sure how far you will be able to go as a programmer.

L. Spiro

**Edited by L. Spiro, 19 December 2012 - 07:56 AM.**

L. Spiro Engine: http://lspiroengine.com

L. Spiro Engine Forums: http://lspiroengine.com/forums

Posted 19 December 2012 - 08:13 AM

This is exactly what almost every book is going to give you, so if you can only handle to be spoon-fed I am not sure how far you will be able to go as a programmer.

@L. Spiro:

I don't appreciate your reply, I have been programming for 10 years in around 12 different programming/scripting languages and I'm completely new to DirectX and 3D games programming.

You seriously need to never judge other people.

Anyway, Thanks for trying to help, the question was resolved by simply decreasing max_pitch value.

**Edited by Medo3337, 19 December 2012 - 10:31 AM.**

Posted 19 December 2012 - 11:52 AM

Time spent doing something isn't necessarily the best metric for skill, especially in an ambiguously multi-disciplinary field like programming. Given some of your recent threads and the kind of feedback you give in discussion, I'm surprised to hear you're a seasoned programmer with 10 years of experience.

Spiro knows their stuff, and explained what you needed the first time around. Computer science and programming is effectively a subset and intersection of branches of mathematics, so if you've been programming for 10 years and that should indicate "how far you've gone" as a programmer, you should be able to make use of a mathematical explanation. Not to mention, 3d programming and graphics is HUGELY math-driven. Your learning process is going to be pretty blind until you grasp the mechanics behind the functions you're calling.

Looking a several of your recent threads, you're missing a lot of the "why" and theory behind what you're trying to accomplish, which is making your task much harder. I'd embrace any assistance that tries to teach you theory and reasoning over directly handing you code.

Tip: "You seriously need to" ditch the ego.

As for your camera issues, I know you've solved the problem but here's another approach that I think is simpler to manage: create a rotation matrix that represents the camera's per-axis rotations (yawpitchroll in some form) which can be calculated off stored rotation values. Here's where the clamp can be applied to your pitch, as well. Then every update call, just apply the newly calculated rotation matrix to a unit forward, up, and right vector (unit x, y, and z respectively) and use those to create your look-at (view) matrix.

...And in retrospect I just described MJP's approach. Hooray redundancy.

Spiro knows their stuff, and explained what you needed the first time around. Computer science and programming is effectively a subset and intersection of branches of mathematics, so if you've been programming for 10 years and that should indicate "how far you've gone" as a programmer, you should be able to make use of a mathematical explanation. Not to mention, 3d programming and graphics is HUGELY math-driven. Your learning process is going to be pretty blind until you grasp the mechanics behind the functions you're calling.

Looking a several of your recent threads, you're missing a lot of the "why" and theory behind what you're trying to accomplish, which is making your task much harder. I'd embrace any assistance that tries to teach you theory and reasoning over directly handing you code.

Tip: "You seriously need to" ditch the ego.

As for your camera issues, I know you've solved the problem but here's another approach that I think is simpler to manage: create a rotation matrix that represents the camera's per-axis rotations (yawpitchroll in some form) which can be calculated off stored rotation values. Here's where the clamp can be applied to your pitch, as well. Then every update call, just apply the newly calculated rotation matrix to a unit forward, up, and right vector (unit x, y, and z respectively) and use those to create your look-at (view) matrix.

...And in retrospect I just described MJP's approach. Hooray redundancy.

Hazard Pay :: FPS/RTS in SharpDX (gathering dust, retained for... historical purposes)

DeviantArt :: Because right-brain needs love too (also pretty neglected these days)

Posted 19 December 2012 - 12:19 PM

Just to let you know, I started programming since I was around 10-11 years old, right now I'm 20, have been focusing on software and web development much more than mathematics, I know 3D games programming has alot of math involved and physics as well, I'm in hurry to complete the 3D Game Engine that I'm working on.

Thanks everyone,

Thanks everyone,

Posted 28 December 2012 - 07:32 PM

I started programming since I was around 10-11 years old

Whee-hee. So did many of the other users here. Heck, I'm pretty sure some of the people who post around here are STILL 10-11 years old. However, as stated before, you are asking for someone to just give you the code you want. All that will do is force you to come back to the forums and beg when you can't do the same thing later on. MJP gave you a REALLY easy way to do it, L. Spiro, although somewhat curtly, gave you the answer you needed as well. Just... Listen.

"Only idiots quote themselves" - MisterFuzzy

Posted 28 December 2012 - 11:29 PM

@MisterFuzzy: You really need to show some respect to other members, the problem was resolved weeks ago and I have reported your reply and yes I tried L. Spiro solution and it didn't work as expected.

**Edited by Medo3337, 28 December 2012 - 11:35 PM.**

Posted 29 December 2012 - 09:24 AM

That's enough. Closing this down.

-- Tom Sloper

Sloperama Productions

Making games fun and getting them done.

www.sloperama.com

**Please do not PM me. **My email address is easy to find, but note that I do not give private advice.

Sloperama Productions

Making games fun and getting them done.

www.sloperama.com