Jump to content
  • Advertisement
Sign in to follow this  
ReDevilGames

OpenGL Weird vertical camera rotation

This topic is 993 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi at all! I'm playing and experimenting with OpenGL. I wanted to do a 3D camera, and this is the algorithm I used:

1) Store global mouse coordinates
2) Reset mouse position at the center of the screen
3) Increment horizontal and vertical camera directions by the variation of mouse coordinates (what others call "delta" mouse coordinates, computed from the difference of previous stored variables)
4) Compute X, Y and Z position using trigonometry, then pass to the glm::lookAt object.

The horizontal rotation it's OK, but the vertical one isn't. I think the problem is the gimbal lock... I've noticed that I used two axis for the horizontal one, and only one for the vertical one. So, as far as I know from a book I've read, I should use quartenions because it adds a fourth dimension. I've not yet studied quartenions at school (I am at the last year of high school)...

 

This is what happens:

 

2dqtyrr.gif

 

 

So, can you give me a quick solution or explanation to this problem?

Thanks in advance for any answer!

This is the code if you need it:

// Projection matrix : 45° Field of View, calculated aspect ratio, display range : 0.1 to 100 units
projection = glm::perspective(glm::radians(45.0f), Screen.aspectRatio, 0.1f, 65535.0f);

// Compute camera directions
float cpos[] = { 0.0f, 0.0f, 0.0f };
int mpos[] = { 0, 0 };

SDL_GetGlobalMouseState(&mpos[0], &mpos[1]);
SDL_WarpMouseGlobal(Screen.displayMode.w / 2, Screen.displayMode.h / 2);

Params.h_dir += (float)(mpos[0] - Screen.displayMode.w / 2) / Params.mousePrecision;
Params.v_dir += (float)(mpos[1] - Screen.displayMode.h / 2) / Params.mousePrecision;

cpos[0] = Position.x + cos(glm::radians(Params.h_dir)) * Params.distance;
cpos[1] = Position.y + sin(glm::radians(Params.v_dir)) * Params.distance;
cpos[2] = Position.z + sin(glm::radians(Params.h_dir)) * Params.distance;

// Camera matrix
view = glm::lookAt(
	glm::vec3(cpos[0], cpos[1], cpos[2]), // Camera is at computed position in World Space
	glm::vec3(Position.x, Position.y, Position.z), // and looks at the origin
	glm::vec3(0, 1, 0)  // Head is up (set to 0, -1, 0 to look upside-down)
);
Edited by ReDevilGames

Share this post


Link to post
Share on other sites
Advertisement

You seem to map the mouse pointer position to a kind of inclination and azimuth pair of angles, using them together with a fix distance (radius) as spherical coordinates, convert that into cartesian coordinates, and transform that from object local into global space.

 

Accordingly to the formulas found e.g. at the end of the section here, your trigonometry isn't correct then.

Edited by haegarr

Share this post


Link to post
Share on other sites
Mmhh, Ok, I managed to do a nice third person camera with little changes:
cpos[0] = Position.x + cos(glm::radians(Params.v_dir)) * cos(glm::radians(Params.h_dir)) * Params.distance;
cpos[1] = Position.y + sin(glm::radians(Params.v_dir)) * Params.distance;
cpos[2] = Position.z + cos(glm::radians(Params.v_dir)) * sin(glm::radians(Params.h_dir)) * Params.distance;

I also restricted vertical rotation to stay between [-90, 90]. It's nice :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!