Hi Ulrich,
Thanks for your fast reply.
I absolutely agree with your suggestion and I modified my application. But when
I change the osg::ref_ptr<osg::Node> to an osg::Node* it has no effect. I still
have the same problem.
Thanks,
Dominic
-----Ursprüngliche Nachricht-----
Von: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Im Auftrag von Ulrich Hertlein
Gesendet: Dienstag, 20. Mai 2008 08:12
An: OpenSceneGraph Users
Betreff: Re: [osg-users] Problem with OSG Particle System
Hi Dominik,
it looks like you have a problem with reference counting:
{
osg::NodePath& fullNodePath = nv->getNodePath();
osg::ref_ptr<osg::Node>x = fullNodePath.back();
...
fullNodePath.push_back( x.get() );
}
assigns an 'osg::Node*' (from 'getNodePath') to a smart pointer.
You later get the pointer from the smart pointer and push it onto the nodepath.
When you leave the current scope the smart pointer 'x' is destroyed which
destroys the object it pointed to (since there apparently are no other users).
But you've pushed the object onto the nodelist, so that now contains a pointer
to an invalid object -> segfault.
Just replace 'osg::ref_ptr<osg::Node>' with a regular 'osg::Node*' and you
should be good.
Cheers,
/ulrich
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgSim/MultiSwitch>
#include <osgSim/DOFTransform>
#include <osgViewer/Viewer>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osg/Group>
#include <osg/Geode>
#include <osg/NodeCallback>
#include <osgParticle/Particle>
#include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleSystemUpdater>
#include <osgParticle/ModularEmitter>
#include <osgParticle/ModularProgram>
#include <osgParticle/RandomRateCounter>
#include <osgParticle/SectorPlacer>
#include <osgParticle/RadialShooter>
#include <osgParticle/AccelOperator>
#include <osgParticle/FluidFrictionOperator>
#include <osgParticle/AccelOperator>
#include <osgParticle/MultiSegmentPlacer>
#include <osgParticle/RadialShooter>
#include <osgParticle/Interpolator>
#include <osgParticle/SmokeEffect>
#include <osgParticle/FireEffect>
class orbit : public osg::NodeCallback {
public:
orbit(): _angle(0.0) {}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
osg::MatrixTransform *tx = dynamic_cast<osg::MatrixTransform *>(node);
if( tx != NULL ) {
_angle += 3.1415927/(180.0*5.0); //M_PI
tx->setMatrix( osg::Matrix::translate( 50.0, 0.0, 8.0) *
osg::Matrix::rotate( _angle, 0, 0, 1 ) );
}
traverse(node, nv);
}
private:
float _angle;
};
class psGeodeTransform : public osg::MatrixTransform
{
public:
class psGeodeTransformCallback : public osg::NodeCallback
{
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if ( psGeodeTransform* ps = dynamic_cast<psGeodeTransform*>( node ) ) {
osg::NodePath& fullNodePath = nv->getNodePath();
osg::Node* x = fullNodePath.back(); //modified
fullNodePath.pop_back();
osg::Matrix localCoordMat = osg::computeLocalToWorld( fullNodePath );
osg::Matrix inverseOfAccum = osg::Matrix::inverse( localCoordMat );
ps->setMatrix( inverseOfAccum );
fullNodePath.push_back( x ); //modified
}
traverse(node, nv);
}
};
psGeodeTransform() {setUpdateCallback( new psGeodeTransformCallback() );}
};
class findGeodeVisitor : public osg::NodeVisitor
{
public:
findGeodeVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
{
foundGeode = NULL;
}
virtual void apply(osg::Node &searchNode)
{
if ( osg::Geode* g = dynamic_cast<osg::Geode*> (&searchNode) ) {
foundGeode = g;
} else {
traverse(searchNode);
}
}
osg::Geode* getGeode() {
return foundGeode;
}
protected:
osg::Geode* foundGeode;
};
class particleSystemHelper : public osg::Group
{
public:
particleSystemHelper(osg::Group* psGroup) : osg::Group(*psGroup)
{
osg::ref_ptr<findGeodeVisitor> fg = new findGeodeVisitor();
accept(*fg.get());
osg::ref_ptr<osg::Geode> psGeode = fg->getGeode();
psGeodeXForm = new psGeodeTransform();
psGeodeXForm->addChild (psGeode.get());
replaceChild(psGeode.get(),psGeodeXForm);
}
void addEffect(osg::Group* psGroup)
{
this->addChild(psGroup);
osg::ref_ptr<findGeodeVisitor> fg = new findGeodeVisitor();
psGroup->accept(*fg.get());
osg::ref_ptr<osg::Geode> psGeode = fg->getGeode();
psGeodeXForm->addChild(psGeode.get());
psGroup->removeChild( psGroup->getChildIndex(psGeode.get()) );
}
protected:
psGeodeTransform* psGeodeXForm;
};
int main() {
putenv( "OSG_SCREEN=1" );
osg::ref_ptr<osg::Group> rootNode = new osg::Group();
osg::ref_ptr<osg::Node> terrainNode = new osg::Node();
osg::ref_ptr<osg::Node> tankNode = new osg::Node();
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::Geode> geode2 = new osg::Geode();
osgViewer::Viewer viewer;
terrainNode = osgDB::readNodeFile( "C:\\Dokumente und
Einstellungen\\I123066D\\Desktop\\OSG_NPS_Tutorials\\NPS_Data\\Models\\JoeDirt\\JoeDirt.flt"
);
if( !terrainNode ) {
return -1;
}
rootNode->addChild( terrainNode.get() );
tankNode = osgDB::readNodeFile( "C:\\Dokumente und
Einstellungen\\I123066D\\Desktop\\OSG_NPS_Tutorials\\NPS_Data\\Models\\t72-tank\\T72-tank_des.flt"
);
if( !tankNode ) {
return -1;
}
osg::ref_ptr<osgParticle::ParticleSystem> dustParticleSystem = new
osgParticle::ParticleSystem;
dustParticleSystem->setDefaultAttributes( "C:\\Dokumente und
Einstellungen\\I123066D\\Desktop\\OSG_NPS_Tutorials\\NPS_Data\\Textures\\dust2.png",
false, false );
geode->addDrawable( dustParticleSystem.get() );
osg::ref_ptr<osgParticle::ParticleSystemUpdater> dustSystemUpdater = new
osgParticle::ParticleSystemUpdater;
dustSystemUpdater->addParticleSystem( dustParticleSystem.get() );
osgParticle::Particle smokeParticle;
smokeParticle.setSizeRange( osgParticle::rangef( 2.0, 30.0 ) );
smokeParticle.setLifeTime( 20 );
smokeParticle.setMass( 0.01 );
dustParticleSystem->setDefaultParticleTemplate( smokeParticle );
osg::ref_ptr<osgParticle::ModularEmitter> emitter = new
osgParticle::ModularEmitter;
emitter->setParticleSystem( dustParticleSystem.get() );
osg::ref_ptr<osgParticle::RandomRateCounter> dustRate =
static_cast<osgParticle::RandomRateCounter*> ( emitter->getCounter() );
dustRate->setRateRange( 5, 10 );
osg::ref_ptr<osgParticle::MultiSegmentPlacer> lineSegment = new
osgParticle::MultiSegmentPlacer();
lineSegment->addVertex( 0, 0, -2 );
lineSegment->addVertex( 0, -2, -2 );
lineSegment->addVertex( 0, -16, 0 );
emitter->setPlacer( lineSegment.get() );
osg::ref_ptr<osgParticle::RadialShooter> smokeShooter = new
osgParticle::RadialShooter();
smokeShooter->setThetaRange( 0.0, 3.14159/2 );
smokeShooter->setInitialSpeedRange( 50, 100 );
emitter->setShooter( smokeShooter.get() );
osg::ref_ptr<osg::MatrixTransform> tankTransform = new osg::MatrixTransform();
tankTransform->setUpdateCallback( new orbit() );
osg::ref_ptr<osgParticle::ModularProgram> moveDustInAir = new
osgParticle::ModularProgram;
moveDustInAir->setParticleSystem( dustParticleSystem.get() );
osg::ref_ptr<osgParticle::AccelOperator> accelUp = new
osgParticle::AccelOperator;
accelUp->setToGravity( -1 );
moveDustInAir->addOperator( accelUp.get() );
osg::ref_ptr<osgParticle::FluidFrictionOperator> airFriction = new
osgParticle::FluidFrictionOperator;
airFriction->setFluidToAir();
moveDustInAir->addOperator( airFriction.get() );
osg::ref_ptr<osg::Group> effectGroup = new osg::Group();
effectGroup->addChild( geode.get() );
effectGroup->addChild( dustSystemUpdater.get() );
effectGroup->addChild( emitter.get() );
effectGroup->addChild( moveDustInAir.get() );
particleSystemHelper* psh = new particleSystemHelper( effectGroup.get() );
tankTransform->addChild( psh );
tankTransform->addChild( tankNode.get() );
rootNode->addChild( tankTransform.get() );
viewer.setSceneData( rootNode.get() );
viewer.getCamera()->setClearColor( osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) );
// add the state manipulator
viewer.addEventHandler( new
osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
// add the window size toggle handler
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
// add the stats handler
viewer.addEventHandler(new osgViewer::StatsHandler);
return viewer.run();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org