Title: Objectives
1CSC461 Lecture 17Modeling and Virtual TrackBall
- Objectives
- Introduce simple data structures for building
polygonal models -- Vertex lists and Edge lists - OpenGL vertex arrays
- Use transformations by an example of creating
graphical (virtual) devices using OpenGL - Lead to reusable code that will be helpful later
2Representing a Mesh
- Consider a mesh
- There are 8 nodes and 12 edges
- 5 interior polygons
- 6 interior (shared) edges
- Each vertex has a location vi (xi yi zi)
3Simple Representation
- List all polygons by their geometric locations
- Leads to OpenGL code such as
- glBegin(GL_POLYGON)
- glVertex3f(x1, y1, z1)
- glVertex3f(x6, y6, z6)
- glVertex3f(x7, y7, z7)
- glEnd()
- Inefficient and unstructured
- Consider moving a vertex to a new locations
4Inward and Outward Facing Polygons
- The order v1, v6, v7 and v6, v7, v1 are
equivalent in that the same polygon will be
rendered by OpenGL but the order v1, v7, v6 is
different - The first two describe outwardly facing polygons
- Use the right-hand rule
- counter-clockwise encirclement
- of outward-pointing normal
- OpenGL treats inward and
- outward facing polygons differently
5Geometry vs Topology
- Generally it is a good idea to look for data
structures that separate the geometry from the
topology - Geometry locations of the vertices
- Topology organization of the vertices and edges
- Example a polygon is an ordered list of vertices
with an edge connecting successive pairs of
vertices and the last to the first - Topology holds even if geometry changes
6Vertex Lists
- Put the geometry in an array
- Use pointers from the vertices into this array
- Introduce a polygon list
7Shared Edges and Edge List
- Vertex lists will draw filled polygons correctly
but if we draw the polygon by its edges, shared
edges are drawn twice - Can store mesh by edge list
- Edge List
x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 x5 y5 z5. x6
y6 z6 x7 y7 z7 x8 y8 z8
e1 e2 e3 e4 e5 e6 e7 e8 e9
v1 v6
Note polygons are not represented
8Drawing a polygon from a list of indices
Modeling a Cube
- Model a color cube for rotating cube program
- Define global arrays for vertices and colors
-
- GLfloat vertices3
- -1.0,-1.0,-1.0, 1.0,-1.0,-1.0,
- 1.0, 1.0,-1.0, -1.0, 1.0,-1.0,
- -1.0,-1.0, 1.0, 1.0,-1.0, 1.0,
- 1.0, 1.0, 1.0, -1.0, 1.0, 1.0
-
- GLfloat colors3
- 0.0,0.0,0.0, 1.0,0.0,0.0,
- 1.0,1.0,0.0, 0.0,1.0,0.0,
- 0.0,0.0,1.0, 1.0,0.0,1.0,
- 1.0,1.0,1.0, 0.0,1.0,1.0
- Draw a quadrilateral from a list of indices into
the array vertices and use color corresponding to
first index - void polygon(int a, int b, int c , int d)
- glBegin(GL_POLYGON)
- glColor3fv(colorsa)
- glVertex3fv(verticesa)
- glVertex3fv(verticesb)
- glVertex3fv(verticesc)
- glVertex3fv(verticesd)
- glEnd()
-
9Draw cube from faces
- void colorcube( )
- polygon(0,3,2,1)
- polygon(2,3,7,6)
- polygon(0,4,7,3)
- polygon(1,2,6,5)
- polygon(4,5,6,7)
- polygon(0,1,5,4)
-
- Note that vertices are ordered so that
- we obtain correct outward facing normals
- Efficiency
- The weakness of our approach is that we are
building the model in the application and must do
many function calls to draw the cube - Drawing a cube by its faces in the most straight
forward way requires - 6 glBegin, 6 glEnd
- 6 glColor
- 24 glVertex
- More if we use texture and lighting
10Vertex Arrays
- OpenGL provides a facility called vertex arrays
that allow us to store array data in the
implementation - Six types of arrays supported
- Vertices
- Colors
- Color indices
- Normals
- Texture coordinates
- Edge flags
- We will need only colors and vertices
- Initialization -- Using the same color and vertex
data, first we enable - glEnableClientState(GL_COLOR_ARRAY)
- glEnableClientState(GL_VERTEX_ARRAY)
11Using Arrays
- Identify location of arrays
- glVertexPointer(3, GL_FLOAT, 0, vertices)
- glColorPointer(3, GL_FLOAT, 0, colors)
- Map indices to faces
- Form an array of face indices
- GLubyte cubeIndices24 0,3,2,1, 2,3,7,6,
0,4,7,3, - 1,2,6,5, 4,5,6,7, 0,1,5,4
- Each successive four indices describe a face of
the cube
12Drawing the cube
- Draw through glDrawElements which replaces all
glVertex and glColor calls in the display callback
glDrawElements(GL_QUADS, 24,
GL_UNSIGNED_BYTE, cubeIndices)
Draws cube with 1 function call!!
13Example Virtual Trackball
- Physical Trackball
- The trackball is an upside down mouse
- If there is little friction between the ball and
the rollers, we can give the ball a push and it
will keep rolling yielding continuous changes
- Two possible modes of operation
- Continuous pushing or tracking hand motion and
Spinning - A Trackball from a Mouse
- Problem we want to get the two behavior modes
from a mouse - We would also like the mouse to emulate a
frictionless (ideal) trackball - Solve in two steps
- Map trackball position to mouse position
- Use GLUT to obtain the proper modes
14Trackball Frame
Projection of Trackball Position
We can relate position on trackball to position
on a normalized mouse pad by projecting
orthogonally onto pad
origin at center of ball
15Reversing Projection
- Because both the pad and the upper hemisphere of
the ball are two-dimensional surfaces, we can
reverse the projection - A point (x,z) on the mouse pad corresponds to the
point (x,y,z) on the upper hemisphere where - Computing Rotations
- Suppose that we have two points that were
obtained from the mouse. - We can project them up to the hemisphere to
points p1 and p2 - These points determine a great circle on the
sphere - We can rotate from p1 to p
- by finding the proper axis of rotation and the
angle between the points
16Obtaining the angle
- The axis of rotation is given by the normal to
the plane determined by the origin, p1 , and p2 - The angle between p1
- and p2 is given by
- If we move the mouse slowly or sample its
position frequently, then q will be small and we
can use the approximation
sin q ? q
17Implementing with GLUT
- We will use the idle, motion, and mouse callbacks
to implement the virtual trackball - Define actions in terms of three booleans
- trackingMouse if true update trackball position
- redrawContinue if true, idle function posts a
redisplay - trackballMove if true, update rotation matrix
- In this example, we use the virtual trackball to
rotate the color cube we modeled earlier - The code for the colorcube function is omitted
because it is unchanged from the earlier examples
18Initialization
- define bool int / if system does not support
- bool type /
- define false 0
- define true 1
- define M_PI 3.14159 / if not in math.h /
- int winWidth, winHeight
- float angle 0.0, axis3, trans3
- bool trackingMouse false
- bool redrawContinue false
- bool trackballMove false
- float lastPos3 0.0, 0.0, 0.0
- int curx, cury
- int startX, startY
19The Projection Step
- voidtrackball_ptov(int x, int y, int width, int
height, float v3) -
- float d, a
- / project x,y onto a hemisphere centered
within width, height , note z is up here/ - v0 (2.0x - width) / width
- v1 (height - 2.0Fy) / height
- d sqrt(v0v0 v1v1)
- v2 cos((M_PI/2.0) ((d lt 1.0) ? d
1.0)) - a 1.0 / sqrt(v0v0 v1v1
v2v2) - v0 a v1 a v2 a
20glutMotionFunc
- void mouseMotion(int x, int y)
-
- float curPos3,
- dx, dy, dz
- // compute position on
- hemisphere
- trackball_ptov(x, y, winWidth,
- winHeight, curPos)
- if (trackingMouse)
-
- / compute the change of
- position on the hemisphere /
- dx curPos0 - lastPos0
- dy curPos1 - lastPos1
- dz curPos2 - lastPos2
-
if (dx dy dz) // compute theta
and cross product angle 90.0
sqrt(dxdx dydy dzdz) axis0
lastPos1curPos2
lastPos2curPos1 axis1
lastPos2curPos0
lastPos0curPos2 axis2
lastPos0curPos1
lastPos1curPos0 / update position
/ lastPos0 curPos0 lastPos1
curPos1 lastPos2 curPos2
glutPostRedisplay()
21Idle and Display Callbacks
- void spinCube()
-
- if (redrawContinue) glutPostRedisplay()
-
- void display()
- glClear(GL_COLOR_BUFFER_BITGL_DEPTH_BUFFER_B
IT) - if (trackballMove)
-
- glRotatef(angle, axis0, axis1, axis2)
-
- colorcube()
- glutSwapBuffers()
22Mouse Callback
- void mouseButton(int button,int state,int x,int
y) -
- if(buttonGLUT_RIGHT_BUTTON) exit(0)
- / holding down left button
- allows user to rotate cube /
- if(buttonGLUT_LEFT_BUTTON) switch(state)
-
- case GLUT_DOWN
- ywinHeight-y
- startMotion( x,y)
- break
- case GLUT_UP
- stopMotion( x,y)
- break
-
23Start Function
Stop Function
- void startMotion(int x, int y)
-
- trackingMouse true
- redrawContinue false
- startX x
- startY y
- curx x
- cury y
- trackball_ptov(x, y, winWidth, winHeight,
lastPos) - trackballMovetrue
void stopMotion(int x, int y) trackingMouse
false / check if position has changed /
if(startX!x startY!y) redrawContinue
true else angle 0.0
redrawContinuefalse trackballMovefalse
24Quaternions
- Because the rotations are on the surface of a
sphere, quaternions provide an interesting and
more efficient way to implement the trackball - See code in some of the standard demos included
with Mesa