For assignment 3 you need to be able to select graphical objects with the mouse

The simple principle

- Mouse gives (x, y).
- Render pixel at (x, y ) keeping track of the polygon it comes from.
- Associate polygon with object

For the assignment let GL do it for you.

- Associate names (unsigned integers) with objects that are drawn
- Get back a hit stack, with primitives `near' where the mouse clicked
- It's up to you how you handle the hit stack.

See the notes.

Suppose you are modelling classical temples. How do you do it?

- Open up Vitruvius. You will find that all temples are assumbled from a
few basic parts, such as
- shafts, bases, capitals
- stylobates, stereobates
- architraves
- etc.

- You don't know the words, but there are drawings with dimensions.
- There are rules for making them bigger and smaller, so you think of scaling matrices.
- There are rules for putting them in different orientations, so you think of rotation matrices.
- There are rules for placing them in different locations, so you think of translation matrices.

At this point you can make a temple, but it's a lot of work. To make it easier, divide and conquer

- Column = base + shaft + capital. Reuse this as a unit.
- Entablature = architrave + frieze + cornice. Reuse this as a unit.

You get the idea. The result is

- a data structure called an acyclic directed graph, DAG, which is like a tree designed for computer graphics.

What does this look like?

Scene -> First temple -> Stylobate -> First column -> Generic column -> Base -> Shaft -> Capital -> Second column -> ... -> Entablature -> Second temple / -> First column /

Make a scene

proc scene multMatrix(P) multMatrix(V) pushMatrix( ) multMatrix(T1) temple( ) popMatrix( ) pushMatrix( ) multMatrix(T2) temple( ) popMatrix( ) etc.

Make a temple

proc temple( ) pushMatrix( ) multMatrix(SB) stylobate( ) popMatrix( ) pushMatrix( ) multMatrix(C1) column( ) popMatrix( ) pushMatrix( ) multMatrix(C2) column( ) popMatrix( ) ... pushMatrix( ) multMatrix(En) entablature( ) popMatrix( )

We don't want always to write a program, so we encapsulate the program as data.

Traverse a DAG

traverse( root ) proc traverse( node ) { if ( primitve( node ) ) { draw( node ) } else { for each child { traverse( child ) } }

Build a DAG

scene = gr.transform( ) temple1 = gr.transform( ) gr.add_child( temple1, scene ) gr.set_transform( temple1, gr.translation(...)*gr.rotation(...) gr.set_material( temple1, marble ) ... stylobate1 = gr.transform( ) floor = gr.cube( ) gr.add_child( stylobate, floor ) gr.add_child( temple1, stylobate ) gr.set_transform( stylobate, gr.scaling(...) ) column1 = gr.transform( ) gr.add_child( temple1, column1 ) gr.set_transform( column1, gr.translation(...)*gr.scaling(...) ...