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

Reply via email to