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
103
104
105
|
#include "UnityPrefix.h"
#include "UVModule.h"
#include "Runtime/BaseClasses/ObjectDefines.h"
#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
#include "Runtime/Graphics/ParticleSystem/ParticleSystemParticle.h"
#include "Runtime/Graphics/ParticleSystem/ParticleSystemCurves.h"
#include "Runtime/Graphics/ParticleSystem/ParticleSystemUtils.h"
#include "Runtime/Math/Random/Random.h"
template<ParticleSystemCurveEvalMode mode>
void UpdateWholeSheetTpl(float cycles, const MinMaxCurve& curve, const ParticleSystemParticles& ps, float* tempSheetIndex, size_t fromIndex, size_t toIndex)
{
for (size_t q = fromIndex; q < toIndex; ++q)
tempSheetIndex[q] = Repeat (cycles * Evaluate(curve, NormalizedTime(ps, q), GenerateRandom(ps.randomSeed[q] + kParticleSystemUVCurveId)), 1.0f);
}
UVModule::UVModule () : ParticleSystemModule(false)
, m_TilesX (1), m_TilesY (1)
, m_AnimationType (kWholeSheet)
, m_RowIndex (0)
, m_Cycles (1.0f)
, m_RandomRow (true)
{}
void UVModule::Update (const ParticleSystemParticles& ps, float* tempSheetIndex, size_t fromIndex, size_t toIndex)
{
const float cycles = m_Cycles;
DebugAssert(toIndex <= ps.array_size ());
if (m_AnimationType == kSingleRow) // row
{
int rows = m_TilesY;
float animRange = (1.0f / (m_TilesX * rows)) * m_TilesX;
if(m_RandomRow)
{
for (size_t q = fromIndex; q < toIndex; ++q)
{
const float t = cycles * Evaluate(m_Curve, NormalizedTime(ps, q), GenerateRandom(ps.randomSeed[q] + kParticleSystemUVCurveId));
const float x = Repeat (t, 1.0f);
const float randomValue = GenerateRandom(ps.randomSeed[q] + kParticleSystemUVRowSelectionId);
const float startRow = Floorf (randomValue * rows);
float from = startRow * animRange;
float to = from + animRange;
tempSheetIndex[q] = Lerp (from, to, x);
}
}
else
{
const float startRow = Floorf(m_RowIndex * animRange * rows);
float from = startRow * animRange;
float to = from + animRange;
for (size_t q = fromIndex; q < toIndex; ++q)
{
const float t = cycles * Evaluate(m_Curve, NormalizedTime(ps, q), GenerateRandom(ps.randomSeed[q] + kParticleSystemUVCurveId));
const float x = Repeat (t, 1.0f);
tempSheetIndex[q] = Lerp (from, to, x);
}
}
}
else if (m_AnimationType == kWholeSheet) // grid || row
{
if(m_Curve.minMaxState == kMMCScalar)
UpdateWholeSheetTpl<kEMScalar>(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex);
else if (m_Curve.IsOptimized() && m_Curve.UsesMinMax ())
UpdateWholeSheetTpl<kEMOptimizedMinMax>(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex);
else if(m_Curve.IsOptimized())
UpdateWholeSheetTpl<kEMOptimized>(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex);
else
UpdateWholeSheetTpl<kEMSlow>(m_Cycles, m_Curve, ps, tempSheetIndex, fromIndex, toIndex);
}
else
{
Assert(!"Animation mode not implemented!");
}
}
void UVModule::CheckConsistency ()
{
m_AnimationType = clamp<int> (m_AnimationType, 0, kNumAnimationTypes-1);
m_TilesX = std::max<int> (1, m_TilesX);
m_TilesY = std::max<int> (1, m_TilesY);
m_Cycles = std::max<int> (1, (int)m_Cycles);
m_RowIndex = clamp<int> (m_RowIndex, 0, m_TilesY-1);
m_Curve.SetScalar(clamp<float> (m_Curve.GetScalar(), 0.0f, 1.0f));
}
void UVModule::GetNumTiles(int& uvTilesX, int& uvTilesY) const
{
uvTilesX = m_TilesX;
uvTilesY = m_TilesY;
}
template<class TransferFunction>
void UVModule::Transfer (TransferFunction& transfer)
{
ParticleSystemModule::Transfer (transfer);
transfer.Transfer (m_Curve, "frameOverTime");
transfer.Transfer (m_TilesX, "tilesX");
transfer.Transfer (m_TilesY, "tilesY");
transfer.Transfer (m_AnimationType, "animationType");
transfer.Transfer (m_RowIndex, "rowIndex");
transfer.Transfer (m_Cycles, "cycles");
transfer.Transfer (m_RandomRow, "randomRow"); transfer.Align ();
}
INSTANTIATE_TEMPLATE_TRANSFER(UVModule)
|