OpenGL ArcBall rotation and animation using interpolation? - opengl

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.

Related

OpenGl rotations and translations

I am building a camera class to look arround a scene. At the moment I have 3 cubes just spread arround to have a good impression of what is going on. I have set my scroll button on a mouse to give me translation along z-axis and when I move my mouse left or right I detect this movement and rotate arround y-axis. This is just to see what happens and play arround a bit. So I succeeded in making the camera rotate by rotating the cubes arround the origin but after I rotate by some angle, lets say 90 degrees, and try to translate along z axis to my surprise I find out that my cubes are now going from left to right and not towards me or away from me. So what is going on here? It seems that z axis is rotated also. I guess the same goes for x axis. So it seems that nothing actually moved in regard to the origin, but the whole coordinate system with all the objects was just rotated. Can anyone help me here, what is going on? How coordinate system works in opengl?
You are most likely confusing local and global rotations. Usual cheap remedy is to change(reverse) order of some of your transformation. However doing this blindly is trial&error and can be frustrating. Its better to understand the math first...
Old API OpeGL uses MVP matrix which is:
MVP = Model * View * Projection
Where Model and View are already multiplied together. What you have is most likely the same. Now the problem is that Model is direct matrix, but View is Inverse.
So if you have some transform matrix representing your camera in oder to use it to transform back you need to use its inverse...
MVP = Model * Inverse(Camera) * Projection
Then you can use the same order of transformations for both Model and Camera and also use their geometric properties like basis vectors etc ... then stuff like camera local movements or camera follow are easy. Beware some tutorials use glTranspose instead of real matrix Inverse. That is correct only if the Matrix contains only unit (or equal sized) orthogonal basis vectors without any offset so no scale,skew,offset or projections just rotation and equal scale along all axises !!!
That means when you rotate Model and View in the same way the result is opposite. So in old code there is usual to have something like this:
// view part of matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotate3f(view_c,0,0,1); // ugly euler angles
glRotate3f(view_b,0,1,0); // ugly euler angles
glRotate3f(view_a,1,0,0); // ugly euler angles
glTranslatef(view_pos); // set camera position
// model part of matrix
for (i=0;i<objs;i++)
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(obj_pos[i]); // set camera position
glRotate3f(obj_a[i],1,0,0); // ugly euler angles
glRotate3f(obj_b[i],0,1,0); // ugly euler angles
glRotate3f(obj_c[i],0,0,1); // ugly euler angles
//here render obj[i]
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
note the order of transforms is opposite (I just wrote it here in editor so its not tested and can be opposite to native GL notation ... I do not use Euler angles) ... The order must match your convention... To know more about these (including examples) not using useless Euler angles see:
Understanding 4x4 homogenous transform matrices
Here is 4D version of what your 3D camera class should look like (just shrink the matrices to 4x4 and have just 3 rotations instead of 6):
reper4D
pay attention to difference between local lrot_?? and global grot_?? functions. Also note rotations are defined by plane not axis vector as axis vector is just human abstraction that does not really work except 2D and 3D ... planes work from 2D to ND
PS. its a good idea to have the distortions (scale,skew) separated from model and keep transform matrices representing coordinate systems orthonormal. It will ease up a lot of things latter on once you got to do advanced math on them. Resulting in:
MVP = Model * Model_distortion * Inverse(Camera) * Projection

Best way to implement looking at point for camera in Opengl

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?

Correct way to translate in a 3D world after rotating?

I have a basic cube generated in my 3D world. I can rotate correctly around the camera, but when I translate after rotating, the translations are not correct.
For example, if I rotate 90 degrees and translate into the Z axis, it would move as if translating in the X axis.
glLoadIdentity();
glRotatef(angle,0,1,0); //Rotate around the camera.
glTranslatef(movX,movY,movZ); //Translate after rotating around the camera.
glCallList(cubes[0]);
I need some help with this. Also, I tried translating before rotating, but the rotation is not at the camera. It is at the edge of the cube.
Keep in mind that in OpenGL that the transformation is applied to the camera, not the objects rendered; so you observe the inverse of the transformation you expected.
Also in OpenGL the Y and Z axes are flipped (Y is vertical), so you observe a horizontal translation instead of a vertical one.
Also, because the object is rotated though 90 degrees about Y, the X and Z axes replace each other (one of them is reversed).
willywonkadailyblah's answer is half correct. Because you are using the old OpenGL, you're using the old matrix stack. You are modifying the modelview matrix when you're doing your glRotatef and glTranslatef calls. The modelview matrix is actually the model's matrix and the camera's view matrix precombined (already multiplied together). These matrices are what determine where your object is in 3D space and where your viewing position/direction of the world is. So you can think of your calls as moving the camera, but it's probably easier to think of them as moving and rotating the world.
These rotate and translation calls are linear transformations. This has a precise definition, but for our purposes it means that you can represent the transformation as a matrix and you multiply it with the point's coordinates to apply the transformation to a point. Now matrix multiplication is not commutative, meaning AB != BA. All this to say that when you rotate, then translate it is different than translating and rotating, which I think you know. But then when you translate, rotate, and translate again, it might be a little more difficult to follow what you're actually doing. Worse even if you throw in some scaling in there. So I would suggest learning how linear transformations work and maintaining your own matrices for the objects and camera if you're serious about learning OpenGL.
learnopengl.org is an excellent website, but it teaches you Modern OpenGL, not what you're currently using. But the lesson on transformations and on coordinate systems are probably generally helpful, even without exact code for you to follow

How to know that object has been rotated only in 15 degree chunks in 3D?

I have an 3D object in 3D space oriented in some orientation. How can I know it has been rotated from its initial rotation q (in euler angles: 0, 0, 0) only in arbitrary number of 15 degree rotations in any axis. E.g, rotated in X-axis 4*15 degrees, and in Y-axis 7*15 degrees and in Z-axis 13*15 degrees. How can I detect this?
I have tried to take euler angles from the object's rotation matrix but it seems to detect the situation correctly only if I rotate only in one axis. If I start to mix X,Y and Z axis 15 degree rotations, the euler angles gets messed up.
I am 100% sure that the object has been rotated only in 15 degree chunks.
Rotation matrices can only be decomposed into quaternions, I believe, and cannot be decomposed into per-axis rotations.
I am not sure what math library you are using, but, if provided, you could use quaternions, which will quite straightforward the functionality you want. They can be translated to rotation matrices afterwards.
Rotations are not commutative, therefore describing them with Euler angles is problematic if you don't know the right order. If you know the order, you can set up an equation system with a multiplication of three rotation matrices (parameterized by the rotation angle) on one side and the final rotation matrix on the other side. Gives you three equations and three unknowns. But watch out for singularities in Euler angle representation!
If you can, the dead simplest way is to store both the components (float3 m_Translation, m_Rotation, m_Scale) and a matrix that is updated whenever they change (float4x4 m_Matrix). To get the data out, simply grab the vector for that part and return it. The memory use is small (12-16 floats) and computational overhead is minimal (recalculate the matrix when a part is updated).
However, if that can't be done, Google suggests you can decompose rotation matrices with a bit of work like so. It does take a chunk of math.
As noted in that page, the D3DX libraries also have a function to decompose matrices: D3DXMatrixDecompose.

Find nearest rotation for cube

I have camera that look at cube from above. I can rotate cube so cube can have rotation values like z=258.18594 x=1. I need advice how to get nearest rotation with cube stand on ground and camera see top face.
Look for Quaternion mathematics and Quaternion interpolation. This will make the task rather easy.
See also Nearest Neighbours using Quaternions