Computer Graphics Dr ChihKuo Yeh Email simpson ycggmail

  • Slides: 30
Download presentation
Computer Graphics Dr. Chih-Kuo Yeh 葉智國 Email: simpson. ycg@gmail. com

Computer Graphics Dr. Chih-Kuo Yeh 葉智國 Email: simpson. ycg@gmail. com

Hierarchical Models Hierarchical models used to represent complex objects • explicit dependency between sub-parts

Hierarchical Models Hierarchical models used to represent complex objects • explicit dependency between sub-parts of an object • object-oriented approach to implementation • e. g. Articulated objects (robot arm) Scene hierarchical uses to represent all objects in as a hierarchy • shapes/lights/viewpoints/transforms/attributes • ‘Scene Graph’ Scenes can be represented non-hierarchically • leads to difficulties in scaling to large scale complex scenes • all functions explicit in display() function • inflexible Design of graphics systems with multiple objects • hierarchical models • object-oriented design • scene graphs

Non-Hierarchical Modelling • Treat object independently • reference object by a unique symbol i.

Non-Hierarchical Modelling • Treat object independently • reference object by a unique symbol i. e. a, b, c…. Object initially defined in local object coordinates Transform each object instance from local to world coordinates: Open. GL display function: 1. display(){ 2. …. . 3. Scalef(…); 4. Rotatef(…); 5. Translatef(. . . ); 6. draw_object(); 7. …. . 8. };

Non-Hierarchical Modelling • All objects are treated independently • display() function transforms/draws each object

Non-Hierarchical Modelling • All objects are treated independently • display() function transforms/draws each object explicitly • No interrelations between objects Can represent objects by a table structure: • • • each object has a symbol each object has corresponding translation/rotation/scale each object has set of attributes colour/material properties etc. render object by calling drawing each symbol in turn with specified transformation/attributes

Symbol-Instance Table

Symbol-Instance Table

Hierarchical Models Consider a more complex model composed of several sub-objects • car =

Hierarchical Models Consider a more complex model composed of several sub-objects • car = chassis + 4 wheels Representation 1: Treat all parts independently (non-hierarchical) • apply transformation to each part independently chassis: translate, draw chassis wheel 1: rotate, translate, draw wheel 1 wheel 2: rotate, translate, draw wheel 2 …. • redundant, repeated computation of translate • no explicit representation of dependence between chassis and wheels

Representation 2: Group parts hierarchically • exploit relation between parts • exploit similarity •

Representation 2: Group parts hierarchically • exploit relation between parts • exploit similarity • i. e. wheels are identical (just translated)

Graph Structures Graph Representation • - nodes: objects + attributes? + transforms? • -

Graph Structures Graph Representation • - nodes: objects + attributes? + transforms? • - edges: dependency between objects • parent-child relation between nodes ‘Directed-Graph’ edges have a direction associated with them Tree - directed graph with no closed-loops • • i. e. cannot return to the same point in the graph - ‘root node’: no entering edges - Intermediate nodes have one parent and one or more children - ‘leaf node’: no children Parameters such as location & attributes may be stored either in nodes or edges

Hierarchical Models • We represent such models using transformations • Each transformation represents a

Hierarchical Models • We represent such models using transformations • Each transformation represents a relative change from one scaling, position and orientation to another

Example: a small solar system • A sun • Two planets • A moon

Example: a small solar system • A sun • Two planets • A moon around each planet

Example: a small solar system Every primitive is drawn as a sphere • Draw.

Example: a small solar system Every primitive is drawn as a sphere • Draw. Solid. Sphere(. . . ); The use of Push. Matrix() and Pop. Matrix() allow for • Using the present model-view matrix to place objects • preserving the model-view matrix for drawing other objects

Example: Solar system Relationships The sun stands still. Planets rotate around the sun and

Example: Solar system Relationships The sun stands still. Planets rotate around the sun and spin around their y-axis The moons • rotate around their planet • spin around their y-axis • Rotate around the sun (together with their planet)

Just one planet and one moon void draw() {. . . // set the

Just one planet and one moon void draw() {. . . // set the projection and the camera here (see labs) // draw the scene Draw. Solid. Sphere(. . . ); // sun Rotate(angle_1 p, 0, 1, 0); Translate(radius_1 p); Draw. Solid. Sphere(. . . ); // first planet Rotate(angle_1 m, 0, 1, 0); Translate(radius_1 m); Draw. Solid. Sphere(. . . ); // moon around first planet }

Adding another planet with a moon void draw() {. . . // set the

Adding another planet with a moon void draw() {. . . // set the projection and the camera here (see labs) // draw the scene Draw. Solid. Sphere(. . . ); // sun Push. Matrix(); // save the model-view matrix into the transformation stack Rotate(angle_1 p, 0, 0, 1); Translate(radius_1 p); Draw. Solid. Sphere(. . . ); // first planet Rotate(angle_1 m, 0, 0, 1); Translate(radius_1 m); Draw. Solid. Sphere(. . . ); // moon around first planet Pop. Matrix(); // restore the model-view matrix (pop from stack) Rotate(angle_2 p, 0, 0, 1); Translate(radius_2 p); Draw. Solid. Sphere(. . . ); // second planet Rotate(angle_2 m, 0, 0, 1); Translate(radius_2 m); Draw. Solid. Sphere(. . . ); // moon around second planet }

Making one planet spin around its own axis void draw() {. . . //

Making one planet spin around its own axis void draw() {. . . // set the projection and the camera here (see labs) // draw the scene Draw. Solid. Sphere(. . . ); // sun Push. Matrix(); // save the model-view matrix into the transformation stack Rotate(angle_1 p, 0, 0, 1); Translate(radius_1 p); Push. Matrix(); Rotate(angle_1 rot, 0, 1, 0); // spin! Draw. Solid. Sphere(. . . ); // first planet Pop. Matrix(); Rotate(angle_1 m, 0, 0, 1); Translate(radius_1 m); Solid. Sphere(. . . ); // moon around first planet Pop. Matrix(); // restore the model-view matrix (pop from stack). . . // draw the second planet here }

Example: Robot Arm Represented by a tree with a single chain Explicit hierarchical implementation

Example: Robot Arm Represented by a tree with a single chain Explicit hierarchical implementation (i) Base: Rotate about base R(θ 1) M 1 = R(θ 1) (ii) Upper-arm: translate & rotate M 2 = M 1 T(l 2 )R(θ 2) (iii) lower-arm: translate & rotate M 3 = M 2 T(l 3 )R(θ 3) (iv) end-effector: translate & rotate M 4 = M 3 T(l 4 )R(θ 4) Base Open. GL: display(){ draw_base() Rotatef(θ 1, 0, 0, 1); draw_upperarm(); Translatef(0, l 2 , 0); Rotatef(θ 2, 0, 0, 1); draw_lowerarm(); …… } Upper-arm Lower-arm End-effector

This example demonstrates an explicit hierarchy • hard-coded in display function • hierarchy cannot

This example demonstrates an explicit hierarchy • hard-coded in display function • hierarchy cannot be changed (inflexible) Object-oriented hierarchical tree data structure Each node ‘object’ store (1) Transformation of object M (2) Pointer to function to draw object (3) Pointers to children

Open. GL pseudo code for single chain tree display(){ draw_arm(root); /* single call to

Open. GL pseudo code for single chain tree display(){ draw_arm(root); /* single call to recursive function */ } draw_arm(node){ Transform(node. M); /* apply model transform */ node. draw(); /* draw this part */ draw_arm(node. child); /* recursive call to children */ }

Example: Torso • This figure consists of a torso and connected part, each arm

Example: 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.

Example: Torso • The display callback must traverse the tree i. e. visit every

Example: 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

Example: Torso

Example: Torso

 • First draw torso. It only has one angle associated with it that

• 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 recomputed the matrix that we apply to the torso node we can save it on the stack with a Push. Matrix(). • 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 Pop. Matrix() • We have to come back up the torso after dealing with the left arm so we must go to a Push. Matrix() immediately after the pop to keep a copy of the same model-view matrix

Simple! • Although it appears convoluting, the rule is simple – every time we

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; every time 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

Rotatef(theta[0], 0. 0, 1. 0, 0. 0); Draw. Torso(); Push. Matrix(); //save current model-view

Rotatef(theta[0], 0. 0, 1. 0, 0. 0); Draw. Torso(); Push. Matrix(); //save current model-view matrix Translatef(0. 0, TORSO_HEIGHT+0. 5*HEAD_HEIGHT, 0. 0); Rotatef(theta[1], 1. 0, 0. 0); Rotatef(theta[2], 0. 0, 1. 0, 0. 0); Translatef(0. 0, -0. 5*HEAD_HEIGHT, 0. 0); Draw. Head(); Pop. Matrix(); //we have drawn the head so go back up to torso Push. Matrix(); //but now want to draw left arm so save the torso matrix again Translatef(-(TORSO_RADIUS+UPPER_ARM_RADIUS), 0. 9*TORSO_HEIGHT, 0. 0); Rotatef(theta[3], 1. 0, 0. 0); Draw. Left_upper_arm(); Translatef(0. 0, UPPER_ARM_HEIGHT, 0. 0); Rotatef(theta[4], 1. 0, 0. 0); Draw. Left_lower_arm();

Pop. Matrix(); //left arm done, go back up to torso Push. Matrix(); //but we

Pop. Matrix(); //left arm done, go back up to torso Push. Matrix(); //but we are going to draw the right arm so save the torso matrix again Translatef(TORSO_RADIUS+UPPER_ARM_RADIUS, 0. 9*TORSO_HEIGHT, 0. 0); Rotatef(theta[5], 1. 0, 0. 0); Draw. Right_upper_arm(); Translatef(0. 0, UPPER_ARM_HEIGHT, 0. 0); Rotatef(theta[6], 1. 0, 0. 0); Draw. Right_lower_arm(); Pop. Matrix(); //back up to torso Push. Matrix(); //save it we are going to draw the left leg Translatef(-(TORSO_RADIUS+UPPER_LEG_RADIUS), 0. 1*UPPER_LEG_HEIGHT, 0. 0); Rotatef(theta[7], 1. 0, 0. 0); Draw. Left_upper_leg(); Translatef(0. 0, UPPER_LEG_HEIGHT, 0. 0); Rotatef(theta[8], 1. 0, 0. 0); Draw. Left_lower_leg();

Pop. Matrix(); //back to torso Push. Matrix(); //save it as we are going to

Pop. Matrix(); //back to torso Push. Matrix(); //save it as we are going to draw right leg Translatef(TORSO_RADIUS+UPPER_LEG_RADIUS, 0. 1*UPPER_LEG_HEIGHT, 0. 0); Rotatef(theta[9], 1. 0, 0. 0); Draw. Right_upper_leg(); Translatef(0. 0, UPPER_LEG_HEIGHT, 0. 0); Rotatef(theta[10], 1. 0, 0. 0); Right_lower_leg(); Pop. Matrix(); //pop so that the total number of pushes = total number of pops!

Example: Skeleton Represent transformation matrices between each parent and child • each matrix is

Example: Skeleton Represent transformation matrices between each parent and child • each matrix is the transformation of the object in local coordinates into the parents coordinates How do we traverse the tree to draw the figure? Any order i. e. depth-first, breadth-first 2 methods to implement traversal: (1) Stack based - use matrix stack to store required matrices (2) Recursive - store matrix within nodes of data structure

(1) Stack-based tree traversal • use matrix stack to store intermediate matrices • current

(1) Stack-based tree traversal • use matrix stack to store intermediate matrices • current Model. View matrix M determines position of figure in scene draw_figure(){ Push. Matrix(); /* torso transform */ draw_torso(); Translatef(…); /* transform of head relative to torso */ Rotatef(. . . ); draw_head(); Pop. Matrix(); /* restore torso transform */ Push. Matrix(); Translate(); /* left_arm */ Rotate(); draw_upperarm(); Translate(); Rotate(); draw_lowerarm(); Pop. Matrix(); /* restore torso transform */ Push. Matrix(); Translate(); /* right arm */ …. . . }

Can also use Push/Pop values from attribute stack i. e. color etc. • Push.

Can also use Push/Pop values from attribute stack i. e. color etc. • Push. Attrib(); • Pop. Attrib(); Limitation of stack-based approach: • explicit representation of tree in single function • relies on application programmer to push/pop matrices • hard-coded/inflexible source code must be changed for different hierarchical structure • no clear distinction between building a model and rendering it

(2) Recursive tree data-structures • each node is a recursive structure with pointers to

(2) Recursive tree data-structures • each node is a recursive structure with pointers to children • use a standard tree structure to represent hierarchy • render via tree traversal algorithm (independent of model) typedef struct treenode { Glfloat m[16]; void (*draw)(); int nchild; struct treenode *children; } treenode; void draw_tree(treenode *node){ Push. Matrix(); /* save transform*/ Mult. Matrixf(node->m); node->draw(); for (i=0; i<node->nchild; i++) …. . draw_tree(node->children[i]); Pop. Matrix(); /* restore transform */ }