/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/EnginePlugins/ParticlePlugin/Emitter/ParticleEmitter_Distance.cpp
145 строк
5 KB
Jan Krassnigg
Added Expression Particle Behavior (#1884)
29 мар 2026, 23:32
Не верифицирован
29 мар 2026, 23:32
071fa9d
Код
Авторство
О чём код?
#include <ParticlePlugin/ParticlePluginPCH.h> #include <Foundation/DataProcessing/Stream/ProcessingStreamGroup.h> #include <Foundation/Math/Random.h> #include <ParticlePlugin/Effect/ParticleEffectInstance.h> #include <ParticlePlugin/Emitter/ParticleEmitter_Distance.h> #include <ParticlePlugin/System/ParticleSystemInstance.h> // clang-format off EZ_BEGIN_DYNAMIC_REFLECTED_TYPE(ezParticleEmitterFactory_Distance, 1, ezRTTIDefaultAllocator<ezParticleEmitterFactory_Distance>) { EZ_BEGIN_PROPERTIES { EZ_MEMBER_PROPERTY("DistanceThreshold", m_fDistanceThreshold)->AddAttributes(new ezDefaultValueAttribute(0.1f), new ezClampValueAttribute(0.01f, 100.0f)), EZ_MEMBER_PROPERTY("MinSpawnCount", m_uiSpawnCountMin)->AddAttributes(new ezDefaultValueAttribute(1)), EZ_MEMBER_PROPERTY("SpawnCountRange", m_uiSpawnCountRange), EZ_MEMBER_PROPERTY("SpawnCountScaleParam", m_sSpawnCountScaleParameter), } EZ_END_PROPERTIES; } EZ_END_DYNAMIC_REFLECTED_TYPE; EZ_BEGIN_DYNAMIC_REFLECTED_TYPE(ezParticleEmitter_Distance, 1, ezRTTIDefaultAllocator<ezParticleEmitter_Distance>) EZ_END_DYNAMIC_REFLECTED_TYPE; // clang-format on ezParticleEmitterFactory_Distance::ezParticleEmitterFactory_Distance() = default; const ezRTTI* ezParticleEmitterFactory_Distance::GetEmitterType() const { return ezGetStaticRTTI<ezParticleEmitter_Distance>(); } void ezParticleEmitterFactory_Distance::CopyEmitterProperties(ezParticleEmitter* pEmitter0, bool bFirstTime) const { ezParticleEmitter_Distance* pEmitter = static_cast<ezParticleEmitter_Distance*>(pEmitter0); pEmitter->m_fDistanceThresholdSQR = ezMath::Square(m_fDistanceThreshold); pEmitter->m_uiSpawnCountMin = (ezUInt32)(m_uiSpawnCountMin * pEmitter->GetOwnerSystem()->GetSpawnCountMultiplier()); pEmitter->m_uiSpawnCountRange = (ezUInt32)(m_uiSpawnCountRange * pEmitter->GetOwnerSystem()->GetSpawnCountMultiplier()); pEmitter->m_sSpawnCountScaleParameter = ezTempHashedString(m_sSpawnCountScaleParameter.GetData()); } void ezParticleEmitterFactory_Distance::QueryMaxParticleCount(ezUInt32& out_uiMaxParticlesAbs, ezUInt32& out_uiMaxParticlesPerSecond) const { out_uiMaxParticlesAbs = 0; out_uiMaxParticlesPerSecond = (m_uiSpawnCountMin + m_uiSpawnCountRange) * 10; // assume that this won't fire more than 10 times per second // TODO: consider to scale by m_sSpawnCountScaleParameter } enum class EmitterDistanceVersion { Version_1 = 1, // insert new version numbers above Version_Count, Version_Current = Version_Count - 1 }; void ezParticleEmitterFactory_Distance::Save(ezStreamWriter& inout_stream) const { const ezUInt8 uiVersion = (int)EmitterDistanceVersion::Version_Current; inout_stream << uiVersion; // Version 1 inout_stream << m_fDistanceThreshold; inout_stream << m_uiSpawnCountMin; inout_stream << m_uiSpawnCountRange; inout_stream << m_sSpawnCountScaleParameter; } void ezParticleEmitterFactory_Distance::Load(ezStreamReader& inout_stream, const ezParticleEffectDescriptor& ownerEffectDescriptor, const ezParticleSystemDescriptor& ownerSystemDescriptor) { ezUInt8 uiVersion = 0; inout_stream >> uiVersion; EZ_ASSERT_DEV(uiVersion <= (int)EmitterDistanceVersion::Version_Current, "Invalid version {0}", uiVersion); inout_stream >> m_fDistanceThreshold; inout_stream >> m_uiSpawnCountMin; inout_stream >> m_uiSpawnCountRange; inout_stream >> m_sSpawnCountScaleParameter; } void ezParticleEmitter_Distance::CreateRequiredStreams() {} void ezParticleEmitter_Distance::InitializeElements(ezUInt64 uiStartIndex, ezUInt64 uiNumElements) {} bool ezParticleEmitter_Distance::IsContinuous() const { return true; } void ezParticleEmitter_Distance::OnFinalize() { // do not use the System transform, because then this would not work with local space simulation m_vLastSpawnPosition = GetOwnerEffect()->GetTransform().m_vPosition; m_bFirstUpdate = true; if (GetOwnerEffect()->IsSharedEffect()) { ezLog::Warning("Particle emitters of type 'Distance' do not work for shared particle effect instances."); } } ezParticleEmitterState ezParticleEmitter_Distance::IsFinished() { return ezParticleEmitterState::Active; } ezUInt32 ezParticleEmitter_Distance::ComputeSpawnCount(const ezTime& tDiff) { const ezVec3 vCurPos = GetOwnerEffect()->GetTransform().m_vPosition; if ((m_vLastSpawnPosition - vCurPos).GetLengthSquared() < m_fDistanceThresholdSQR) return 0; m_vLastSpawnPosition = vCurPos; if (m_bFirstUpdate) { m_bFirstUpdate = false; return 0; } float fSpawnFactor = 1.0f; const float spawnCountScale = ezMath::Max(GetOwnerEffect()->GetFloatParameter(m_sSpawnCountScaleParameter, 1.0f), 0.0f); fSpawnFactor *= spawnCountScale; ezUInt32 uiSpawn = m_uiSpawnCountMin; if (m_uiSpawnCountRange > 0) uiSpawn += GetRNG().UIntInRange(m_uiSpawnCountRange); uiSpawn = static_cast<ezUInt32>((float)uiSpawn * fSpawnFactor); return uiSpawn; } EZ_STATICLINK_FILE(ParticlePlugin, ParticlePlugin_Emitter_ParticleEmitter_Distance);