/
redgpu
/
ezEngine
Обзор
Документация
Войти
/
redgpu
/
ezEngine
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
Code/EnginePlugins/ParticlePlugin/Initializer/ParticleInitializer_SpherePosition.cpp
218 строк
7 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 <Foundation/Profiling/Profiling.h> #include <Foundation/Serialization/AbstractObjectGraph.h> #include <Foundation/Serialization/GraphPatch.h> #include <ParticlePlugin/Finalizer/ParticleFinalizer_ApplyVelocity.h> #include <ParticlePlugin/Initializer/ParticleInitializer_SpherePosition.h> #include <ParticlePlugin/System/ParticleSystemInstance.h> // clang-format off EZ_BEGIN_DYNAMIC_REFLECTED_TYPE(ezParticleInitializerFactory_SpherePosition, 2, ezRTTIDefaultAllocator<ezParticleInitializerFactory_SpherePosition>) { EZ_BEGIN_PROPERTIES { EZ_MEMBER_PROPERTY("PositionOffset", m_vPositionOffset), EZ_MEMBER_PROPERTY("Radius", m_fRadius)->AddAttributes(new ezDefaultValueAttribute(0.25f), new ezClampValueAttribute(0.01f, 100.0f)), EZ_MEMBER_PROPERTY("OnSurface", m_bSpawnOnSurface), EZ_MEMBER_PROPERTY("SetVelocity", m_bSetVelocity), EZ_MEMBER_PROPERTY("Speed", m_Speed), EZ_MEMBER_PROPERTY("ScaleRadiusParam", m_sScaleRadiusParameter), } EZ_END_PROPERTIES; EZ_BEGIN_ATTRIBUTES { new ezSphereVisualizerAttribute("Radius", ezColor::MediumVioletRed, nullptr, ezVisualizerAnchor::Center, ezVec3(1.0f), "PositionOffset"), } EZ_END_ATTRIBUTES; } EZ_END_DYNAMIC_REFLECTED_TYPE; EZ_BEGIN_DYNAMIC_REFLECTED_TYPE(ezParticleInitializer_SpherePosition, 1, ezRTTIDefaultAllocator<ezParticleInitializer_SpherePosition>) EZ_END_DYNAMIC_REFLECTED_TYPE; // clang-format on ezParticleInitializerFactory_SpherePosition::ezParticleInitializerFactory_SpherePosition() { m_fRadius = 0.25f; m_vPositionOffset.SetZero(); m_bSpawnOnSurface = false; m_bSetVelocity = false; } const ezRTTI* ezParticleInitializerFactory_SpherePosition::GetInitializerType() const { return ezGetStaticRTTI<ezParticleInitializer_SpherePosition>(); } void ezParticleInitializerFactory_SpherePosition::CopyInitializerProperties(ezParticleInitializer* pInitializer0, bool bFirstTime) const { ezParticleInitializer_SpherePosition* pInitializer = static_cast<ezParticleInitializer_SpherePosition*>(pInitializer0); const float fScale = pInitializer->GetOwnerEffect()->GetFloatParameter(ezTempHashedString(m_sScaleRadiusParameter.GetData()), 1.0f); pInitializer->m_fRadius = ezMath::Max(m_fRadius * fScale, 0.01f); // prevent 0 radius pInitializer->m_bSpawnOnSurface = m_bSpawnOnSurface; pInitializer->m_bSetVelocity = m_bSetVelocity; pInitializer->m_Speed = m_Speed; pInitializer->m_vPositionOffset = m_vPositionOffset; } float ezParticleInitializerFactory_SpherePosition::GetSpawnCountMultiplier(const ezParticleEffectInstance* pEffect) const { const float fScale = pEffect->GetFloatParameter(ezTempHashedString(m_sScaleRadiusParameter.GetData()), 1.0f); if (m_fRadius != 0.0f && fScale != 1.0f) { if (m_bSpawnOnSurface) { // original surface area const float s0 = 1.0f; /*4.0f * ezMath::Pi<float>() * m_fRadius * m_fRadius; */ // new surface area const float s1 = 1.0f /*4.0f * ezMath::Pi<float>() * m_fRadius * m_fRadius */ * fScale * fScale; return s1 / s0; } else { // original volume const float v0 = 1.0f; /* 4.0f / 3.0f * ezMath::Pi<float>() * m_fRadius* m_fRadius* m_fRadius; */ // new volume const float v1 = 1.0f /* 4.0f / 3.0f * ezMath::Pi<float>() * m_fRadius * m_fRadius * m_fRadius*/ * fScale * fScale * fScale; return v1 / v0; } } return 1.0f; } void ezParticleInitializerFactory_SpherePosition::Save(ezStreamWriter& inout_stream) const { const ezUInt8 uiVersion = 3; inout_stream << uiVersion; inout_stream << m_fRadius; inout_stream << m_bSpawnOnSurface; inout_stream << m_bSetVelocity; inout_stream << m_Speed.m_Value; inout_stream << m_Speed.m_fVariance; // version 2 inout_stream << m_vPositionOffset; // version 3 inout_stream << m_sScaleRadiusParameter; } void ezParticleInitializerFactory_SpherePosition::Load(ezStreamReader& inout_stream, const ezParticleEffectDescriptor& ownerEffectDescriptor, const ezParticleSystemDescriptor& ownerSystemDescriptor) { ezUInt8 uiVersion = 0; inout_stream >> uiVersion; inout_stream >> m_fRadius; inout_stream >> m_bSpawnOnSurface; inout_stream >> m_bSetVelocity; inout_stream >> m_Speed.m_Value; inout_stream >> m_Speed.m_fVariance; if (uiVersion >= 2) { inout_stream >> m_vPositionOffset; } if (uiVersion >= 3) { inout_stream >> m_sScaleRadiusParameter; } } void ezParticleInitializerFactory_SpherePosition::QueryFinalizerDependencies(ezSet<const ezRTTI*>& inout_finalizerDeps) const { if (m_bSetVelocity) { inout_finalizerDeps.Insert(ezGetStaticRTTI<ezParticleFinalizerFactory_ApplyVelocity>()); } } ////////////////////////////////////////////////////////////////////////// void ezParticleInitializer_SpherePosition::CreateRequiredStreams() { CreateStream("Position", ezProcessingStream::DataType::Float4, &m_pStreamPosition, true); m_pStreamVelocity = nullptr; if (m_bSetVelocity) { CreateStream("Velocity", ezProcessingStream::DataType::Half4, &m_pStreamVelocity, true); } } void ezParticleInitializer_SpherePosition::InitializeElements(ezUInt64 uiStartIndex, ezUInt64 uiNumElements) { EZ_PROFILE_SCOPE("PFX: Sphere Position"); const ezVec3 startVel = GetOwnerSystem()->GetParticleStartVelocity(); const float fStartSpeed = startVel.GetLength(); const ezVec3 startDir = fStartSpeed > 0.0f ? startVel / fStartSpeed : ezVec3(0, 0, 1); ezVec4* pPosition = m_pStreamPosition->GetWritableData<ezVec4>(); ezFloat16Vec4* pVelocity = m_bSetVelocity ? m_pStreamVelocity->GetWritableData<ezFloat16Vec4>() : nullptr; ezRandom& rng = GetRNG(); const ezTransform trans = GetOwnerSystem()->GetTransform(); for (ezUInt64 i = uiStartIndex; i < uiStartIndex + uiNumElements; ++i) { ezVec3 pos = ezVec3::MakeRandomPointInSphere(rng) * m_fRadius; ezVec3 normalPos = pos; if (m_bSpawnOnSurface || m_bSetVelocity) { normalPos.Normalize(); } if (m_bSpawnOnSurface) pos = normalPos * m_fRadius; pos += m_vPositionOffset; if (m_bSetVelocity) { const float fSpeed = (float)rng.DoubleVariance(m_Speed.m_Value, m_Speed.m_fVariance); const ezVec3 vel = startVel + trans.m_qRotation * normalPos * fSpeed; const float fVelLength = vel.GetLength(); const ezVec3 velDir = fVelLength > 0.0f ? vel / fVelLength : ezVec3(0, 0, 1); pVelocity[i] = ezVec4(velDir.x, velDir.y, velDir.z, fVelLength); } pPosition[i] = (trans * pos).GetAsVec4(0); } } ////////////////////////////////////////////////////////////////////////// class ezParticleInitializerFactory_SpherePosition_1_2 : public ezGraphPatch { public: ezParticleInitializerFactory_SpherePosition_1_2() : ezGraphPatch("ezParticleInitializerFactory_SpherePosition", 2) { } virtual void Patch(ezGraphPatchContext& ref_context, ezAbstractObjectGraph* pGraph, ezAbstractObjectNode* pNode) const override { pNode->InlineProperty("Speed").IgnoreResult(); } }; ezParticleInitializerFactory_SpherePosition_1_2 g_ezParticleInitializerFactory_SpherePosition_1_2; EZ_STATICLINK_FILE(ParticlePlugin, ParticlePlugin_Initializer_ParticleInitializer_SpherePosition);