Hi,
 
I have a problem with the OpenSceneGraph particle system.
 
I read tutorial 17 from the NPS Tutorials by Jason Sullivan (
http://faculty.nps.edu/jasullivan/osgTutorials/osgParticle.htm) and the
new summary about loading particle systems from a file (
http://faculty.nps.edu/jasullivan/osgTutorials/osgParticleHelper.htm).
 
My application looks almost like the tutorial, I only modified it at two
positions wich I have marked with "//modified". I attached the complete
source code to this mail.
Now if I start the application it works fine for a few seconds. But
after that, the particles are starting flying wild around a circle and
the application crashes.
Is there still a problem with the transformation?
 
Thanks,
 
Dominic Neusch
 
____________________________________________
Dominic Neusch
Diplomand
EADS
Defence & Security
System Design Center Germany - SDGE1
88039 Friedrichshafen - Deutschland
Telephone: +49 (0) 7545 8-2686
Fax: +49 (0) 7545 8-9630
Email: mailto:[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>  
www.eads.com <http://www.eads.com> 
EADS Deutschland GmbH
Registered Office: Ottobrunn
District Court of Munich HRB 107 648
Chairman of the Supervisory Board: Dr. Thomas Enders
Managing Directors: Dr. Stefan Zoller (chairman), Michael Hecht
This E-mail and any attachment(s) to it are for the addressee's use
only.
It is strictly confidential and may contain legally privileged
information. No confidentiality or privilege is waived or lost by any
mistransmission.
If you are not the intended addressee, then please delete it from your
system and notify the sender immediateley. You are hereby notified that
any use, 
disclosure, copying or any action taken in reliance on it is strictly
prohibited and may be unlawful. - Thank you.
Before printing this e-mail, think about our environmental
responsibility
 
#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::ref_ptr<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.get() ); //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