void PUParticleSystem3D::forceUpdate( float delta ) { if (!_emitters.empty()){ calulateRotationOffset(); prepared(); emitParticles(delta); preUpdator(delta); updator(delta); postUpdator(delta); } Vec3 currentPos = getDerivedPosition(); _latestPositionDiff = currentPos - _latestPosition; _latestPosition = currentPos; _latestOrientation = getDerivedOrientation(); _timeElapsedSinceStart += delta; }
//----------------------------------------------------------------------- void ParticleSystem::_update(Real timeElapsed) { // Only update if attached to a node if (!mParentNode) return; // Only update if the particle system is started or prepare the particle system before starting. if (mState == ParticleSystem::PSS_STARTED) { if (mNonvisibleUpdateTimeoutSet) { long frameDiff = Ogre::Root::getSingleton().getNextFrameNumber() - mLastVisibleFrame; if (frameDiff > 1 || frameDiff < 0) { mTimeSinceLastVisible += timeElapsed; if (mTimeSinceLastVisible >= mNonvisibleUpdateTimeout) { // No update return; } } } // Speedup or slowdown timeElapsed *= mParticleSystemScaleTime; // Only update the time since start if the ParticleSystem is in the 'start' state. // Stop the ParticleSystem if the fixed timeout has been reached (if applicable). mTimeElapsedSinceStart += timeElapsed; if (mFixedTimeoutSet) { if (mTimeElapsedSinceStart >= mFixedTimeout) { // Stop the ParticleSystem if (mStopFadeSet) { // Stop slowly stopFade(); mFixedTimeoutSet = false; } else { // Stop immediately stop(); return; } } } // Update bound timer (if not auto updated) if (!mBoundsAutoUpdate && mBoundsUpdateTime > 0.0f) mBoundsUpdateTime -= timeElapsed; // Calculate rotation of the node calulateRotationOffset(); // Determine whether timeElapsed or iterationInterval is used size_t particlesLeft = 0; if (mIterationIntervalSet) { // Update time since last update mTimeSinceLastUpdate += timeElapsed; while (mTimeSinceLastUpdate >= mIterationInterval) { // Update all techniques using the iteration interval value particlesLeft = _updateTechniques(mIterationInterval); mTimeSinceLastUpdate -= mIterationInterval; } } else { // Update all techniques using the time elapsed (since last frame) particlesLeft = _updateTechniques(timeElapsed); } // Handle situation when no particles are emitted anymore if (particlesLeft == 0) { if (mAtLeastOneParticleEmitted) { // Generate the event _pushSystemEvent(PU_EVT_NO_PARTICLES_LEFT); mAtLeastOneParticleEmitted = false; } // Determine whether the particle system should be stopped because of a fade out if (mStopFadeSet) { if (!mFixedTimeoutSet || (mFixedTimeoutSet && mTimeElapsedSinceStart >= mFixedTimeout)) { stop(); return; } } } else { // At least one particle was emitted, so if 'particlesLef' becomes 0, it concerns the period after the last emitted particle. mAtLeastOneParticleEmitted = true; } } else if (mState == ParticleSystem::PSS_PREPARED) { // Generate the event _pushSystemEvent(PU_EVT_SYSTEM_PREPARING); // Prepare all techniques (perform some initialisation in advance) ParticleTechniqueIterator it; ParticleTechniqueIterator itEnd = mTechniques.end(); for (it = mTechniques.begin(); it != itEnd; ++it) { (*it)->_prepare(); } // Only do it once. mState = ParticleSystem::PSS_STOPPED; // Generate the event _pushSystemEvent(PU_EVT_SYSTEM_PREPARED); } else if (mState == ParticleSystem::PSS_PAUSED) { // Determine whether there is a limit to the pause if (mPauseTimeSet) { mPauseTimeElapsed += timeElapsed; if (mPauseTimeElapsed > mPauseTime) { mPauseTimeElapsed = 0.0f; resume(); } } } // Set the latest position. This value is always needed, whether the Particle System is emitted or not. latestPosition = getDerivedPosition(); mLatestOrientation = getDerivedOrientation(); }