PDA

View Full Version : Rotation problems



alx119
01-24-2017, 04:26 AM
Hi guys, I'm new to OpenGl and I need your help.
I try to rotate a cube around z axis, but it is rotating around a target.This is my code:


ourShader.Use();
glm::mat4 transform;
transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
transform = glm::rotate(transform, glm::radians((GLfloat)glfwGetTime() * 50.0f), glm::vec3(0.0f, 0.0f, 1.0f));
GLint transformLoc = glGetUniformLocation(ourShader.Program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));


And in the vertex shader:

uniform mat4 transform;
...
gl_Position = transform * vec4(position, 1.0f);


Can you tell me what it could be the problem ?

Thank you!

BBeck1
01-24-2017, 05:54 AM
Sure. Depending on the order of multiplication when multiplying a rotation times a given matrix you will either rotate on it's own axis or orbit the origin. With the GLM rotate function, as far as I can tell there is no way to control this because they do the math for you. So, you are stuck with their choice of orbiting. There are a couple ways to work around this though. I've been tempted to write my own math library to get around this. But the easiest way is probably to move the object to the origin so that it is centered on the origin, then do the rotation, and move it back all in a single frame before it is drawn. The viewer will never know the difference and because it is at the origin, rotation and orbiting become the same thing. At that point, all the vertices in the model orbiting the origin will rotate the object.

The way I deal with it though is to feed GLM's rotate function an identity matrix rather than one with data in it. This keeps GLM from performing the rotation and forces it to give me a rotation matrix where I can perform the rotation and choose the order of multiplication to control whether it rotates or orbits. Here's a code example:



Cube2Pivot = Cube2Pivot * glm::rotate(glm::mat4(), glm::radians<float>(1), glm::vec3(0.0f, 1.0f, 0.0f));
Cube2.WorldMatrix = Cube.WorldMatrix * Cube2Pivot * Cube2World;


glm::mat4() is an identity (empty) matrix. I probably should have used radians rather than the conversion but this returns a rotation matrix 1 degree around the Y axis. This example is a little more complex because I have 2 cubes. Cube is the main cube and its WorldMatrix controls its position and orientation. Cube2 is a cube that orbits the first cube. Cube2Pivot is a child of the main cube and is the origin of Cube2World (the second cube's world/object matrix). So, this allows the second cube to orbit the first as the first cube rotates or moves. This sort of rigid animation is the next step. For now, just worry about getting one object rotating before worrying about chaining objects in parent child relationships for rigid animation.

Just use glm::rotate(glm::mat4(), glm::radians<float>(1), glm::vec3(0.0f, 1.0f, 0.0f)) to build a rotation matrix and then multiply the object's matrix times this with the result being the object's rotated matrix. And if you want to switch whether it rotates around the origin or its own axis, just do the multiplication in the opposite order.

Hellice
01-24-2017, 08:35 AM
you are using the same matrix for translate and rotate.. the logical thing is to multiplay Rotation by the translation matrix

alx119
01-24-2017, 08:51 AM
Hi,

Thank you guys for reply.I've done it.The problem is that my cube was not situated at the origin.I've changed the vertices so the cube can be placed at the origin and it worked. :D
Thanks again!