1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include "UnityPrefix.h"
#include "Runtime/BaseClasses/ObjectDefines.h"
#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
#include "ClampVelocityModule.h"
#include "Runtime/Graphics/ParticleSystem/ParticleSystemUtils.h"
#include "Runtime/Misc/BuildSettings.h"
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, 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));
Vector3f vel = ps.velocity[q] + ps.animatedVelocity[q];
vel = NormalizeSafe (vel) * DampenOutsideLimit (Magnitude (vel), limit, dampen);
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)
{
if (m_SeparateAxis)
{
Matrix4x4f matrix;
Matrix4x4f invMatrix;
bool transform;
if(IS_CONTENT_NEWER_OR_SAME (kUnityVersion4_0_a1))
transform = GetTransformationMatrices(matrix, invMatrix, !roState.useLocalSpace, m_InWorldSpace, 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);
const float time = NormalizedTime(ps, q);
Vector3f vel = ps.velocity[q] + ps.animatedVelocity[q];
if(transform)
vel = matrix.MultiplyVector3 (vel);
const Vector3f limit (Evaluate (m_X, time, random.x), Evaluate (m_Y, time, random.y), Evaluate (m_Z, time, random.z));
vel.x = DampenOutsideLimit (vel.x, limit.x, m_Dampen);
vel.y = DampenOutsideLimit (vel.y, limit.y, m_Dampen);
vel.z = DampenOutsideLimit (vel.z, limit.z, m_Dampen);
vel = vel - ps.animatedVelocity[q];
if(transform)
vel = invMatrix.MultiplyVector3 (vel);
ps.velocity[q] = vel;
}
}
else
{
if(m_Magnitude.minMaxState == kMMCScalar)
MagnitudeUpdateTpl<kEMScalar> (m_Magnitude, ps, fromIndex, toIndex, m_Dampen);
else if(m_Magnitude.IsOptimized() && m_Magnitude.UsesMinMax())
MagnitudeUpdateTpl<kEMOptimizedMinMax> (m_Magnitude, ps, fromIndex, toIndex, m_Dampen);
else if(m_Magnitude.IsOptimized())
MagnitudeUpdateTpl<kEMOptimized> (m_Magnitude, ps, fromIndex, toIndex, m_Dampen);
else
MagnitudeUpdateTpl<kEMSlow> (m_Magnitude, ps, fromIndex, toIndex, m_Dampen);
}
}
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()));
}
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.Align ();
transfer.Transfer (m_Dampen, "dampen");
}
INSTANTIATE_TEMPLATE_TRANSFER(ClampVelocityModule)
|