Pyrogenesis trunk
ParticleEmitter.h
Go to the documentation of this file.
1/* Copyright (C) 2023 Wildfire Games.
2 * This file is part of 0 A.D.
3 *
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef INCLUDED_PARTICLEEMITTER
19#define INCLUDED_PARTICLEEMITTER
20
23#include "maths/Quaternion.h"
27
28#include <map>
29
30/**
31 * Simulation state for a single particle.
32 */
34{
37 float angle;
39 float size;
42 float age;
43 float maxAge;
44};
45
46typedef std::shared_ptr<CParticleEmitter> CParticleEmitterPtr;
47
48/**
49 * Particle emitter.
50 *
51 * Emitters store particle data in two forms:
52 * * m_Particles contains the raw data used for the CPU particle simulation.
53 * * m_VertexArray contains the data required for rendering.
54 * Particles are rendered as billboard quads, so the vertex array contains four vertices
55 * per particle with different UV coordinates. The billboard position computation is
56 * performed by a vertex shader.
57 *
58 * The number of particles is a constant for the entire life of the emitter,
59 * to simplify the updating and rendering.
60 * m_Particles acts like a ring buffer, so we don't have to worry about dynamically
61 * allocating particles. If particles have variable lifetimes, they'll exist in the
62 * array with alpha=0 until they're overwritten by a new particle after the maximum
63 * lifetime.
64 *
65 * (It's quite likely this could be made more efficient, if the overhead of any added
66 * complexity is not high.)
67 */
69{
70public:
72
73 /**
74 * Set the position to be used for emission of new particles.
75 */
76 void SetPosition(const CVector3D& pos)
77 {
78 m_Pos = pos;
79 }
80
82 {
83 return m_Pos;
84 }
85
86 /**
87 * Set the rotation to be used for emission of new particles (note: depends on particles).
88 */
89 void SetRotation(const CQuaternion& rot)
90 {
91 m_Rot = rot;
92 }
93
94 const CQuaternion& GetRotation() const
95 {
96 return m_Rot;
97 }
98
99 /**
100 * Get the bounding box of the center points of particles at their current positions.
101 */
103
104 /**
105 * Push a new particle onto the ring buffer. (May overwrite an old particle.)
106 */
107 void AddParticle(const SParticle& particle);
108
109 /**
110 * Update particle and vertex array data. Must be called before RenderArray.
111 *
112 * If frameNumber is the same as the previous call to UpdateArrayData,
113 * then the function will do no work and return immediately.
114 */
115 void UpdateArrayData(int frameNumber);
116
117 /**
118 * Make the vertex data available for subsequent binding and rendering.
119 */
120 void PrepareForRendering();
121
122 /**
123 * Upload the vertex data to the backend.
124 */
125 void UploadData(
126 Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
127
128 /**
129 * Bind rendering state (textures and blend modes).
130 */
131 void Bind(
132 Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
134
135 /**
136 * Draw the vertex array.
137 */
138 void RenderArray(
139 Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
140
141 /**
142 * Stop this emitter emitting new particles, and pass responsibility for rendering
143 * to the CParticleManager. This should be called before dropping the last std::shared_ptr
144 * to this object so that it will carry on rendering (until all particles have dissipated)
145 * even when it's no longer attached to a model.
146 * @param self the std::shared_ptr you're about to drop
147 */
148 void Unattach(const CParticleEmitterPtr& self);
149
150 void SetEntityVariable(const std::string& name, float value);
151
153
154 /// Whether this emitter is still emitting new particles
156
159
160 std::map<std::string, float> m_EntityVariables;
161
162 std::vector<SParticle> m_Particles;
164
167
168private:
169 /// Bounding box of the current particle center points
171
173
179
181
183};
184
185/**
186 * Particle emitter model, for attaching emitters as props on other models.
187 */
189{
190public:
192 ~CModelParticleEmitter() override;
193
194 /// Dynamic cast
196 {
197 return this;
198 }
199
200 std::unique_ptr<CModelAbstract> Clone() const override;
201
203 {
204 }
205
206 void SetEntityVariable(const std::string& name, float value) override;
207
208 void CalcBounds() override;
209 void ValidatePosition() override;
210 void InvalidatePosition() override;
211 void SetTransform(const CMatrix3D& transform) override;
212
215};
216
217#endif // INCLUDED_PARTICLEEMITTER
std::shared_ptr< CParticleEmitterType > CParticleEmitterTypePtr
Definition: ParticleEmitterType.h:123
std::shared_ptr< CParticleEmitter > CParticleEmitterPtr
Definition: ParticleEmitter.h:46
Definition: BoundingBoxAligned.h:34
Definition: Matrix3D.h:34
Abstract base class for graphical objects that are used by units, or as props attached to other CMode...
Definition: ModelAbstract.h:50
Particle emitter model, for attaching emitters as props on other models.
Definition: ParticleEmitter.h:189
void SetTransform(const CMatrix3D &transform) override
Definition: ParticleEmitter.cpp:312
std::unique_ptr< CModelAbstract > Clone() const override
Definition: ParticleEmitter.cpp:285
CModelParticleEmitter * ToCModelParticleEmitter() override
Dynamic cast.
Definition: ParticleEmitter.h:195
CModelParticleEmitter(const CParticleEmitterTypePtr &type)
Definition: ParticleEmitter.cpp:269
void SetTerrainDirty(ssize_t i0, ssize_t j0, ssize_t i1, ssize_t j1) override
Called when terrain has changed in the given inclusive bounds.
Definition: ParticleEmitter.h:202
~CModelParticleEmitter() override
Definition: ParticleEmitter.cpp:275
CParticleEmitterTypePtr m_Type
Definition: ParticleEmitter.h:213
CParticleEmitterPtr m_Emitter
Definition: ParticleEmitter.h:214
void CalcBounds() override
(Re)calculates and stores any bounds or bound-dependent data for this object.
Definition: ParticleEmitter.cpp:290
void ValidatePosition() override
Ensure that both the transformation and the bone matrices are correct for this model and all its prop...
Definition: ParticleEmitter.cpp:299
void SetEntityVariable(const std::string &name, float value) override
Called when the entity tries to set some variable to affect the display of this model and/or its chil...
Definition: ParticleEmitter.cpp:280
void InvalidatePosition() override
Mark this model's position and bone matrices, and all props' positions as invalid.
Definition: ParticleEmitter.cpp:308
Particle emitter.
Definition: ParticleEmitter.h:69
CVector3D m_Pos
Definition: ParticleEmitter.h:157
float m_EmissionRoundingError
Definition: ParticleEmitter.h:166
std::vector< SParticle > m_Particles
Definition: ParticleEmitter.h:162
Renderer::Backend::IVertexInputLayout * m_VertexInputLayout
Definition: ParticleEmitter.h:180
CVector3D GetPosition() const
Definition: ParticleEmitter.h:81
int m_LastFrameNumber
Definition: ParticleEmitter.h:182
VertexArray::Attribute m_AttributeColor
Definition: ParticleEmitter.h:178
void SetPosition(const CVector3D &pos)
Set the position to be used for emission of new particles.
Definition: ParticleEmitter.h:76
void AddParticle(const SParticle &particle)
Push a new particle onto the ring buffer.
Definition: ParticleEmitter.cpp:254
void Bind(Renderer::Backend::IDeviceCommandContext *deviceCommandContext, Renderer::Backend::IShaderProgram *shader)
Bind rendering state (textures and blend modes).
Definition: ParticleEmitter.cpp:201
void UpdateArrayData(int frameNumber)
Update particle and vertex array data.
Definition: ParticleEmitter.cpp:100
const CBoundingBoxAligned & GetParticleBounds() const
Get the bounding box of the center points of particles at their current positions.
Definition: ParticleEmitter.h:102
void RenderArray(Renderer::Backend::IDeviceCommandContext *deviceCommandContext)
Draw the vertex array.
Definition: ParticleEmitter.cpp:227
VertexArray::Attribute m_AttributeAxis
Definition: ParticleEmitter.h:176
const CQuaternion & GetRotation() const
Definition: ParticleEmitter.h:94
VertexArray::Attribute m_AttributeUV
Definition: ParticleEmitter.h:177
float m_LastUpdateTime
Definition: ParticleEmitter.h:165
CParticleEmitterTypePtr m_Type
Definition: ParticleEmitter.h:152
std::map< std::string, float > m_EntityVariables
Definition: ParticleEmitter.h:160
size_t m_NextParticleIdx
Definition: ParticleEmitter.h:163
void PrepareForRendering()
Make the vertex data available for subsequent binding and rendering.
Definition: ParticleEmitter.cpp:190
void SetRotation(const CQuaternion &rot)
Set the rotation to be used for emission of new particles (note: depends on particles).
Definition: ParticleEmitter.h:89
void SetEntityVariable(const std::string &name, float value)
Definition: ParticleEmitter.cpp:264
void Unattach(const CParticleEmitterPtr &self)
Stop this emitter emitting new particles, and pass responsibility for rendering to the CParticleManag...
Definition: ParticleEmitter.cpp:248
VertexIndexArray m_IndexArray
Definition: ParticleEmitter.h:172
bool m_Active
Whether this emitter is still emitting new particles.
Definition: ParticleEmitter.h:155
CBoundingBoxAligned m_ParticleBounds
Bounding box of the current particle center points.
Definition: ParticleEmitter.h:170
VertexArray m_VertexArray
Definition: ParticleEmitter.h:174
void UploadData(Renderer::Backend::IDeviceCommandContext *deviceCommandContext)
Upload the vertex data to the backend.
Definition: ParticleEmitter.cpp:195
CQuaternion m_Rot
Definition: ParticleEmitter.h:158
CParticleEmitter(const CParticleEmitterTypePtr &type)
Definition: ParticleEmitter.cpp:32
VertexArray::Attribute m_AttributePos
Definition: ParticleEmitter.h:175
Definition: Quaternion.h:26
Definition: Vector3D.h:31
Definition: IDeviceCommandContext.h:42
IShaderProgram is a container for multiple shaders of different types.
Definition: IShaderProgram.h:81
IVertexInputLayout stores precompiled list of vertex attributes.
Definition: IShaderProgram.h:74
Definition: VertexArray.h:138
A VertexArray that is specialised to handle 16-bit array indices.
Definition: VertexArray.h:220
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning.
Definition: code_annotation.h:40
Definition: SColor.h:31
Simulation state for a single particle.
Definition: ParticleEmitter.h:34
float size
Definition: ParticleEmitter.h:39
float angleSpeed
Definition: ParticleEmitter.h:38
float maxAge
Definition: ParticleEmitter.h:43
SColor4ub color
Definition: ParticleEmitter.h:41
CVector3D pos
Definition: ParticleEmitter.h:35
float angle
Definition: ParticleEmitter.h:37
float age
Definition: ParticleEmitter.h:42
float sizeGrowthRate
Definition: ParticleEmitter.h:40
CVector3D velocity
Definition: ParticleEmitter.h:36
Definition: VertexArray.h:141
intptr_t ssize_t
Definition: wposix_types.h:82