Best way to implement looking at point for camera in Opengl - c++

I am writing camera class for opengl and use glm for maths calculations . I use quaternions for camera orientation. I get quaternions through glm:: angleaxis. Now i am writing a function to look at point from camera position. I need to get rotation for my camera, so i found two options: use glmllookat(pos,point,vec3(0,1,0)) and converting result matrix to quaternions or use glm::quatlookat to get quaternions for rotation. But in both cases there is a gimbal lock, so i can't get proper orientation for looking upsidedown (from pos (0,3,0) to (0,0,0) for example) and further than +-90 degrees. Is there any way to get proper orientation avoiding gimbal lock and getting orientation for looking from any point to anywhere? I found and idea about alternate up vector when front == up but what vector should it be?

Related

OpenGL Stereo View -- How to use GLM Math library for horizontal offset

I'm trying to use the GLM mathematics library to warp the projection matrix such that multiple cameras (e.g. a left eye and a right eye) are viewing the same view, but the camera frustum is distorted.
This is what I am trying to do with my cameras using GLM:
image
Note: One of the challenges I have for my camera, is that I only have in my OpenGL Graphics API a read-only view matrix and projection matrix. So even once I have the view and projection matrix, I can only move my camera using x,y,z for eye position, and then yaw,pitch,roll for view direction. Then I have standard OpenGL calls, but I am not sure how to shift or warp the projection matrix as shown below.
I think this second picture also accurately shows what I am trying to achieve with OpenGL.
Any tips on how to approach this problem? Do I need to implement a special lookAt function, or is there something built into GLM that can help me compute the right view?
A possible way to do this is:
Assume that X is the position of the "nose" (the half point between the 2 eyes).
Let V be the direction orthogonal to the left eye - right eye line.
The function X + t * V describes the "line of sight" in your last
picture.
Take t > 0 and set that as your look at point P/
Create 2 cameras with centers at the eyes, both with the exact same up direction, then use glm::lookat to look at P.

How do I implement basic camera operations in OpenGL?

I'm trying to implement an application using OpenGL and I need to implement the basic camera movements: orbit, pan and zoom.
To make it a little clearer, I need Maya-like camera control. Due to the nature of the application, I can't use the good ol' "transform the scene to make it look like the camera moves". So I'm stuck using transform matrices, gluLookAt, and such.
Zoom I know is dead easy, I just have to hook to the depth component of the eye vector (gluLookAt), but I'm not quite sure how to implement the other two, pan and orbit. Has anyone ever done this?
I can't use the good ol' "transform the scene to make it look like the camera moves"
OpenGL has no camera. So you'll end up doing exactly this.
Zoom I know is dead easy, I just have to hook to the depth component of the eye vector (gluLookAt),
This is not a Zoom, this is a Dolly. Zooming means varying the limits of the projection volume, i.e. the extents of a ortho projection, or the field of view of a perspective.
gluLookAt, which you've already run into, is your solution. First three arguments are the camera's position (x,y,z), next three are the camera's center (the point it's looking at), and the final three are the up vector (usually (0,1,0)), which defines the camera's y-z plane.*
It's pretty simple: you just glLoadIdentity();, call gluLookAt(...), and then draw your scene as normally. Personally, I always do all the calculations in the CPU myself. I find that orbiting a point is an extremely common task. My template C/C++ code uses spherical coordinates and looks like:
double camera_center[3] = {0.0,0.0,0.0};
double camera_radius = 4.0;
double camera_rot[2] = {0.0,0.0};
double camera_pos[3] = {
camera_center[0] + camera_radius*cos(radians(camera_rot[0]))*cos(radians(camera_rot[1])),
camera_center[1] + camera_radius* sin(radians(camera_rot[1])),
camera_center[2] + camera_radius*sin(radians(camera_rot[0]))*cos(radians(camera_rot[1]))
};
gluLookAt(
camera_pos[0], camera_pos[1], camera_pos[2],
camera_center[0],camera_center[1],camera_center[2],
0,1,0
);
Clearly you can adjust camera_radius, which will change the "zoom" of the camera, camera_rot, which will change the rotation of the camera about its axes, or camera_center, which will change the point about which the camera orbits.
*The only other tricky bit is learning exactly what all that means. To clarify, because the internet is lacking:
The position is the (x,y,z) position of the camera. Pretty straightforward.
The center is the (x,y,z) point the camera is focusing at. You're basically looking along an imaginary ray from the position to the center.
Now, your camera could still be looking any direction around this vector (e.g., it could be upsidedown, but still looking along the same direction). The up vector is a vector, not a position. It, along with that imaginary vector from the position to the center, form a plane. This is the camera's y-z plane.

OpenGl polygon rotation

I'm trying to implement a moving and rotating polygon in OpenGl and C++.
Movement and rotation are along the XZ plane(2D transformations only).
The polygon is defined by a centre point and a set of vertices whose coordinates are stored as offsets from the centre point.
The polygon is moved based on the user's key-press either in X or Z direction by simply adding the moved distance to the centre point and updating the vertices by adding the offset values to centre coordinates.
Rotation with respect to centre point is implemented by using the glRotatef() function.
But i need to know the coordinates of vertices for collision detection calculations.
Is there any chance of just retrieving the vertex coordinates of the transformed polygon without performing matrix operations myself?
The glRotatef function creates a matrix which is multiplied with the current matrix that exists on the stack to get the rotation on screen. Even if you could obtain that matrix then you would still have to multiply it against your vectors to obtain the values you want, which is what you'd have to do if you did the maths yourself. Just like datenwolf said, it would be better for you to make a maths library yourself that will perform all the necessary things needed for manipulating objects in a 2d or 3d world.
Is there any chance of just retrieving the vertex coordinates of the transformed polygon...
OpenGL is not a math library. It's only meant for drawing. Also the matrix manipulation functions of fixed function OpenGL are obsolete and have been removed from OpenGL-3 core and further.
without performing matrix operations myself?
In fact, this is the recommended way to do this. Remember: OpenGL is just your drawing tool, not a 3D-renderer-game-simulation-engine-math-geometry-toolkit.

OpenGL ArcBall rotation and animation using interpolation?

In my OpenGL application I need to use ArcBall rotation to rotate objects using mouse.
I relized that I have to go with Quaternions after reading this article - http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095
And I found an easy to use implementation at here - http://www.codeproject.com/KB/openGL/virtualtrackball.aspx
But my problem is I also need to animate my object between saved two status.
That is -
State(1)= (Postition X1,Position Y1,Position Z1, Rotation 1);
State(2)= (Postition X2,Position Y2,Position Z2, Rotation 2);
*These 'Rotations' are rotation matrices
And the animation is done in n steps.
Something like shown in this video - http://www.youtube.com/watch?v=rrUCBOlJdt4
If I was using 3 seperate angles for three axises(roll, pitch, yaw) I could easily interpolate the angles.
But ,since ArcBall uses rotation Matrix , how can I interpolate the rotations between State 1 and State2 ?
Any suggestions ?
Use quaternions (SLERP). Neither rotation matrices nor Euler angles are appropriate for interpolation.
See 45:05 here (David Sachs, Google Tech Talk).
See also Interpolating between rotation matrices
Either use Matrix or Quaternion for rotation representation internally. With roll/pitch/yaw you could interpolate the angles in theory, but this will not work every time - read up on Gimbal lock.
With Quaternions the rotation interpolation is easy - just interpolate the individual coordinates (just as you would with r/p/y angles), normalizing when necessary. You'd have to then adjust your rendering function to work with quaternions (but I assume you already did that since you mention quaternions youself).
With Matrixes the interpolation is not so nice, I've struggled with it several years back and all I can remember it that I finally decided to go with quaternions. So I can't advice on this, sorry.

Best way to make a camera both move and rotate

I'm learning some OpenGL game programing, and I'm stuck in how to implement so the camera follows the mousepointer. Like in a fps game you want to look where your mouse is pointing, but I can't find a nice solution to this while I'm moving. I was thinking of saving one matrix for the move, like walkking and strafing, while using quaternions to handle the rotation. Then make the quaternion to a rotationmatrix, load the identity for the modelview matrix and time this matrix with both matrixes.
There is ofcourse some problems with this, like which matrix we should use in the multiplication first, and the code will be ugly.
So I'm wondering if anyone have a good solution to solving this, so I don't have to find out which matrix to use first, and which gives cleaner code.
Store the camera's view details as a position vector, a view-vector and an up-vector (think of pointing with your thumb stuck out: your finger is the view-vector, and your thumb is the up-vector). Keep these vectors normalized and at 90 degrees to each other. You should be able to see that these three vectors are sufficient to represent any camera position and orientation.
You can use these vectors to transform world-coordinates to camera-coordinates:
Translate by -position;
Rotate around (up-vector 'cross' y-axis) by -(angle between up-vector and y-axis);
Rotate around up-vector by -(angle between view-vector and z-axis).
(I might have got some of my signs the wrong way around there).
You can transform these vectors as the user moves the mouse:
As the mouse moves sideways, rotate the view-vector around the up-vector (or rotate both view-vector and up-vector around y-axis, if you prefer).
As the mouse moves back/forwards, rotate both the view-vector and up-vector around (view-vector 'cross' up-vector).
I don't really have a solution for your problem, but i know the open-source 3d engine Irrlicht has a FPS camera that does exactly what you're looking for and, usually, it has a well-documented source.
You could try looking at how the FPS camera is implemented in Irrlicht or you could even use Irrlicht itself for your project; i used it for a couple of mine when i was in college and it always worked like a charm :)