Jump to content

  • Log In with Google      Sign In   
  • Create Account


Restricting Camera


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • This topic is locked This topic is locked
18 replies to this topic

#1 Medo3337   Members   -  Reputation: 619

Like
0Likes
Like

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

Sponsor:

#2 MJP   Moderators   -  Reputation: 8751

Like
2Likes
Like

Posted 18 December 2012 - 08:49 PM

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.

#3 Medo3337   Members   -  Reputation: 619

Like
0Likes
Like

Posted 18 December 2012 - 09:03 PM

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?

#4 L. Spiro   Crossbones+   -  Reputation: 9723

Like
0Likes
Like

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
It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#5 Medo3337   Members   -  Reputation: 619

Like
-1Likes
Like

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.

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


#6 L. Spiro   Crossbones+   -  Reputation: 9723

Like
1Likes
Like

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

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

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#7 Alin   Members   -  Reputation: 391

Like
2Likes
Like

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

#8 Medo3337   Members   -  Reputation: 619

Like
-1Likes
Like

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.

#9 L. Spiro   Crossbones+   -  Reputation: 9723

Like
2Likes
Like

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

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

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#10 Medo3337   Members   -  Reputation: 619

Like
-1Likes
Like

Posted 19 December 2012 - 12:22 AM

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

#11 GuyWithBeard   Members   -  Reputation: 649

Like
1Likes
Like

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

#12 Medo3337   Members   -  Reputation: 619

Like
-1Likes
Like

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:
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 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

#13 L. Spiro   Crossbones+   -  Reputation: 9723

Like
1Likes
Like

Posted 19 December 2012 - 06:59 AM

Are you seriously unable to add semicolons for yourself?

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

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

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums

#14 Medo3337   Members   -  Reputation: 619

Like
-1Likes
Like

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.


#15 BCullis   Crossbones+   -  Reputation: 1799

Like
1Likes
Like

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.
Hazard Pay :: FPS/RTS in SharpDX
DeviantArt :: Because right-brain needs love too

#16 Medo3337   Members   -  Reputation: 619

Like
-2Likes
Like

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,

#17 MisterFuzzy   Banned   -  Reputation: 161

Like
0Likes
Like

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

 


#18 Medo3337   Members   -  Reputation: 619

Like
-1Likes
Like

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.


#19 Tom Sloper   Moderators   -  Reputation: 7447

Like
0Likes
Like

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS