Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I was recently writing a simple 3D maze FPP game. Once I was done fiddling with planes in OpenGL, I wanted to add support for importing Blender objects. The approach I used was triangulization of the object, then using Three.js to export the points to plaintext and then parsing the result JSON in my app.

The example file can be seen here: https://github.com/d33tah/tinyfpp/blob/master/Data/Models/cross.txt The numbers represent x,y,z,u,v of a single vertex, which combined in three make a triangle.

Then I rendered such an object triangle-by-triangle and played with it. I could move it back and forth and sideways, but I still have no idea how to rotate it by some axis. Let's say I'd like to rotate all the points by five degrees to the left, how would a code doing it look like?

share|improve this question
    
Look up polar coordinates. –  jco Nov 13 '12 at 18:29
    
@Bane OpenGL has functions to rotate the object as shown in Apahidean's answer. No need to make it more complicated than it is :) –  Maik Semder Nov 13 '12 at 18:57
    
Yeah, I know, but I guess it's always cool to know the math behind it (if that's the case). –  jco Nov 13 '12 at 20:08
add comment

2 Answers 2

up vote 2 down vote accepted

I think the easiest way to rotate a vertex around an axis is using the Rodrigues Rotation Formula.

Here is my implementation of it using C++ and the library GLM:

(Note: it may not be the most efficient way, but I use it for learning purpose :3. Also, I'm using row major order (not the way GLM do things), so the multiplication is inverse later. Also, rotation are counter-clockwise :3)

glm::mat3 rodriguesMatrix(const double degrees, const glm::vec3& axis) {
glm::mat3 v = glm::mat3(
    axis.x*axis.x, axis.x*axis.y, axis.x*axis.z,
    axis.x*axis.y, axis.y*axis.y, axis.y*axis.z,
    axis.x*axis.z, axis.y*axis.z, axis.z*axis.z
    );

glm::mat3 v2 = glm::mat3(
    0, -axis.z, axis.y,
    axis.z, 0, -axis.x,
    -axis.y, axis.x, 0
    );

glm::mat3 rotation = cos(degrees * M_PI/180.f) * glm::mat3(1.0f) + (1-cos(degrees * M_PI/180.f)) * v + sin(degrees * M_PI/180.f) * v2;

return rotation;
}

So, let's say you want to rotate the vertice (3.866185 -0.996761 -1.366355)(first of your example) by 5 degress along the y axis. You can do it by doing something like:

glm::vec3 y_unit = glm::vec3(0, 1.f, 0);

glm::mat3 rotationMatrix = rodriguesMatrix(5, y_unit);

glm::vec3 myVertice = glm::vec3(3.866185,-0.996761,-1.366355);

glm::vec3 myVerticeRotated = myVertice*rotationMatrix;
share|improve this answer
    
Thanks! I'll accept the answer once I implement it. –  d33tah Nov 13 '12 at 14:58
    
-1 It's a very bad advice to use glm in in row major form instead of OpenGL's native column major form. Especially if the asker seems to be not fluent with it, it will make it much harder for him. Just use the plain glm matrix rotation functions, then you can also use them for OpenGL as they are. –  Maik Semder Nov 13 '12 at 18:25
    
The Row Major form is how this formula is present in the literature, and I found it easier to learn this way. Also, I did not post plain calls to rotations, but instead an actual implementation so the OP can implement it in others languages without GLM if he decides to use modern OpenGL. –  AranHase Nov 13 '12 at 19:25
    
IT WORKED! Thanks a lot, mate! :) Now, the question is... I implemented it, how do I change the center point? Here's the code in my version: github.com/d33tah/tinyfpp/compare/… –  d33tah Nov 13 '12 at 23:14
    
@d33tah What this algorithm is doing is rotating each of your vertices around one vector (in your code, it is the y axis, declared by the y_unit variable). To change the center of the rotation, you have to translate your vertices to a new position, apply rotation, then translate back by the same distance. I highly recommend watching those videos, they are very, very, very good :) –  AranHase Nov 13 '12 at 23:41
show 2 more comments
glPushMatrix();

// Translate our object in  (x,y,z) position
glTranslatef(x, y, z); 

// Rotates the object around a rotation axis
// i.e. glRotatef(45.0, 0.0, 1.0, 0.0) rotates 45 degrees around the y-axis
glRotatef(angle, rot_axis_x, rot_axis_y, rot_axis_z);  

// Create a function for drawing the object
Draw();   

glPopMatrix();

You need to draw you're object preferably in the origin, because every rotation that you apply will be done around a position vector (vector that starts from the origin), and than you can translate it. OpenGl will first rotate your object and then it will translate it, so it will call the functions in reverse order. If you change the order, you will first translate the object and then rotate it around the position vector.

share|improve this answer
    
Not really what I asked for. –  d33tah Nov 13 '12 at 16:08
1  
@d33tah actually that is the correct answer and exactly what you asked for. This is the OpenGL way of doing what you were asking. +1 –  Maik Semder Nov 13 '12 at 18:27
    
@Apahidean Iancu you might want to look at the format options for answers, it makes your answer much more readable. I edited your answer :) –  Maik Semder Nov 13 '12 at 18:32
    
Well, if I wanted to render a rotated object, that would be perfect. The point is, I wanted to rotate a set of points and it was AranHase that helped me out here. Thanks for sharing anyway ^^ –  d33tah Nov 13 '12 at 23:40
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.