#include #include #include using namespace osg; osgParticle::ParticleSystemUpdater::ParticleSystemUpdater() : osg::Node(), _t0(-1), _frameNumber(0) { setCullingActive(false); } osgParticle::ParticleSystemUpdater::ParticleSystemUpdater(const ParticleSystemUpdater& copy, const osg::CopyOp& copyop) : osg::Node(copy, copyop), _t0(copy._t0), _frameNumber(0) { ParticleSystem_Vector::const_iterator i; for (i=copy._psv.begin(); i!=copy._psv.end(); ++i) { _psv.push_back(static_cast(copyop(i->get()))); } } void osgParticle::ParticleSystemUpdater::traverse(osg::NodeVisitor& nv) { osgUtil::CullVisitor* cv = nv.asCullVisitor(); if (cv) { if (nv.getFrameStamp()) { if( _frameNumber < nv.getFrameStamp()->getFrameNumber()) { _frameNumber = nv.getFrameStamp()->getFrameNumber(); double t = nv.getFrameStamp()->getSimulationTime(); if (_t0 != -1.0) { ParticleSystem_Vector::iterator i; for (i=_psv.begin(); i!=_psv.end(); ++i) { ParticleSystem* ps = i->get(); ParticleSystem::ScopedWriteLock lock(*(ps->getReadWriteMutex())); // We need to allow at least 2 frames difference, because the particle system's lastFrameNumber // is updated in the draw thread which may not have completed yet. if (!ps->isFrozen() && (!ps->getFreezeOnCull() || ((nv.getFrameStamp()->getFrameNumber()-ps->getLastFrameNumber()) <= 2)) ) { ps->update(t - _t0, nv); } } } _t0 = t; } } else { OSG_WARN << "osgParticle::ParticleSystemUpdater::traverse(NodeVisitor&) requires a valid FrameStamp to function, particles not updated.\n"; } } Node::traverse(nv); } osg::BoundingSphere osgParticle::ParticleSystemUpdater::computeBound() const { return osg::BoundingSphere(); } bool osgParticle::ParticleSystemUpdater::addParticleSystem(ParticleSystem* ps) { _psv.push_back(ps); return true; } bool osgParticle::ParticleSystemUpdater::removeParticleSystem(ParticleSystem* ps) { unsigned int i = getParticleSystemIndex( ps ); if( i >= _psv.size() ) return false; removeParticleSystem( i ); return true; } bool osgParticle::ParticleSystemUpdater::removeParticleSystem(unsigned int pos, unsigned int numParticleSystemsToRemove) { if( (pos < _psv.size()) && (numParticleSystemsToRemove > 0) ) { unsigned int endOfRemoveRange = pos + numParticleSystemsToRemove; if( endOfRemoveRange > _psv.size() ) { OSG_DEBUG<<"Warning: ParticleSystem::removeParticleSystem(i,numParticleSystemsToRemove) has been passed an excessive number"<