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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
#include "UnityPrefix.h"
#include "EmissionModule.h"
#include "Runtime/BaseClasses/ObjectDefines.h"
#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
#include "Runtime/Math/Vector2.h"
static int AccumulateBursts (const ParticleSystemEmissionData& emissionData, float t0, float t1)
{
int burstParticles = 0;
const size_t count = emissionData.burstCount;
for (size_t q = 0; q < count; ++q)
{
if (emissionData.burstTime[q] >= t0 && emissionData.burstTime[q] < t1)
burstParticles += emissionData.burstParticleCount[q];
}
return burstParticles;
}
static float AccumulateContinuous(const ParticleSystemEmissionData& emissionData, const float length, const float toT, const float dt)
{
DebugAssert (length > 0.0001f);
DebugAssert (toT >= 0.0f);
DebugAssert (toT <= length);
float normalizedT = toT / length;
return std::max<float> (0.0f, Evaluate (emissionData.rate, normalizedT)) * dt;
};
EmissionModule::EmissionModule () : ParticleSystemModule(true)
{
m_EmissionData.burstCount = 0;
m_EmissionData.type = kEmissionTypeTime;
for(int i = 0; i < ParticleSystemEmissionData::kMaxNumBursts; i++)
{
m_EmissionData.burstParticleCount[i] = 30;
m_EmissionData.burstTime[i] = 0.0f;
}
}
void EmissionModule::Emit (ParticleSystemEmissionState& emissionState, size_t& amountOfParticlesToEmit, size_t& numContinuous, const ParticleSystemEmissionData& emissionData, const Vector3f velocity, float fromT, float toT, float dt, float length)
{
const float epsilon = 0.0001f;
if(kEmissionTypeTime == emissionData.type)
{
float rate = 0.0f;
float t0 = std::max<float> (0.0f, fromT);
float t1 = std::max<float> (0.0f, toT);
if (t1 < t0) // handle loop
{
rate += AccumulateContinuous (emissionData, length, t1, t1); // from start to current time
t1 = length; // from last time to end
}
rate += AccumulateContinuous (emissionData, length, t1, t1 - t0); // from start to current time
const float newParticles = rate;
if(newParticles >= epsilon)
emissionState.m_ParticleSpacing = 1.0f / newParticles;
else
emissionState.m_ParticleSpacing = 1.0f;
emissionState.m_ToEmitAccumulator += newParticles;
amountOfParticlesToEmit = (int)emissionState.m_ToEmitAccumulator;
emissionState.m_ToEmitAccumulator -= (float)amountOfParticlesToEmit;
// Continuous emits
numContinuous = amountOfParticlesToEmit;
// Bursts
t0 = std::max<float> (0.0f, fromT);
t1 = std::max<float> (0.0f, toT);
if (t1 < t0) // handle loop
{
amountOfParticlesToEmit += AccumulateBursts (emissionData, 0.0f, t1); // from start to current time
t1 = length + epsilon; // from last time to end
}
amountOfParticlesToEmit += AccumulateBursts (emissionData, t0, t1); // from start to current time
}
else
{
float newParticles = AccumulateContinuous (emissionData, length, toT, dt) * Magnitude (velocity); // from start to current time
if(newParticles >= epsilon)
emissionState.m_ParticleSpacing = 1.0f / newParticles;
else
emissionState.m_ParticleSpacing = 1.0f;
emissionState.m_ToEmitAccumulator += newParticles;
amountOfParticlesToEmit = (int)emissionState.m_ToEmitAccumulator;
emissionState.m_ToEmitAccumulator -= (float)amountOfParticlesToEmit;
// Continuous emits
numContinuous = amountOfParticlesToEmit;
}
}
void EmissionModule::CheckConsistency ()
{
m_EmissionData.rate.SetScalar(std::max<float> (0.0f, m_EmissionData.rate.GetScalar()));
const size_t count = m_EmissionData.burstCount;
for (size_t q = 0; q < count; ++q)
{
m_EmissionData.burstTime[q] = std::max<float> (0.0f, m_EmissionData.burstTime[q]);
}
}
template<class TransferFunction>
void EmissionModule::Transfer (TransferFunction& transfer)
{
ParticleSystemModule::Transfer (transfer);
transfer.Transfer (m_EmissionData.type, "m_Type");
transfer.Transfer (m_EmissionData.rate, "rate");
const char* kCountNames [ParticleSystemEmissionData::kMaxNumBursts] = { "cnt0", "cnt1", "cnt2", "cnt3", };
const char* kTimeNames [ParticleSystemEmissionData::kMaxNumBursts] = { "time0", "time1", "time2", "time3", };
for(int i = 0; i < ParticleSystemEmissionData::kMaxNumBursts; i++)
transfer.Transfer (m_EmissionData.burstParticleCount[i], kCountNames[i]);
for(int i = 0; i < ParticleSystemEmissionData::kMaxNumBursts; i++)
transfer.Transfer (m_EmissionData.burstTime[i], kTimeNames[i]);
transfer.Transfer (m_EmissionData.burstCount, "m_BurstCount"); transfer.Align();
}
INSTANTIATE_TEMPLATE_TRANSFER(EmissionModule)
|