[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
|