summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/ParticleSystem/Modules/UVModule.cpp
blob: 67d49b338f05a25efca7331752bbadcae9bfd406 (plain)
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)