diff --git a/code/particle/ParticleEffect.cpp b/code/particle/ParticleEffect.cpp index 2068a69eadf..36252794c59 100644 --- a/code/particle/ParticleEffect.cpp +++ b/code/particle/ParticleEffect.cpp @@ -416,13 +416,17 @@ void ParticleEffect::pageIn() { } } -std::pair ParticleEffect::getEffectDuration() const { +std::pair ParticleEffect::getEffectDuration(float interp, const ParticleSource& source, size_t effectNumber) const { std::pair timing; timing.first = _timestamp(fl2i(m_delayRange.next() * 1000.0f)); if (m_duration == Duration::ALWAYS) timing.second = TIMESTAMP::never(); - else - timing.second = timestamp_delta(timing.first, fl2i(m_durationRange.next() * 1000.0f)); + else { + const auto& [pos, hostOrientation] = source.m_host->getPositionAndOrientation(m_parent_local, interp, m_manual_offset); + auto modularCurvesInput = std::forward_as_tuple(source, effectNumber, pos); + + timing.second = timestamp_delta(timing.first, fl2i(m_durationRange.next() * 1000.0f * m_modular_curves.get_output(ParticleCurvesOutput::SOURCE_DURATION_MULT, modularCurvesInput))); + } return timing; } diff --git a/code/particle/ParticleEffect.h b/code/particle/ParticleEffect.h index fdc277715e0..0824139850e 100644 --- a/code/particle/ParticleEffect.h +++ b/code/particle/ParticleEffect.h @@ -75,6 +75,7 @@ class ParticleEffect { RADIUS_MULT, LENGTH_MULT, LIFETIME_MULT, + SOURCE_DURATION_MULT, VOLUME_VELOCITY_MULT, INHERIT_VELOCITY_MULT, POSITION_INHERIT_VELOCITY_MULT, @@ -236,7 +237,7 @@ class ParticleEffect { const SCP_string& getName() const { return m_name; } - std::pair getEffectDuration() const; + std::pair getEffectDuration(float interp, const ParticleSource& source, size_t effectNumber) const; float getNextSpawnDelay() const; @@ -251,6 +252,7 @@ class ParticleEffect { std::pair {"Radius Mult", ParticleCurvesOutput::RADIUS_MULT}, std::pair {"Length Mult", ParticleCurvesOutput::LENGTH_MULT}, std::pair {"Lifetime Mult", ParticleCurvesOutput::LIFETIME_MULT}, + std::pair {"Source Duration Mult", ParticleCurvesOutput::SOURCE_DURATION_MULT}, std::pair {"Velocity Volume Mult", ParticleCurvesOutput::VOLUME_VELOCITY_MULT}, std::pair {"Velocity Inherit Mult", ParticleCurvesOutput::INHERIT_VELOCITY_MULT}, std::pair {"Velocity Position Inherit Mult", ParticleCurvesOutput::POSITION_INHERIT_VELOCITY_MULT}, @@ -299,6 +301,7 @@ class ParticleEffect { std::pair {"Host Ship Time Until Explosion", modular_curves_submember_input<&ParticleSource::m_host, &EffectHost::getParentObjAndSig, 0, &Objects, &obj_get_instance_maybe, &ship::final_death_time, static_cast(×tamp_until)>{}}) .derive_modular_curves_input_only_subset( //Effect Number std::pair {"Spawntime Left", modular_curves_functional_full_input<&ParticleSource::getEffectRemainingTime>{}}, + std::pair {"Life Left", modular_curves_functional_full_input<&ParticleSource::getEffectRemainingLife>{}}, std::pair {"Time Running", modular_curves_functional_full_input<&ParticleSource::getEffectRunningTime>{}}) .derive_modular_curves_input_only_subset( //Sampled spawn position std::pair {"Pixel Size At Emitter", modular_curves_functional_full_input<&ParticleSource::getEffectPixelSize>{}}, diff --git a/code/particle/ParticleSource.cpp b/code/particle/ParticleSource.cpp index cf94e233701..0dd4c73e603 100644 --- a/code/particle/ParticleSource.cpp +++ b/code/particle/ParticleSource.cpp @@ -34,8 +34,10 @@ void ParticleSource::finishCreation() { m_host->setupProcessing(); - for (const auto& effect : ParticleManager::get()->getEffect(m_effect)) { - const auto& [begin, end] = effect.getEffectDuration(); + const auto& effectList = ParticleManager::get()->getEffect(m_effect); + for (size_t i = 0; i < effectList.size(); i++) { + const auto& effect = effectList[i]; + const auto& [begin, end] = effect.getEffectDuration(0.0, *this, i); m_timing.emplace_back(SourceTiming{timestamp_delta(begin, 0), begin, end}); } } @@ -111,6 +113,11 @@ float ParticleSource::getEffectRunningTime(const std::tuple& source) { + const auto& timing = std::get<0>(source).m_timing[std::get<1>(source)]; + return i2fl(timestamp_get_delta(timing.m_nextCreation, timing.m_endTimestamp)) / i2fl(timestamp_get_delta(timing.m_startTimestamp, timing.m_endTimestamp)) ; +} + float ParticleSource::getEffectPixelSize(const std::tuple& source) { return std::get<0>(source).getEffect()[std::get<1>(source)].getApproximatePixelSize(std::get<2>(source)); } diff --git a/code/particle/ParticleSource.h b/code/particle/ParticleSource.h index df5c2c2c7f8..c4cd709d1ad 100644 --- a/code/particle/ParticleSource.h +++ b/code/particle/ParticleSource.h @@ -75,6 +75,8 @@ class ParticleSource { static float getEffectRunningTime(const std::tuple& source); + static float getEffectRemainingLife(const std::tuple& source); + static float getEffectPixelSize(const std::tuple& source); static float getEffectApparentSize(const std::tuple& source);