RavEngine
Loading...
Searching...
No Matches
ParticleEmitter.hpp
1#pragma once
2#include "Queryable.hpp"
3#include "CTTI.hpp"
4#include "RGL/Types.hpp"
5#include "Ref.hpp"
6#include "ComponentWithOwner.hpp"
7
8namespace RavEngine {
9
10 struct BillboardParticleRenderMaterialInstance;
11 struct MeshParticleRenderMaterialInstance;
12 struct ParticleUpdateMaterialInstance;
13
15 uint32_t aliveParticleCount = 0;
16 uint32_t freeListCount = 0;
17 uint32_t particlesCreatedThisFrame = 0;
18 };
19
20 struct EmitterState {
22 entity_t emitterOwnerID;
23 };
24
25 // to ensure the buffer copies for Reset work correctly
26 static_assert(offsetof(EmitterState, emitterOwnerID) == sizeof(EmitterStateNumericFields), "EmitterState is not correctly aligned!");
27
28
29 using ParticleRenderMaterialVariant = std::variant<Ref<BillboardParticleRenderMaterialInstance>, Ref<MeshParticleRenderMaterialInstance>>;
30
31 struct ParticleEmitter : public ComponentWithOwner, public Queryable<ParticleEmitter>{
32 friend class RenderEngine;
33 enum class Mode : uint8_t {
34 Stream,
35 Burst
36 } mode = Mode::Stream;
37
38 ParticleEmitter(Entity owner, uint32_t maxParticles, uint16_t sizeOfEachParticle, const Ref<ParticleUpdateMaterialInstance> updateMat, const ParticleRenderMaterialVariant& mat);
39
40 MOVE_NO_COPY(ParticleEmitter);
41
42 void Destroy();
43
44 const auto GetRenderMaterial() const {
45 return renderMaterial;
46 }
47
48 const auto GetUpdateMaterial() const {
49 return updateMaterial;
50 }
51
56 void Play();
57
61 void Stop();
62
66 void Reset() {
67 resetRequested = true;
68 }
69
70 bool IsEmitting() const {
71 return emittingThisFrame;
72 }
73
74 auto GetMaxParticles() const {
75 return maxParticleCount;
76 }
77
78 void SetEmissionRate(uint32_t rate);
79
80 // this function modifies internal state.
81 // for internal use only
82 uint32_t GetNextParticleSpawnCount();
83
84
85 // when a particle systen is frozen, it does not tick.
86 // If a particle system is set to invisible, it also becomes frozen
87 void SetFrozen(bool frozen) {
88 isFrozen = frozen;
89 }
90
91 void SetVisibility(bool visible) {
92 isVisible = visible;
93 SetFrozen(!isVisible);
94 }
95
96 bool GetFrozen() const {
97 return isFrozen;
98 }
99
100 bool GetVisible() const {
101 return isVisible;
102 }
103
104 private:
105 RGLBufferPtr
106 particleDataBuffer = nullptr,
107 particleReuseFreelist = nullptr,
108 spawnedThisFrameList = nullptr,
109 activeParticleIndexBuffer = nullptr,
110 indirectComputeBuffer = nullptr,
111 indirectDrawBuffer = nullptr,
112 emitterStateBuffer = nullptr,
113 particleLifeBuffer = nullptr,
114 indirectDrawBufferStaging = nullptr, // not initialized in the Emitter constructor
115 meshAliveParticleIndexBuffer = nullptr; // not initialized in the Emitter constructor
116
117 ParticleRenderMaterialVariant renderMaterial;
118 Ref<ParticleUpdateMaterialInstance> updateMaterial;
119
120 double lastSpawnTime = 0;
121
122 uint32_t maxParticleCount;
123
124 uint32_t spawnRate = 10;
125
126 void ClearReset() {
127 resetRequested = false;
128 }
129
130 // this is icky and nasty, we need a better solution than this
131 struct RenderState {
132 uint32_t maxTotalParticlesOffset = 0;
133 } renderState;
134
135 bool emittingThisFrame : 1 = false;
136 bool isVisible : 1 = true;
137 bool isFrozen : 1 = false;
138 bool resetRequested : 1 = false;
139 };
140
141}
Definition ComponentWithOwner.hpp:6
Definition RenderEngine.hpp:64
Definition concurrentqueue.h:747
uint32 uint32_t
Definition fwd.hpp:131
Definition Animation.hpp:6
Definition Types.hpp:10
Definition ParticleEmitter.hpp:14
Definition ParticleEmitter.hpp:20
Definition Entity.hpp:11
Definition ParticleEmitter.hpp:31
void Reset()
Definition ParticleEmitter.hpp:66
void Play()
Definition ParticleEmitter.cpp:66
void Stop()
Definition ParticleEmitter.cpp:71
Definition Queryable.hpp:21