-------- 原始消息 -------- 主题: PickHandler doesn't woks well if use an image as background 日期: Fri, 13 Dec 2013 22:52:53 +0800 发件人: Xue Junjie <[email protected]> 收件人: [email protected] Hi, I was using OSG to implementation a node transparency operation. The PickHandler works fine for me (hit the model using mouse, the node which was hit change into a transparent node). Then I want to use a sky image as my background, the code is as follow (i just used the code in OpenSceneGraph 3 cookbook). And the background works well, too. Then when i hit my model in the scene, it fail to make the node which i have hit transparent. Then i added some breakpoints to the code to tracing the code excuting process. I found in 'nodePath' , the 'geode' and 'camera' in background are picked first. And whereever i hit on the screen, the 'geode' and 'camera' will be picked. Is there any method setting up some intersection masks to the 'geode' and 'camera' to make my PickHandler work fine? Thanks for you help in advance. //using an image as background void setupBackgroundImage(osg::Group* root) { osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D; osg::ref_ptr<osg::Image> image = osgDB::readImageFile( "sky.jpg" ); texture->setImage( image.get() ); osg::ref_ptr<osg::Drawable> quad = osg::createTexturedQuadGeometry( osg::Vec3(), osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f) ); quad->getOrCreateStateSet()->setTextureAttributeAndModes( 0, texture.get() ); osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable( quad.get() ); osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setCullingActive( false ); camera->setClearMask( 0 ); camera->setAllowEventFocus( false ); camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); camera->setRenderOrder( osg::Camera::POST_RENDER ); camera->setProjectionMatrix( osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0) ); camera->addChild( geode.get() ); osg::StateSet* ss = camera->getOrCreateStateSet(); ss->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); ss->setAttributeAndModes( new osg::Depth( osg::Depth::LEQUAL, 1.0, 1.0) ); root->addChild(camera); } // PickHandler -- A GUIEventHandler that implements picking. class PickHandler : public osgGA::GUIEventHandler { public: PickHandler() : _mX( 0. ),_mY( 0. ) {} bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) { osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>( &aa ); if (!viewer) return( false ); switch( ea.getEventType() ) { case osgGA::GUIEventAdapter::PUSH: case osgGA::GUIEventAdapter::MOVE: { // Record mouse location for the button press // and move events. _mX = ea.getX(); _mY = ea.getY(); return( false ); } case osgGA::GUIEventAdapter::RELEASE: { // If the mouse hasn't moved since the last // button press or move event, perform a // pick. (Otherwise, the trackball // manipulator will handle it.) if (_mX == ea.getX() && _mY == ea.getY()) { if (pick( ea.getXnormalized(), ea.getYnormalized(), viewer )) return( true ); } return( false ); } default: return( false ); } } protected: // Store mouse xy location for button press & move events. float _mX, _mY; // Perform a pick operation. bool pick( const double x, const double y, osgViewer::Viewer* viewer ) { if (!viewer->getSceneData()) // Nothing to pick. return( false ); double w( .03 ), h( .03 ); osgUtil::PolytopeIntersector* picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, x-w, y-h, x+w, y+h ); picker->setIntersectionLimit(osgUtil::Intersector::IntersectionLimit::LIMIT_NEAREST); osgUtil::IntersectionVisitor iv( picker ); viewer->getCamera()->accept( iv ); if (picker->containsIntersections()) { const osg::NodePath& nodePath = picker->getFirstIntersection().nodePath; unsigned int idx = nodePath.size(); while (idx--) { osg::Node* node = dynamic_cast<osg::Node* >( nodePath[ idx-1 ] ); if (node == NULL) continue; if (_selectedNode.valid()) _selectedNode->setUpdateCallback( NULL ); _selectedNode = node; //Add Transparent effect // Create StateSet and Material osg::StateSet* state2 = _selectedNode->getOrCreateStateSet(); // Set alpha value //mat2->setAlpha(osg::Material::FRONT_AND_BACK, alphavalue); state2->setAttributeAndModes( mat2.get() , osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); // Turn on blending osg::BlendFunc* bf = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE_MINUS_SRC_ALPHA ); state2->setAttributeAndModes(bf); cout<<_selectedNode->getName()<<" picked successfully..."<<std::endl; break; } if (!_selectedNode.valid()) printf("Pick failed ...\n"); } else if (_selectedNode.valid()) { _selectedNode->setUpdateCallback( NULL ); _selectedNode = NULL; } return( _selectedNode.valid() ); } }; Thanks, Junjie
_______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

