I'm trying to make a simple animation where an object rotates around the world origin in OpenGL using glm lib. My ideia is:
Send object to origin
Rotate it
Send back to original position
Make it look at what I want
Here's my implementation:
// Rotates object around point p
void rotate_about(float deltaTime, glm::vec3 p, bool ended) {
glm::vec3 axis = glm::vec3(0,1,0); //rotation axis
glm::mat4 scale_m = glm::scale(glm::mat4(1.0f), glm::vec3(scale, scale, scale)); //scale matrix
glm::mat4 rotation = getMatrix(Right, Up, Front, Position); //builds rotation matrix
rotation = glm::translate(rotation, p - Position );
rotation = glm::rotate(rotation, ROTATION_SPEED * deltaTime, axis);
rotation = glm::translate(rotation, Position - p );
Matrix = rotation * scale_m;
//look at point P
Front = glm::normalize(p - start_Position);
Right = glm::normalize(glm::cross(WorldUp, Front));
Up = glm::normalize(glm::cross(Right, Front));
if (ended == true) { //if last iteration of my animation: saves position
Position.x = Matrix[3][0];
Position.y = Matrix[3][1];
Position.z = Matrix[3][2];
}
}
getMatrix() simply returns a 4x4 matrix as:
| Right.x Right.y Right.z |
| Up.x Up.y Up.z |
| Front.x Front.y Front.z |
| Pos.x Pos.y Pos.z |
I'm using this image as reference:
As it is my model simply disappears when I start the animation. If I remove lines bellow "//look at point P"
it rotates around the origin, but twitches every time my animation restarts. I'm guessing I'm losing or mixing informations I shouldn't somewhere.
How can I store my models Front/Right/Up information so I can rebuild its matrix from scratch?
First edit, this is the effect I'm having when I don't try to make my model look at the point P, in this case the origin. When I do try my model disappears. How can I make it look at where I want, and how can I get my models new Front/Right/Up vectors after I finish rotating it?
This is the code I ran in the gif above
SOLUTION:
The problem was in this part:
Note that I was using the distance between world origin and model as the radius of the translation. However, after the animation ends I update the models Position, which changes the result of
p - Position
, i.e, the orbit radius. When this happen the model "twitches", because it lost rotation information.I solved it by using a different variable for the orbit radius, and applying the translation on the
z-axis
of the model. When the translation is applied on the x-axis, the model - which faces the camera initially - will end up sideways to the origin. However, applying the translation on the z-axis will end up with the model either facing or backwards to the origin, depending on the signal.Operations like
glm::translate()
orglm::roate()
build a matrix by its parameters and multiply the input matrix by the new matrixThis means that
can be expressed as (pseudo code):
Note, that the matrix multiplication has to be "read" from the left to the right. (See GLSL Programming/Vector and Matrix Operations)
The operation
translate * rotate
causes a rotation around the origin of the object:The operation
rotate * translate
causes a rotation around the origin of the world:The matrix
glm::mat4 rotation
(in the code of your question) is the current model matrix of your object.It contains the position (translation) and the orientation of the object.
You want to rotate the object around the origin of the world.
To do so you have to create a matrix which contains the new rotation
Then you can calculate the final matrix as follows:
If you want to rotate an object around the a point
p
and the object should always face a pointp
, then all you need is the position of the object (start_position
) and the rotation axis. In your case the rotation axis is the up vector of the world.Calculate the rotation matrix and the new (rotated) position
Calculate the direction in which the object should "look"
You can use your function
getMatrix
to setup the current orientation matrix of the object:Calculate the model matrix:
The final code may look like this: