123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- //
- // ClampVelocityModule.cpp
- // cocos2d_libs
- //
- // Created by 徐俊杰 on 2020/4/24.
- //
- #include "rparticle/Modules/ClampVelocityModule.h"
- //#include "UnityPrefix.h"
- //#include "Runtime/BaseClasses/ObjectDefines.h"
- #include "rparticle/Serialize/TransferFunctions/SerializeTransfer.h"
- //#include "rparticle/Modules/ClampVelocityModule.h"
- #include "rparticle/ParticleSystemUtils.h"
- //#include "Runtime/Misc/BuildSettings.h"
- NS_RRP_BEGIN
- inline float DampenOutsideLimit (float v, float limit, float dampen)
- {
- float sgn = Sign (v);
- float abs = Abs (v);
- if (abs > limit)
- abs = Lerp(abs, limit, dampen);
- return abs * sgn;
- }
- ClampVelocityModule::ClampVelocityModule () : ParticleSystemModule(false)
- , m_SeparateAxis (false)
- , m_InWorldSpace (false)
- , m_Dampen (1.0f)
- {
- }
- template<ParticleSystemCurveEvalMode mode>
- void MagnitudeUpdateTpl(const MinMaxCurve& magnitude, const ParticleSystemReadOnlyState& roState, ParticleSystemParticles& ps, size_t fromIndex, size_t toIndex, float dampen)
- {
- for (size_t q = fromIndex; q < toIndex; ++q)
- {
- float limit = Evaluate<mode> (magnitude, NormalizedTime(ps, q), GenerateRandom(ps.randomSeed[q] + kParticleSystemClampVelocityCurveId)) * roState.GetRenderScale();
- Vector3f vel = ps.velocity[q] + ps.animatedVelocity[q];
- vel = NormalizeSafe (vel) * DampenOutsideLimit (Magnitude (vel), limit, dampen);
- ps.velocity[q] = vel - ps.animatedVelocity[q];
- }
- }
- template<ParticleSystemCurveEvalMode mode>
- void MagnitudeUpdatePerAxisTpl(const MinMaxCurve& x, const MinMaxCurve& y, const MinMaxCurve& z, const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps, size_t fromIndex, size_t toIndex, float dampen, bool worldSpace)
- {
- Matrix4x4f matrix;
- Matrix4x4f invMatrix;
- bool transform;
- // if(IS_CONTENT_NEWER_OR_SAME (kUnityVersion4_0_a1))
- if(true)
- transform = GetTransformationMatrices(matrix, invMatrix, !roState.useLocalSpace, worldSpace, state.localToWorld);
- else
- transform = false; // Revert to old broken behavior
- for (size_t q = fromIndex; q < toIndex; ++q)
- {
- Vector3f random;
- GenerateRandom3(random, ps.randomSeed[q] + kParticleSystemClampVelocityCurveId);
- float time = NormalizedTime(ps, q);
- Vector3f vel = ps.velocity[q] + ps.animatedVelocity[q];
- if (transform)
- vel = matrix * vel;
- float scale = roState.GetRenderScale();
- float limitX = Evaluate<mode>(x, time, random.x) * scale;
- float limitY = Evaluate<mode>(y, time, random.y) * scale;
- float limitZ = Evaluate<mode>(z, time, random.z) * scale;
- vel.x = DampenOutsideLimit(vel.x, limitX, dampen);
- vel.y = DampenOutsideLimit(vel.y, limitY, dampen);
- vel.z = DampenOutsideLimit(vel.z, limitZ, dampen);
- vel -= ps.animatedVelocity[q];
- if (transform)
- vel = invMatrix * vel;
- ps.velocity[q] = vel;
- }
- }
- template<ParticleSystemCurveEvalMode mode>
- void DragUpdateTpl(const MinMaxCurve& drag, bool useParticleSize, bool useParticleVelocity, ParticleSystemParticles& ps, size_t fromIndex, size_t toIndex, float dt)
- {
- int useSize = useParticleSize ? 0xffffffff : 0;
- int useVelocity = useParticleVelocity ? 0xffffffff : 0;
- for (size_t q = fromIndex; q < toIndex; ++q)
- {
- float time = NormalizedTime(ps, q);
- float random = GenerateRandom(ps.randomSeed[q] + kParticleSystemDragCurveId);
- float dragCoefficient = Evaluate<mode>(drag, time, random);
- Vector3f vel = ps.velocity[q] + ps.animatedVelocity[q];
- float velMagSqr = SqrMagnitude(vel);
- float maxDimension = ps.size[q];
- // if (ps.uses3DSize)
- // {
- // maxDimension = math::max(maxDimension, math::max(particleSizes[1].load(q), particleSizes[2].load(q)));
- // }
- maxDimension *= 0.5f;
- float circleArea = (M_PI * maxDimension * maxDimension);
- float dragValue = dragCoefficient;
- if (useSize)
- dragValue *= circleArea;
- if (useVelocity)
- dragValue *= velMagSqr;
- float velMag = sqrt(velMagSqr);
- // Vector3f normalizedVel = select(Vector3f(ZERO, ZERO, ZERO), div(vel, velMag), velMag > epsilon_normal_sqrt());
- Vector3f normalizedVel;
- if (velMag > 0)
- normalizedVel = vel / velMag;
- velMag = std::max<float>(0, velMag - dragValue * dt);
-
- vel = normalizedVel * velMag;
- ps.velocity[q] = vel - ps.animatedVelocity[q];
- }
- }
- void ClampVelocityModule::Update (const ParticleSystemReadOnlyState& roState, const ParticleSystemState& state, ParticleSystemParticles& ps, const size_t fromIndex, const size_t toIndex, float dt)
- {
- if (m_Dampen > 0.0f)
- {
- const bool isOptimized = m_X.IsOptimized() && m_Y.IsOptimized() && m_Z.IsOptimized();
- float dampen = 1.0f - pow(1.0f - m_Dampen, dt * 30.0f); // use a reference fps of 30, as damping is set between 0 and 1, and without the reference fps, applied damping
- // is far too small. if we don't apply dt at all, we get FogBugz case 606420, where damping is fps dependent
- if (m_SeparateAxis)
- {
- if (m_X.minMaxState == kMMCScalar)
- MagnitudeUpdatePerAxisTpl<kEMScalar>(m_X, m_Y, m_Z, roState, state, ps, fromIndex, toIndex, dampen, m_InWorldSpace);
- else if (isOptimized && m_X.UsesMinMax())
- MagnitudeUpdatePerAxisTpl<kEMOptimizedMinMax>(m_X, m_Y, m_Z, roState, state, ps, fromIndex, toIndex, dampen, m_InWorldSpace);
- else if (isOptimized)
- MagnitudeUpdatePerAxisTpl<kEMOptimized>(m_X, m_Y, m_Z, roState, state, ps, fromIndex, toIndex, dampen, m_InWorldSpace);
- else
- MagnitudeUpdatePerAxisTpl<kEMSlow>(m_X, m_Y, m_Z, roState, state, ps, fromIndex, toIndex, dampen, m_InWorldSpace);
- }
- else
- {
- if (m_Magnitude.minMaxState == kMMCScalar)
- MagnitudeUpdateTpl<kEMScalar>(m_Magnitude, roState, ps, fromIndex, toIndex, dampen);
- else if (m_Magnitude.IsOptimized() && m_Magnitude.UsesMinMax())
- MagnitudeUpdateTpl<kEMOptimizedMinMax>(m_Magnitude, roState, ps, fromIndex, toIndex, dampen);
- else if (m_Magnitude.IsOptimized())
- MagnitudeUpdateTpl<kEMOptimized>(m_Magnitude, roState, ps, fromIndex, toIndex, dampen);
- else
- MagnitudeUpdateTpl<kEMSlow>(m_Magnitude, roState, ps, fromIndex, toIndex, dampen);
- }
- }
- // apply air drag
- if (m_Drag.GetScalar() != 0.0f)
- {
- if (m_Drag.minMaxState == kMMCScalar)
- DragUpdateTpl<kEMScalar>(m_Drag, m_MultiplyDragByParticleSize, m_MultiplyDragByParticleVelocity, ps, fromIndex, toIndex, dt);
- else if (m_Drag.IsOptimized() && m_Drag.UsesMinMax())
- DragUpdateTpl<kEMOptimizedMinMax>(m_Drag, m_MultiplyDragByParticleSize, m_MultiplyDragByParticleVelocity, ps, fromIndex, toIndex, dt);
- else if (m_Drag.IsOptimized())
- DragUpdateTpl<kEMOptimized>(m_Drag, m_MultiplyDragByParticleSize, m_MultiplyDragByParticleVelocity, ps, fromIndex, toIndex, dt);
- else
- DragUpdateTpl<kEMSlow>(m_Drag, m_MultiplyDragByParticleSize, m_MultiplyDragByParticleVelocity, ps, fromIndex, toIndex, dt);
- }
- }
- void ClampVelocityModule::CheckConsistency ()
- {
- m_Dampen = clamp<float> (m_Dampen, 0.0f, 1.0f);
- m_X.SetScalar(std::max<float> (0.0f, m_X.GetScalar()));
- m_Y.SetScalar(std::max<float> (0.0f, m_Y.GetScalar()));
- m_Z.SetScalar(std::max<float> (0.0f, m_Z.GetScalar()));
- m_Magnitude.SetScalar(std::max<float> (0.0f, m_Magnitude.GetScalar()));
- m_Drag.SetScalar(clamp<float> (m_Drag.GetScalar(), 0.0f, 100000.0f));
- }
- template<class TransferFunction>
- void ClampVelocityModule::Transfer (TransferFunction& transfer)
- {
- ParticleSystemModule::Transfer (transfer);
- transfer.Transfer (m_X, "x");
- transfer.Transfer (m_Y, "y");
- transfer.Transfer (m_Z, "z");
- transfer.Transfer (m_Magnitude, "magnitude");
- transfer.Transfer (m_SeparateAxis, "separateAxis");
- transfer.Transfer (m_InWorldSpace, "inWorldSpace");
- transfer.Transfer (m_MultiplyDragByParticleSize, "multiplyDragByParticleSize");
- transfer.Transfer (m_MultiplyDragByParticleVelocity, "multiplyDragByParticleVelocity"); transfer.Align ();
- transfer.Transfer (m_Dampen, "dampen");
- transfer.Transfer (m_Drag, "drag");
- }
- INSTANTIATE_TEMPLATE_TRANSFER(ClampVelocityModule)
- NS_RRP_END
|