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
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to