[Plib-users] R: Help for code that is not documented and is confusing
Brought to you by:
sjbaker
From: Paolo L. <p.l...@ci...> - 2007-07-25 11:41:01
|
Dimitris,=20 > -----Messaggio originale----- > Da: pli...@li...=20 > [mailto:pli...@li...] Per conto=20 > di Dimitris Mexis > Inviato: luned=EC 23 luglio 2007 23.42 > A: pli...@li... > Oggetto: [Plib-users] Help for code that is not documented=20 > and is confusing > > [...] > > OR has anyone achieved to point and click an object ? This code works for picking an SSG node in a GLUT-based app (Project2d3d = and getPickedLeaf functions reported below): glutMouseFunc( mouseclick ); ... void mouseclick( int button, int state, int x, int y ) { if ( button =3D=3D GLUT_LEFT_BUTTON && !state ) { // pick only when = the left button is pressed float x3, y3, z3; if ( Project2d3d ( x, y, x3, y3, z3 ) ) { sgVec3 pick_pnt =3D {x3, y3, z3}; // pack them into a sgVec3 for use in getPickedLeaf ulSetError( UL_DEBUG, "picking point (%f,%f,%f)", x3, y3, z3 ); ssgEntityBinding *ebind =3D getPickedLeaf( pick_pnt, scene ); if ( ebind ) { // really picked a node // picked_entity is what the name says, ssgEntity *picked_entity =3D *(ebind->entity); // ebind->entity is a ssgEntity**, so setting it as ssgEntity* is handy = and more SSG-ish // *(ebind->nameOrPath) is its path along the scene graph, useful as far as it could not be unique! // make use of them ... } } } } ssgEntityBinding *getPickedEntity( sgVec3 center, ssgBranch *scene ) // // this function gets // - a 3D 'picked' point in the scene (typically returned by the = Project2d3d function), // - a scene graph root pointer, // and returns a pointer to ssgEntityBinding, which actually holds a (entity,path) pair for the picked node. // 'path' is useful when one wants the path to walk from the root to = reach that node, and it is not unique // (remember, it's a scene *graph*, not necessarily a tree, so a node = could have in general more than one parent) // { sgVec3 test_vec, cam_center, up =3D {0,0,1}; sgMat4 inv_cam_mat, cam_mat, _OpenGL2ssg; extern sgMat4 _ssgOpenGLAxisSwapMatrix; // defined in ssg.cxx // back to SSG coordinate system sgTransposeNegateMat4( _OpenGL2ssg, _ssgOpenGLAxisSwapMatrix ); ssgGetModelviewMatrix ( inv_cam_mat ); sgPostMultMat4( inv_cam_mat, _OpenGL2ssg ); // cam_mat is finally the current SSG camera sgTransposeNegateMat4( cam_mat, inv_cam_mat ); // rotate the world so to put the 'center' point at the center of the scene sgCopyVec3( cam_center, cam_mat[3] ); sgMakeLookAtMat4( cam_mat, cam_center, center, up ); // inv_cam_mat is reused here with a different meaning - it is now the inverse of cam_mat sgTransposeNegateMat4( inv_cam_mat, cam_mat ); sgSetVec3( test_vec, 0, 1, 0 ); static ssgLeaf *leaf; // its pointer must live outside the function call ssgHit *results, *hit; int num_hits =3D ssgLOS ( scene, test_vec, inv_cam_mat, &results ) ; if ( num_hits > 0 ) { float min_dst =3D -1000000.0f ; for ( int i =3D 0 ; i < num_hits ; i++ ) { ssgHit *h =3D &results [ i ] ; float dst =3D - h->plane[3] / h->plane[1]; if ( dst > 0 && dst < fabs(min_dst) ) { min_dst =3D dst; leaf =3D h->leaf; hit =3D h; } } if ( min_dst > 0 ) { static ssgEntityBinding ebind; static char path_string[1023], *name; strcpy( path_string, "" ); // ssgHit give us the node path for free, let's export it in string form for ( int i =3D 0; i < hit->getNumPathEntries(); i++ ) { strcat( path_string, "/" ); strcat( path_string, (name=3Dhit->getPathEntry(i)->getName()) ? name : "" ); } ebind.entity =3D (ssgEntity**)&leaf; ebind.nameOrPath =3D path_string; return &ebind; } } return NULL; } // Project2d3d is the function which will transform 2d into 3d = coordinates: int Project2d3d ( int x2, int y2, float& x3, float& y3, float& z3 ) { GLint viewport[4] ; GLdouble modvmatrix[16], projmatrix[16] ; glGetIntegerv ( GL_VIEWPORT, viewport ) ; /* OpenGL y starts at lower left, X/Windows y starts at top left */ GLdouble y2gl =3D viewport[3] - y2 ; /* Update the Modelview and Projectionmatrix */ glMatrixMode ( GL_MODELVIEW ) ; ssgLoadModelviewMatrix () ; glMatrixMode ( GL_PROJECTION ) ; ssgLoadProjectionMatrix () ; /* Use GL power to find the depth of the projection */ GLfloat z2 ; glReadPixels ( x2, y2gl, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z2 ) ; if ( z2 >=3D 1 ) return 0; /* Some more GL magic. Get the projection and modelview matrices */ glGetDoublev ( GL_MODELVIEW_MATRIX, modvmatrix ) ; glGetDoublev ( GL_PROJECTION_MATRIX, projmatrix ) ; GLdouble dx, dy, dz ; /* convert screen coords to object coords. */ int retcode =3D gluUnProject ( x2, y2gl, z2, modvmatrix, projmatrix, viewport, &dx, &dy, &dz ) ; x3 =3D dx ; y3 =3D dy ; z3 =3D dz ; return retcode; } > Crying for help... > Dimitris >=20 > Thank you Don't cry. Just ask. Greetings, Paolo Leoncini |