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