[Plib-users] R: Selecting ssEntity with mouse
Brought to you by:
sjbaker
From: Paolo L. <p.l...@ci...> - 2010-07-23 10:06:33
|
Johannes, here is what I do: float z2, x3, y3, z3; if ( Project2d3d ( x, y, z2, x3, y3, z3 ) ) { sgVec3 pick_pnt = {x3, y3, z3}; ulSetError( UL_DEBUG, "picking point (%f,%f,%f)", x3, y3, z3 ); sgMat4 mview_mat; extern void get_eye_matrices( int eye, sgMat4 proj_mat, sgMat4 mview_mat ); get_eye_matrices( 0, NULL, mview_mat ); // my way of doing glGetDoublev(GL_MODELVIEW_MATRIX, mview_mat) ssgEntityBinding *ebind = getPickedLeaf( z2, pick_pnt, mview_mat, scene ); } x, y are mouse coord, e.g. those arguments of the mouse button press GLUT callback. Project2d3d maps 2D's x,y to 3D's x3,y3,z3, and is listed below (borrowed from a past post): // Project2d3d is the function which will transform 2d into 3d coordinates: int Project2d3d ( int x2, int y2, float& z2, 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 = viewport[3] - y2 ; /* Use GL power to find the depth of the projection */ glReadPixels ( x2, y2gl, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z2 ) ; if ( z2 >= 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 = gluUnProject ( x2, y2gl, z2, modvmatrix, projmatrix, viewport, &dx, &dy, &dz ) ; x3 = dx ; y3 = dy ; z3 = dz ; return retcode; } getPickedLeaf actually intersects a screen-inward ray with the scene graph content, and return the outmost leaf along the SSG coord system's z-axis. ssgEntityBinding *getPickedLeaf( float zmin, sgVec3 center, sgMat4 inv_cam_mat, ssgBranch *scene ) { sgVec3 test_vec, cam_center, up = {0,0,1}; sgMat4 cam_mat, _OpenGL2ssg; extern sgMat4 _ssgOpenGLAxisSwapMatrix; // defined in ssg.cxx // back to SSG coordinate system sgTransposeNegateMat4( _OpenGL2ssg, _ssgOpenGLAxisSwapMatrix ); sgPostMultMat4( inv_cam_mat, _OpenGL2ssg ); 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 ); sgTransposeNegateMat4( inv_cam_mat, cam_mat ); sgSetVec3( test_vec, 0, 1, 0 ); static ssgLeaf *leaf; // its pointer goes outside ssgHit *results, *hit; int num_hits = ssgLOS ( scene, test_vec, inv_cam_mat, &results ) ; if ( num_hits > 0 ) { ulSetError( UL_DEBUG, "hits %d", num_hits ); float min_dst; bool done = false; leaf = NULL; for ( int i = 0 ; i < num_hits ; i++ ) { ssgHit *h = &results [ i ] ; float dst = - h->plane[3] / h->plane[1]; ulSetError( UL_DEBUG, "\tdst %f, zmin %f, min_dst %f", dst, zmin, min_dst ); if ( dst > 0 && (!done || dst < min_dst) ) { done = true; min_dst = dst; leaf = h->leaf; hit = h; ulSetError( UL_DEBUG, "\t\thit %d, leaf '%s', min_dst %f", hit, leaf->getName(), min_dst ); } } // normally at this point one could return the ssgLeaf * 'leaf', yet I need the path-to-node string so I fill & return a ssgEntityBinding if ( leaf != NULL ) { static ssgEntityBinding ebind; static char path_string[1023], *name; strcpy( path_string, "" ); hit->addPath( leaf ); // doesn't include the hit leaf itself, but we need it for ( int i = 0; i < hit->getNumPathEntries(); i++ ) { strcat( path_string, "/" ); strcat( path_string, (name=hit->getPathEntry(i)->getName()) ? name : "" ); } ebind.entity = (ssgEntity**)&leaf; ebind.nameOrPath = ulStrDup( path_string ); return &ebind; } } return NULL; } I hope the code would get compiled with little effort and finally will work. Greetings, Paolo Leoncini _____ Da: Johannes Strömberg [mailto:joh...@gm...] Inviato: venerdì 23 luglio 2010 10.34 A: pli...@li... Oggetto: [Plib-users] Selecting ssEntity with mouse Hello, I need a way of selecting an object on screen using the mouse. How do I convert mouse input to something that I can use with my scene and how do I find what is under the mouse? /Johannes |