1 / 24

CSC461: Lecture 17 Modeling and Virtual TrackBall

CSC461: Lecture 17 Modeling 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

aiden
Download Presentation

CSC461: Lecture 17 Modeling and Virtual TrackBall

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

  2. e2 v5 v6 e3 e9 e8 v8 v4 e1 e11 e10 v7 e4 e7 v1 e12 v2 v3 e6 e5 Representing 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)

  3. Simple 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

  4. Inward 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

  5. Geometry 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

  6. x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4 x5 y5 z5. x6 y6 z6 x7 y7 z7 x8 y8 z8 v1 v7 v6 P1 P2 P3 P4 P5 v8 v5 v6 topology geometry Vertex Lists • Put the geometry in an array • Use pointers from the vertices into this array • Introduce a polygon list

  7. e2 v5 v6 e3 e9 e8 v8 v4 e1 e11 e10 v7 e4 e7 v1 e12 v2 v3 e6 e5 Shared 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

  8. Drawing 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 vertices[][3] = {{-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 colors[][3] = {{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(colors[a]); glVertex3fv(vertices[a]); glVertex3fv(vertices[b]); glVertex3fv(vertices[c]); glVertex3fv(vertices[d]); glEnd(); }

  9. 5 6 2 1 7 4 0 3 Draw 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

  10. Vertex 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);

  11. data array data contiguous stored as floats 3d arrays Using 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 cubeIndices[24] = { 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

  12. number of indices what to draw for(i=0; i<6; i++) glDrawElements(GL_POLYGON, 4, GL_UNSIGNED_BYTE, &cubeIndices[4*i]); format of index data start of index data Drawing the cube • Draw through glDrawElements which replaces all glVertex and glColor calls in the display callback • Method 1: • Method 2: glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices); Draws cube with 1 function call!!

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

  14. Trackball 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

  15. y = if r  |x| 0, r  |z|  0 Reversing 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

  16. n =p1  p1 | sin q| = Obtaining 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

  17. Implementing 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

  18. Initialization #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, axis[3], trans[3]; bool trackingMouse = false; bool redrawContinue = false; bool trackballMove = false; float lastPos[3] = {0.0, 0.0, 0.0}; int curx, cury; int startX, startY;

  19. The Projection Step voidtrackball_ptov(int x, int y, int width, int height, float v[3]) { float d, a; /* project x,y onto a hemisphere centered within width, height , note z is up here*/ v[0] = (2.0*x - width) / width; v[1] = (height - 2.0F*y) / height; d = sqrt(v[0]*v[0] + v[1]*v[1]); v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0)); a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] *= a; v[1] *= a; v[2] *= a; }

  20. glutMotionFunc if (dx || dy || dz) { // compute theta and cross product angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz); axis[0] = lastPos[1]*curPos[2] – lastPos[2]*curPos[1]; axis[1] = lastPos[2]*curPos[0] – lastPos[0]*curPos[2]; axis[2] = lastPos[0]*curPos[1] – lastPos[1]*curPos[0]; /* update position */ lastPos[0] = curPos[0]; lastPos[1] = curPos[1]; lastPos[2] = curPos[2]; } } glutPostRedisplay(); } void mouseMotion(int x, int y) { float curPos[3], 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 = curPos[0] - lastPos[0]; dy = curPos[1] - lastPos[1]; dz = curPos[2] - lastPos[2]; }

  21. Idle and Display Callbacks void spinCube() { if (redrawContinue) glutPostRedisplay(); } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); if (trackballMove) { glRotatef(angle, axis[0], axis[1], axis[2]); } colorcube(); glutSwapBuffers(); }

  22. Mouse Callback void mouseButton(int button,int state,int x,int y) { if(button==GLUT_RIGHT_BUTTON) exit(0); /* holding down left button allows user to rotate cube */ if(button==GLUT_LEFT_BUTTON) switch(state) { case GLUT_DOWN: y=winHeight-y; startMotion( x,y); break; case GLUT_UP: stopMotion( x,y); break; } }

  23. Start Function Stop Function void stopMotion(int x, int y) { trackingMouse = false; /* check if position has changed */ if(startX!=x || startY!=y) redrawContinue = true; else{ angle = 0.0; redrawContinue=false; trackballMove=false; } } 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); trackballMove=true; }

  24. Quaternions • 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

More Related