1 / 20

Transformations Tutorial

Learn about using homogeneous coordinates in OpenGL to represent 3D and 2D points, and how to apply transformations for modeling and viewing. Also explore hierarchical models and how to represent dependencies between parts using transformations.

Download Presentation

Transformations Tutorial

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Transformations Tutorial

  2. Homogeneous Coordinates • OpenGL works in 4 dimensions called Homogeneous Coordinates • A 3D point is represented as (x, y, z, 1) and a 2D point is represended as (x, y, 0, 1) (no z value!) • With this representation all the matrices we use for modeling, viewing and projection are represented by 4x4 matrices that act on homogeneous coordinates • When we set up an OpenGL transformation such as a rotation/translation we are setting up a 4x4 matrix within OpenGL

  3. Modeling with Transformations • Instancing • If we start with a collection of common objects such as spheres, cubes etc, we can build other objects by applying affine transformations to them. • Base objects are sometimes called symbols and each occurance of one is called an instance • The matrix that brings the object into the model with the desired position, size and orientation is called the instance transformation

  4. Example • glMatrixMode(GL_MODELVIEW); • glLoadIdentity(); • glTranslatef(...); • glRotatef(...); • glScalef(...); • glutSolidCylinder(...)’

  5. Hierarchical Models • In many applications, the parts of a model depend on one another • If we move one part, it causes other parts to move • Parts of such models can be arranged as a tree data structure e.g. a simple robot arm

  6. Hierarchical Models • We would like to represent such models using transformations • The instance transformations are not quite right because they place each symbol in the scene independently of the others. • However, if we recall that OpenGL transformations are applied to the EXISTING MATRIX, we can observe that each transformation represents a relative change from one scaling, position and orientation to another.

  7. Example:Robot Arm • Use a cylinder for the base, and scaled cubes for the upper and lower arms. • Through 3 functions base(), lower_arm() and upper_arm() we can define the parts. • The use of glPushMatrix() and glPopMatrix() lets us use the present model-view matrix to locate the entire figure while still preserving it for drawing other objects.

  8. Example:Robot Arm Relationships • The base can rotate independently. • The lower arm is attached to the base and can rotate relative to it. • However when the base rotates it also rotates the lower arm • The upper arm can rotate w.r.t. the lower arm but is also affected by the rotation of the lower arm and the base! • The lower arm is positioned on top of the base, so it must be translated up. The upper arme has to be translated up the height of the base and the length of the lower arm.

  9. void base() { glPushMatrix();//save where we are // draw the base /* rotate cylinder to align with y axis */ glRotatef(-90.0, 1.0, 0.0, 0.0); /* cyliner aligned with z axis, render with 5 slices for base and 5 along length */ gluCylinder(p, BASE_RADIUS, BASE_RADIUS, BASE_HEIGHT, 5, 5); glPopMatrix();//go back up to the top! } void upper_arm() { glPushMatrix(); glTranslatef(0.0, 0.5*UPPER_ARM_HEIGHT, 0.0); glScalef(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH); glutWireCube(1.0); glPopMatrix(); } void lower_arm() { glPushMatrix(); glTranslatef(0.0, 0.5*LOWER_ARM_HEIGHT, 0.0); glScalef(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH); glutWireCube(1.0); glPopMatrix(); }

  10. Program • See RobotArm.cpp for the program • Examine the code which includes a small menu which can be displayed using the middle mouse button, rotations are activated using the mouse buttons.

  11. Hierarchical Transformations • The robot example didn’t require us to save anu information about the model-view matrix as we went through the display callback, because the transformations accumulated • The tree structure for the robot arm is very simple, no node has more than one child • Lets look at a more complex example…

  12. Example 2: Torso • This figure consists of a torso and connected part, each arm and leg has two parts, but each arm and leg depend on the location & orientation of the torso, but not each other. • Lets assume we can build the individual parts head(), torso(), left_upper_arm() etc. • Each part can be located w.r.t its parent by a translation and one or more rotations.

  13. Example 2: Torso • The display callback must traverse the tree i.e. visit every node, drawing the object for that node, using the correct model-view matrix • A standard pre-order traversal (that travels down the left of the tree, visiting each node) is used

  14. Example 2: Torso

  15. First draw torso. It only has one angle associated with it that allows it to rotate about y. • Then we go to the head, however note we have to come back up to the torso to get to the arms and legs • Any matrix that we apply to draw the head is not required for the arms or legs. • Rather than recompute the matrix that we apply to the torso node we can save it on the stack with a glPushMatrix(). • We can then go to the node for the head, changing the model-view matrix as necessary to draw the head. • When we come back up to the torso node, we recover the model-view matrix with a glPopMatrix() • We have to come back up the the torso after dealing with the left arm so we must go to a glPushMatrix() immediately after the pop to keep a copy of the same model-view matrix

  16. Simple! • Although it appears convoluting, the rule is simple – every time we go to the left at a node with another unvisited right child we do a push; everytime we return to the node we do a pop. • Note we must do a pop at the end so the total number of pushes and pops is the same

  17. glLoadIdentity(); glColor3f(1.0, 0.0, 0.0); glRotatef(theta[0], 0.0, 1.0, 0.0); torso(); glPushMatrix(); //save current model-view matrix glTranslatef(0.0, TORSO_HEIGHT+0.5*HEAD_HEIGHT, 0.0); glRotatef(theta[1], 1.0, 0.0, 0.0); glRotatef(theta[2], 0.0, 1.0, 0.0); glTranslatef(0.0, -0.5*HEAD_HEIGHT, 0.0); head(); glPopMatrix(); //we have drawn the head so go back up to torso glPushMatrix(); //but now want to draw left arm so save the torso matrix again glTranslatef(-(TORSO_RADIUS+UPPER_ARM_RADIUS), 0.9*TORSO_HEIGHT, 0.0); glRotatef(theta[3], 1.0, 0.0, 0.0); left_upper_arm(); glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0); glRotatef(theta[4], 1.0, 0.0, 0.0); left_lower_arm();

  18. glPopMatrix(); //left arm done, go back up to torso glPushMatrix(); //but we are going to draw the right arm so save the torso matrix again glTranslatef(TORSO_RADIUS+UPPER_ARM_RADIUS, 0.9*TORSO_HEIGHT, 0.0); glRotatef(theta[5], 1.0, 0.0, 0.0); right_upper_arm(); glTranslatef(0.0, UPPER_ARM_HEIGHT, 0.0); glRotatef(theta[6], 1.0, 0.0, 0.0); right_lower_arm(); glPopMatrix(); //back up to torso glPushMatrix(); //save it we are going to draw the left leg glTranslatef(-(TORSO_RADIUS+UPPER_LEG_RADIUS), 0.1*UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[7], 1.0, 0.0, 0.0); left_upper_leg(); glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[8], 1.0, 0.0, 0.0); left_lower_leg();

  19. glPopMatrix(); //back to torso glPushMatrix(); //save it as we are going to draw right leg glTranslatef(TORSO_RADIUS+UPPER_LEG_RADIUS, 0.1*UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[9], 1.0, 0.0, 0.0); right_upper_leg(); glTranslatef(0.0, UPPER_LEG_HEIGHT, 0.0); glRotatef(theta[10], 1.0, 0.0, 0.0); right_lower_leg(); glPopMatrix(); //pop so that the total number of pushes = total number of pops! glFlush();

  20. See the Code • Figure.cpp

More Related