diff --git a/examples/osgparticleshader/osgparticleshader.cpp b/examples/osgparticleshader/osgparticleshader.cpp index 401da35e2..076fde592 100644 --- a/examples/osgparticleshader/osgparticleshader.cpp +++ b/examples/osgparticleshader/osgparticleshader.cpp @@ -166,12 +166,19 @@ int main( int argc, char** argv ) // The updater can receive particle systems as child drawables now. The addParticleSystem() method // is still usable, with which we should define another geode to contain a particle system. osg::ref_ptr updater = new osgParticle::ParticleSystemUpdater; - updater->addDrawable( ps.get() ); + //updater->addDrawable( ps.get() ); osg::ref_ptr root = new osg::Group; root->addChild( parent.get() ); root->addChild( updater.get() ); + // FIXME 2010.9.19: the updater can't be a drawable; otehrwise the ParticleEffect will not work properly. why? + updater->addParticleSystem( ps.get() ); + + osg::ref_ptr geode = new osg::Geode; + geode->addDrawable( ps.get() ); + root->addChild( geode.get() ); + /*** Start the viewer ***/ @@ -190,4 +197,8 @@ int main( int argc, char** argv ) // Now we make use of the getDeltaTime() of ParticleSystem to maintain and dispatch the delta time. But.. // it is not the best solution so far, since there are still very few particles acting unexpectedly. return viewer.run(); + + // FIXME 2010.9.19: At present, getDeltaTime() is not used and the implementations in the updater and processors still + // use a (t - _t0) as the delta time, which is of course causing floating errors. ParticleEffect will not work if we + // replace the delta time with getDeltaTime()... Need to find a solution. } diff --git a/include/osgParticle/ParticleProcessor b/include/osgParticle/ParticleProcessor index d5d804640..cd6e8e923 100644 --- a/include/osgParticle/ParticleProcessor +++ b/include/osgParticle/ParticleProcessor @@ -151,6 +151,7 @@ namespace osgParticle private: ReferenceFrame _rf; bool _enabled; + double _t0; osg::ref_ptr _ps; bool _first_ltw_compute; bool _need_ltw_matrix; diff --git a/include/osgParticle/ParticleSystemUpdater b/include/osgParticle/ParticleSystemUpdater index bf8292941..ef9fa71f4 100644 --- a/include/osgParticle/ParticleSystemUpdater +++ b/include/osgParticle/ParticleSystemUpdater @@ -36,19 +36,13 @@ namespace osgParticle update() method on the specified particle systems. You should place this updater AFTER other nodes like emitters and programs. */ - class OSGPARTICLE_EXPORT ParticleSystemUpdater: public osg::Geode { + class OSGPARTICLE_EXPORT ParticleSystemUpdater: public osg::Node { public: ParticleSystemUpdater(); ParticleSystemUpdater(const ParticleSystemUpdater& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); META_Node(osgParticle,ParticleSystemUpdater); - /// Add a Drawable and call addParticleSystem() if it is a particle system - virtual bool addDrawable(osg::Drawable* drawable); - - /// Remove a Drawable and call removeParticleSystem() if it is a particle system - virtual bool removeDrawable(osg::Drawable* drawable); - /// Add a particle system to the list. virtual bool addParticleSystem(ParticleSystem* ps); @@ -87,11 +81,11 @@ namespace osgParticle virtual ~ParticleSystemUpdater() {} ParticleSystemUpdater &operator=(const ParticleSystemUpdater &) { return *this; } - private: typedef std::vector > ParticleSystem_Vector; ParticleSystem_Vector _psv; + double _t0; //added 1/17/06- bgandere@nps.edu //a var to keep from doing multiple updates per frame diff --git a/src/osgParticle/ParticleProcessor.cpp b/src/osgParticle/ParticleProcessor.cpp index 96cb1d37c..b32a348b3 100644 --- a/src/osgParticle/ParticleProcessor.cpp +++ b/src/osgParticle/ParticleProcessor.cpp @@ -15,6 +15,7 @@ osgParticle::ParticleProcessor::ParticleProcessor() : osg::Node(), _rf(RELATIVE_RF), _enabled(true), + _t0(-1), _ps(0), _first_ltw_compute(true), _need_ltw_matrix(false), @@ -35,6 +36,7 @@ osgParticle::ParticleProcessor::ParticleProcessor(const ParticleProcessor& copy, : osg::Node(copy, copyop), _rf(copy._rf), _enabled(copy._enabled), + _t0(copy._t0), _ps(static_cast(copyop(copy._ps.get()))), _first_ltw_compute(copy._first_ltw_compute), _need_ltw_matrix(copy._need_ltw_matrix), @@ -77,38 +79,45 @@ void osgParticle::ParticleProcessor::traverse(osg::NodeVisitor& nv) if ((_currentTime >= _resetTime) && (_resetTime > 0)) { _currentTime = 0; + _t0 = -1; } - - // check whether the processor is alive - bool alive = false; - if (_currentTime >= _startTime) + + // skip if we haven't initialized _t0 yet + if (_t0 != -1) { - if (_endless || (_currentTime < (_startTime + _lifeTime))) - alive = true; - } - - // update current time - _currentTime += _ps->getDeltaTime(t); - - // process only if the particle system is not frozen/culled - if (alive && - _enabled && - !_ps->isFrozen() && - (_ps->getLastFrameNumber() >= (nv.getFrameStamp()->getFrameNumber() - 1) || !_ps->getFreezeOnCull())) - { - // initialize matrix flags - _need_ltw_matrix = true; - _need_wtl_matrix = true; - _current_nodevisitor = &nv; - - // do some process (unimplemented in this base class) - process( _ps->getDeltaTime(t) ); - } else { - //The values of _previous_wtl_matrix and _previous_ltw_matrix will be invalid - //since processing was skipped for this frame - _first_ltw_compute = true; - _first_wtl_compute = true; + + // check whether the processor is alive + bool alive = false; + if (_currentTime >= _startTime) + { + if (_endless || (_currentTime < (_startTime + _lifeTime))) + alive = true; + } + + // update current time + _currentTime += t - _t0; + + // process only if the particle system is not frozen/culled + if (alive && + _enabled && + !_ps->isFrozen() && + (_ps->getLastFrameNumber() >= (nv.getFrameStamp()->getFrameNumber() - 1) || !_ps->getFreezeOnCull())) + { + // initialize matrix flags + _need_ltw_matrix = true; + _need_wtl_matrix = true; + _current_nodevisitor = &nv; + + // do some process (unimplemented in this base class) + process( t - _t0 ); + } else { + //The values of _previous_wtl_matrix and _previous_ltw_matrix will be invalid + //since processing was skipped for this frame + _first_ltw_compute = true; + _first_wtl_compute = true; + } } + _t0 = t; } //added- 1/17/06- bgandere@nps.edu diff --git a/src/osgParticle/ParticleSystemUpdater.cpp b/src/osgParticle/ParticleSystemUpdater.cpp index 180ca2080..a888a607b 100644 --- a/src/osgParticle/ParticleSystemUpdater.cpp +++ b/src/osgParticle/ParticleSystemUpdater.cpp @@ -6,13 +6,13 @@ using namespace osg; osgParticle::ParticleSystemUpdater::ParticleSystemUpdater() -: osg::Geode(), _frameNumber(0) +: osg::Node(), _t0(-1), _frameNumber(0) { setCullingActive(false); } osgParticle::ParticleSystemUpdater::ParticleSystemUpdater(const ParticleSystemUpdater& copy, const osg::CopyOp& copyop) -: osg::Geode(copy, copyop), _frameNumber(0) +: osg::Node(copy, copyop), _t0(copy._t0), _frameNumber(0) { ParticleSystem_Vector::const_iterator i; for (i=copy._psv.begin(); i!=copy._psv.end(); ++i) { @@ -27,24 +27,27 @@ void osgParticle::ParticleSystemUpdater::traverse(osg::NodeVisitor& nv) { if (nv.getFrameStamp()) { - if( _frameNumber < nv.getFrameStamp()->getFrameNumber()) { _frameNumber = nv.getFrameStamp()->getFrameNumber(); - + double t = nv.getFrameStamp()->getSimulationTime(); - ParticleSystem_Vector::iterator i; - for (i=_psv.begin(); i!=_psv.end(); ++i) + if (_t0 != -1.0) { - ParticleSystem* ps = i->get(); - - ParticleSystem::ScopedWriteLock lock(*(ps->getReadWriteMutex())); - - if (!ps->isFrozen() && (ps->getLastFrameNumber() >= (nv.getFrameStamp()->getFrameNumber() - 1) || !ps->getFreezeOnCull())) + ParticleSystem_Vector::iterator i; + for (i=_psv.begin(); i!=_psv.end(); ++i) { - ps->update(ps->getDeltaTime(t), nv); + ParticleSystem* ps = i->get(); + + ParticleSystem::ScopedWriteLock lock(*(ps->getReadWriteMutex())); + + if (!ps->isFrozen() && (ps->getLastFrameNumber() >= (nv.getFrameStamp()->getFrameNumber() - 1) || !ps->getFreezeOnCull())) + { + ps->update(t - _t0, nv); + } } } + _t0 = t; } } @@ -54,32 +57,17 @@ void osgParticle::ParticleSystemUpdater::traverse(osg::NodeVisitor& nv) } } - Geode::traverse(nv); + Node::traverse(nv); } osg::BoundingSphere osgParticle::ParticleSystemUpdater::computeBound() const { - return Geode::computeBound(); -} - -bool osgParticle::ParticleSystemUpdater::addDrawable(Drawable* drawable) -{ - ParticleSystem* ps = dynamic_cast(drawable); - if (ps) addParticleSystem(ps); - return Geode::addDrawable(drawable); -} - -bool osgParticle::ParticleSystemUpdater::removeDrawable(Drawable* drawable) -{ - ParticleSystem* ps = dynamic_cast(drawable); - if (ps) removeParticleSystem(ps); - return Geode::removeDrawable(drawable); + return osg::BoundingSphere(); } bool osgParticle::ParticleSystemUpdater::addParticleSystem(ParticleSystem* ps) { - unsigned int i = getParticleSystemIndex( ps ); - if( i >= _psv.size() ) _psv.push_back(ps); + _psv.push_back(ps); return true; } diff --git a/src/osgWrappers/deprecated-dotosg/osgParticle/IO_ParticleSystemUpdater.cpp b/src/osgWrappers/deprecated-dotosg/osgParticle/IO_ParticleSystemUpdater.cpp index 9497c5051..71f7fdf35 100644 --- a/src/osgWrappers/deprecated-dotosg/osgParticle/IO_ParticleSystemUpdater.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgParticle/IO_ParticleSystemUpdater.cpp @@ -13,7 +13,7 @@ REGISTER_DOTOSGWRAPPER(PSU_Proxy) ( new osgParticle::ParticleSystemUpdater, "ParticleSystemUpdater", - "Object Node Geode ParticleSystemUpdater", + "Object Node ParticleSystemUpdater", PSU_readLocalData, PSU_writeLocalData ); diff --git a/src/osgWrappers/serializers/osgParticle/ParticleSystemUpdater.cpp b/src/osgWrappers/serializers/osgParticle/ParticleSystemUpdater.cpp index c00400339..14c42295b 100644 --- a/src/osgWrappers/serializers/osgParticle/ParticleSystemUpdater.cpp +++ b/src/osgWrappers/serializers/osgParticle/ParticleSystemUpdater.cpp @@ -35,7 +35,7 @@ static bool writeParticleSystems( osgDB::OutputStream& os, const osgParticle::Pa REGISTER_OBJECT_WRAPPER( osgParticleParticleSystemUpdater, new osgParticle::ParticleSystemUpdater, osgParticle::ParticleSystemUpdater, - "osg::Object osg::Node osg::Geode osgParticle::ParticleSystemUpdater" ) + "osg::Object osg::Node osgParticle::ParticleSystemUpdater" ) { ADD_USER_SERIALIZER( ParticleSystems ); // _psv }