// |----------------------------------------------------------------------------| // | Logic() | // |----------------------------------------------------------------------------| bool ParticleSystem::Logic() { DebugLog ("ParticleSystem: Logic() called.", DB_LOGIC, 10); // Increment the frame time. float time = TimerManager::GetRef()->GetTime() / 1000; m_accumulatedTime += time; // Set emit particle to false for now. bool emitParticle = false; // Check if it is time to emit a new particle or not. if(m_accumulatedTime > (m_particleSpawnFrequency)) { m_accumulatedTime = 0.0f; emitParticle = true; } if(m_spawnParticles && (emitParticle == true) && (m_particles.size() < (m_maxParticles - 1))) { // Emit new particles. EmitParticle(); } // Update the position of the particles. UpdateParticles(); // Release old particles. KillParticles(); return true; }
/*! * \brief Applies the controllers * * \param mapper Mapper containing layout information of each particle * \param particleCount Number of particles * \param elapsedTime Delta time between the previous frame */ void ParticleGroup::ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime) { m_processing = true; // To avoid a lock in case of exception CallOnExit onExit([this]() { m_processing = false; }); for (ParticleController* controller : m_controllers) controller->Apply(*this, mapper, 0, particleCount - 1, elapsedTime); onExit.CallAndReset(); // We only kill now the dead particles during the update if (m_dyingParticles.size() < m_particleCount) { // We kill them in reverse order, std::set sorting them via std::greater // The reason is simple, as the death of a particle means moving the last particle in the buffer, // without this solution, certain particles could avoid death for (unsigned int index : m_dyingParticles) KillParticle(index); } else KillParticles(); // Every particles are dead, this is way faster m_dyingParticles.clear(); }
void Particle::Frame(float frameTime) { // Release old particles. KillParticles(); // Emit new particles. EmitParticles(frameTime); // Update the position of the particles. UpdateParticles(frameTime); }
bool ParticleSystemClass::Frame(float frameTime, ID3D11DeviceContext* deviceContext, D3DXVECTOR3 emitterPosition, D3DXVECTOR3 camPos) { bool result; KillParticles(); EmitParticles(frameTime, emitterPosition); UpdateParticles(frameTime, camPos); result = UpdateBuffers(deviceContext); //updating dynamic vertex buffer with new position of each particle if(!result) { return false; } return true; }
bool ParticleSystemClass::Frame(float frameTime, ID3D11DeviceContext* deviceContext) { bool result; // Release old particles. KillParticles(); // Emit new particles. EmitParticles(frameTime); // Update the position of the particles. UpdateParticles(frameTime); // Update the dynamic vertex buffer with the new position of each particle. result = UpdateBuffers(deviceContext); if(!result) { return false; } return true; }
//Frame Particle System bool CParticleSystem::Frame(ID3D11DeviceContext* deviceContext, float frameTime, CCamera* mainCamera) { bool result; //Release previous Particles KillParticles(); //Emit new Particles EmitParticles(frameTime); //Update positions of Particles UpdateParticles(frameTime); //Update Buffers (Dynamic) result = UpdateBuffers(deviceContext, mainCamera); if (!result) { return false; } return true; }
/** * PreTick - handles killing dead particles, emitter death, and buffer swaps */ void FNiagaraSimulation::PreTick() { UNiagaraEmitterProperties* PinnedProps = Props.Get(); if (!PinnedProps || !bIsEnabled || TickState == NTS_Suspended || TickState == NTS_Dead || Data.GetNumInstances() == 0) { return; } check(Data.GetNumVariables() > 0); check(PinnedProps->SpawnScriptProps.Script); check(PinnedProps->UpdateScriptProps.Script); KillParticles(); //Swap all data set buffers before doing the main tick on any simulation. for (TPair<FNiagaraDataSetID, FNiagaraDataSet*> SetPair : DataSetMap) { SetPair.Value->Tick(); } }
/** * Tick the instance. * * @param DeltaTime The time slice to use * @param bSuppressSpawning If true, do not spawn during Tick */ void FParticleBeam2EmitterInstance::Tick(float DeltaTime, bool bSuppressSpawning) { SCOPE_CYCLE_COUNTER(STAT_BeamTickTime); if (Component) { UParticleLODLevel* LODLevel = SpriteTemplate->GetCurrentLODLevel(this); check(LODLevel); // TTP #33141 // Handle EmitterTime setup, looping, etc. float EmitterDelay = Tick_EmitterTimeSetup(DeltaTime, LODLevel); // Kill before the spawn... Otherwise, we can get 'flashing' KillParticles(); // If not suppressing spawning... if (!bHaltSpawning && !bSuppressSpawning && (EmitterTime >= 0.0f)) { if ((LODLevel->RequiredModule->EmitterLoops == 0) || (LoopCount < LODLevel->RequiredModule->EmitterLoops) || (SecondsSinceCreation < (EmitterDuration * LODLevel->RequiredModule->EmitterLoops))) { // For beams, we probably want to ignore the SpawnRate distribution, // and focus strictly on the BurstList... float SpawnRate = 0.0f; // Figure out spawn rate for this tick. SpawnRate = LODLevel->SpawnModule->Rate.GetValue(EmitterTime, Component); // Take Bursts into account as well... int32 Burst = 0; float BurstTime = GetCurrentBurstRateOffset(DeltaTime, Burst); SpawnRate += BurstTime; // Spawn new particles... //@todo. Fix the issue of 'blanking' beams when the count drops... // This is a temporary hack! const float InvDeltaTime = (DeltaTime > 0.0f) ? 1.0f / DeltaTime : 0.0f; if ((ActiveParticles < BeamCount) && (SpawnRate <= 0.0f)) { // Force the spawn of a single beam... SpawnRate = 1.0f * InvDeltaTime; } // Force beams if the emitter is marked "AlwaysOn" if ((ActiveParticles < BeamCount) && BeamTypeData->bAlwaysOn) { Burst = BeamCount; if (DeltaTime > KINDA_SMALL_NUMBER) { BurstTime = Burst * InvDeltaTime; SpawnRate += BurstTime; } } if (SpawnRate > 0.f) { SpawnFraction = SpawnBeamParticles(SpawnFraction, SpawnRate, DeltaTime, Burst, BurstTime); } } } // Reset particle data ResetParticleParameters(DeltaTime); // Not really necessary as beams do not LOD at the moment, but for consistency... CurrentMaterial = LODLevel->RequiredModule->Material; Tick_ModuleUpdate(DeltaTime, LODLevel); Tick_ModulePostUpdate(DeltaTime, LODLevel); // Calculate bounding box and simulate velocity. UpdateBoundingBox(DeltaTime); if (!bSuppressSpawning) { // Ensure that we flip the 'FirstEmission' flag FirstEmission = false; } // Invalidate the contents of the vertex/index buffer. IsRenderDataDirty = 1; // Bump the tick count TickCount++; // 'Reset' the emitter time so that the delay functions correctly EmitterTime += CurrentDelay; // Reset particles position offset PositionOffsetThisTick = FVector::ZeroVector; } INC_DWORD_STAT(STAT_BeamParticlesUpdateCalls); }