Skip to content

Commit f063abe

Browse files
committed
Engine: Flexible Visual Effects system #893
1 parent 1d4a3f0 commit f063abe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1408
-1131
lines changed

engine/includes/components/effectrender.h

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,22 @@
33

44
#include "renderable.h"
55

6-
#include "resources/particleeffect.h"
7-
8-
struct GpuQuadParticle {
9-
// xyz - world position, w - objectID.x
10-
Vector4 worldPosition;
11-
12-
// xy - size, z - rotation, w - objectID.y
13-
Vector4 sizeRot;
14-
15-
// xy - uvScale, z - distance, w - objectID.z
16-
Vector4 uvScaleDist;
17-
18-
// xy - uvOffset, z - unused, w - objectID.w
19-
Vector4 uvOffset;
20-
21-
// xyzw - color
22-
Vector4 color;
23-
};
6+
#include "resources/visualeffect.h"
247

258
class ENGINE_EXPORT EffectRender : public Renderable {
269
A_REGISTER(EffectRender, Renderable, Components/Effects)
2710

2811
A_PROPERTIES(
29-
A_PROPERTYEX(ParticleEffect *, effect, EffectRender::effect, EffectRender::setEffect, "editor=Asset")
12+
A_PROPERTYEX(VisualEffect *, effect, EffectRender::effect, EffectRender::setEffect, "editor=Asset")
3013
)
3114
A_NOMETHODS()
3215

3316
public:
3417
EffectRender();
3518
~EffectRender() override;
3619

37-
ParticleEffect *effect() const;
38-
void setEffect(ParticleEffect *effect);
20+
VisualEffect *effect() const;
21+
void setEffect(VisualEffect *effect);
3922

4023
void deltaUpdate(float dt);
4124

@@ -53,11 +36,11 @@ class ENGINE_EXPORT EffectRender : public Renderable {
5336

5437
std::vector<float> m_particleData;
5538

56-
std::vector<GpuQuadParticle> m_quads;
39+
std::vector<float> m_renderData;
5740

5841
std::vector<int32_t> m_offsets;
5942

60-
ParticleEffect *m_effect;
43+
VisualEffect *m_effect;
6144
};
6245

6346
#endif // EFFECTRENDER_H

engine/includes/editor/assetconverter.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,10 @@ struct Template {
132132
type(MetaType::INVALID) {
133133

134134
}
135-
Template(const QString &p, const uint32_t t) :
136-
path(p) {
137-
type = MetaType::name(t);
135+
Template(const QString &p, const QString &t) :
136+
path(p),
137+
type(t) {
138+
138139
type = type.replace("*", "");
139140
type = type.trimmed();
140141
}

engine/includes/resources/particleeffect.h renamed to engine/includes/resources/visualeffect.h

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
1-
#ifndef PARTICLEEFFECT_H
2-
#define PARTICLEEFFECT_H
1+
#ifndef VISUALEFFECT_H
2+
#define VISUALEFFECT_H
33

44
#include <resource.h>
55

66
#include <material.h>
77
#include <mesh.h>
88

9-
class ENGINE_EXPORT ParticleEffect : public Resource {
10-
A_REGISTER(ParticleEffect, Resource, Resources)
9+
class ENGINE_EXPORT VisualEffect : public Resource {
10+
A_REGISTER(VisualEffect, Resource, Resources)
1111

1212
A_NOPROPERTIES()
1313
A_NOMETHODS()
1414
A_NOENUMS()
1515

1616
public:
17+
struct Argument {
18+
int32_t space;
19+
20+
int32_t size;
21+
22+
int32_t offset;
23+
};
24+
1725
struct Operator {
1826
int32_t op;
1927

@@ -23,21 +31,24 @@ class ENGINE_EXPORT ParticleEffect : public Resource {
2331

2432
int32_t resultSize;
2533

26-
int32_t mode;
34+
std::vector<Argument> arguments;
2735

28-
int32_t argSpace;
29-
30-
int32_t argOffset;
31-
32-
int32_t argSize;
36+
std::vector<float> constData;
37+
};
3338

34-
std::vector<float> argData;
39+
enum EmitterAttributes {
40+
EmitterAge = 0,
41+
DeltaTime,
42+
AliveParticles,
43+
SpawnRate,
44+
SpawnCounter,
45+
LastAttribute
3546
};
3647

3748
public:
38-
ParticleEffect();
49+
VisualEffect();
3950

40-
void update(std::vector<float> &emitter, std::vector<float> &particles);
51+
void update(std::vector<float> &emitter, std::vector<float> &particles, std::vector<float> &render);
4152

4253
int capacity() const;
4354
void setCapacity(int capacity);
@@ -60,7 +71,8 @@ class ENGINE_EXPORT ParticleEffect : public Resource {
6071
bool continous() const;
6172
void setContinous(bool continuous);
6273

63-
inline int attributeStride() const;
74+
inline int particleStride() const;
75+
inline int renderableStride() const;
6476

6577
AABBox bound() const;
6678

@@ -81,7 +93,9 @@ class ENGINE_EXPORT ParticleEffect : public Resource {
8193

8294
int m_capacity;
8395

84-
int m_attributeStride;
96+
int m_particleStride;
97+
98+
int m_renderableStride;
8599

86100
bool m_gpu;
87101

@@ -90,10 +104,10 @@ class ENGINE_EXPORT ParticleEffect : public Resource {
90104
bool m_continous;
91105

92106
private:
93-
void apply(std::vector<Operator> &operations, std::vector<float> &emitter, std::vector<float> &particle, bool spawn) const;
107+
void apply(std::vector<Operator> &operations, std::vector<float> &emitter, std::vector<float> &particle, std::vector<float> &render, int stage) const;
94108

95109
void loadOperations(const VariantList &list, std::vector<Operator> &operations);
96110

97111
};
98112

99-
#endif // PARTICLEEFFECT_H
113+
#endif // VISUALEFFECT_H

engine/src/components/effectrender.cpp

Lines changed: 37 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,12 @@
88
#include "transform.h"
99
#include "camera.h"
1010

11-
#include "particleeffect.h"
11+
#include "visualeffect.h"
1212
#include "material.h"
1313

1414
#include "commandbuffer.h"
1515
#include "timer.h"
1616

17-
namespace {
18-
const char *gEffect("Effect");
19-
};
20-
21-
enum class EmitterDefaultAttributes {
22-
Age = 0,
23-
DeltaTime,
24-
SpawnCounter,
25-
LastAttribute
26-
};
27-
28-
enum class ParticleDefaultAttributes {
29-
Age = 0,
30-
Lifetime,
31-
Position,
32-
Rotation,
33-
Size,
34-
Color,
35-
Velocity,
36-
LastAttribute
37-
};
38-
3917
/*!
4018
\class EffectRender
4119
\brief Draws a particle effect on the scene.
@@ -70,16 +48,13 @@ void EffectRender::deltaUpdate(float dt) {
7048
return;
7149
}
7250

73-
bool local = m_effect->local();
74-
bool continous = m_effect->continous();
75-
76-
float &emitterAge = m_emitterData[static_cast<int32_t>(EmitterDefaultAttributes::Age)];
77-
float &deltaTime = m_emitterData[static_cast<int32_t>(EmitterDefaultAttributes::DeltaTime)];
51+
float &emitterAge = m_emitterData[VisualEffect::EmitterAge];
52+
float &deltaTime = m_emitterData[VisualEffect::DeltaTime];
7853

7954
deltaTime = dt;
8055

81-
if(continous || emitterAge > 0.0f) {
82-
float &emitterSpawnCounter = m_emitterData[static_cast<int32_t>(EmitterDefaultAttributes::SpawnCounter)];
56+
if(m_effect->continous() || emitterAge > 0.0f) {
57+
float &emitterSpawnCounter = m_emitterData[VisualEffect::SpawnCounter];
8358

8459
emitterSpawnCounter += m_effect->spawnRate() * deltaTime;
8560

@@ -88,50 +63,27 @@ void EffectRender::deltaUpdate(float dt) {
8863
}
8964
}
9065

91-
m_effect->update(m_emitterData, m_particleData);
92-
93-
Matrix4 world(transform()->worldTransform());
94-
Vector3 cameraPos(camera->transform()->worldPosition());
95-
96-
int capacity = m_effect->capacity();
97-
int stride = m_effect->attributeStride();
98-
99-
uint32_t visibleCount = 0;
100-
for(int index = 0; index < capacity; index++) {
101-
int i = index * stride;
102-
103-
if(m_particleData[i] > 0.0f) {
104-
GpuQuadParticle &q = m_quads[visibleCount];
105-
106-
Vector3 position(m_particleData[i + 2], m_particleData[i + 3], m_particleData[i + 4]);
107-
q.worldPosition = (local) ? world * position : position;
108-
109-
q.sizeRot.x = 1.0f; //p.size.x;
110-
q.sizeRot.y = 1.0f; //p.size.y;
111-
q.sizeRot.z = 0.0f; //p.rotation.z * DEG2RAD;
112-
113-
q.uvScaleDist.x = 1.0f; //p.uv.x;
114-
q.uvScaleDist.y = 1.0f; //p.uv.y;
115-
q.uvScaleDist.z = cameraPos.dot(q.worldPosition);
66+
m_effect->update(m_emitterData, m_particleData, m_renderData);
11667

117-
q.uvOffset.x = 0.0f; //p.uv.z;
118-
q.uvOffset.y = 0.0f; //p.uv.w;
68+
if(m_effect->local()) {
69+
Matrix4 world(transform()->worldTransform());
11970

120-
q.color.x = m_particleData[i + 11];
121-
q.color.y = m_particleData[i + 12];
122-
q.color.z = m_particleData[i + 13];
123-
q.color.w = m_particleData[i + 14];
71+
int32_t count = static_cast<int32_t>(m_emitterData[VisualEffect::AliveParticles]);
72+
int32_t stride = m_effect->renderableStride();
12473

125-
visibleCount++;
74+
for(int32_t i = 0; i < count; i++) {
75+
int index = i * stride;
76+
Vector3 p(world * Vector3(m_renderData[index + 12], m_renderData[index + 13], m_renderData[index + 14]));
77+
m_renderData[index + 12] = p.x;
78+
m_renderData[index + 13] = p.y;
79+
m_renderData[index + 14] = p.z;
12680
}
12781
}
12882

129-
std::sort(m_quads.begin(), m_quads.end(), [](const GpuQuadParticle &left, const GpuQuadParticle &right) { return left.uvScaleDist.z > right.uvScaleDist.z; });
130-
13183
MaterialInstance *instance = m_materials.front();
132-
instance->setInstanceCount(visibleCount);
84+
instance->setInstanceCount(static_cast<int32_t>(m_emitterData[VisualEffect::AliveParticles]));
13385

134-
memcpy(instance->rawUniformBuffer().data(), m_quads.data(), sizeof(GpuQuadParticle) * m_quads.size());
86+
memcpy(instance->rawUniformBuffer().data(), m_renderData.data(), m_renderData.size());
13587
}
13688
}
13789
/*!
@@ -143,25 +95,23 @@ Mesh *EffectRender::meshToDraw() const {
14395
/*!
14496
Returns a ParticleEffect assigned to the this component.
14597
*/
146-
ParticleEffect *EffectRender::effect() const {
98+
VisualEffect *EffectRender::effect() const {
14799
return m_effect;
148100
}
149101
/*!
150102
Assgines a particle \a effect to the this component.
151103
*/
152-
void EffectRender::setEffect(ParticleEffect *effect) {
104+
void EffectRender::setEffect(VisualEffect *effect) {
153105
PROFILE_FUNCTION();
154106

155-
if(m_effect != effect) {
156-
if(m_effect) {
157-
m_effect->unsubscribe(this);
158-
}
107+
if(m_effect) {
108+
m_effect->unsubscribe(this);
109+
}
159110

160-
m_effect = effect;
161-
if(m_effect) {
162-
effectUpdated(Resource::Ready, this);
163-
m_effect->subscribe(&EffectRender::effectUpdated, this);
164-
}
111+
m_effect = effect;
112+
if(m_effect) {
113+
effectUpdated(Resource::Ready, this);
114+
m_effect->subscribe(&EffectRender::effectUpdated, this);
165115
}
166116
}
167117
/*!
@@ -197,19 +147,22 @@ void EffectRender::effectUpdated(int state, void *ptr) {
197147
}
198148

199149
// Update emitter buffer
200-
p->m_emitterData.resize(static_cast<int32_t>(EmitterDefaultAttributes::LastAttribute));
150+
p->m_emitterData.resize(VisualEffect::LastAttribute);
201151
// Update particles buffer
202-
p->m_particleData.resize(capacity * p->m_effect->attributeStride());
152+
p->m_particleData.resize(capacity * p->m_effect->particleStride());
203153

204-
p->m_quads.resize(capacity);
154+
int renderableStride = p->m_effect->renderableStride();
155+
p->m_renderData.resize(capacity * renderableStride);
205156

206157
Vector4 colorID(CommandBuffer::idToColor(p->actor()->uuid()));
207158

208159
for(int i = 0; i < capacity; i++) {
209-
p->m_quads[i].worldPosition.w = colorID.x;
210-
p->m_quads[i].sizeRot.w = colorID.y;
211-
p->m_quads[i].uvScaleDist.w = colorID.z;
212-
p->m_quads[i].uvOffset.w = colorID.w;
160+
int r = i * renderableStride;
161+
162+
p->m_renderData[r + 3] = colorID.x;
163+
p->m_renderData[r + 7] = colorID.y;
164+
p->m_renderData[r + 11] = colorID.z;
165+
p->m_renderData[r + 15] = colorID.w;
213166
}
214167
}
215168
}

engine/src/editor/projectsettings.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "config.h"
1717

18+
#include <components/actor.h>
1819
#include <resources/map.h>
1920

2021
#include <editor/pluginmanager.h>
@@ -131,7 +132,7 @@ void ProjectSettings::loadSettings() {
131132
if(index > -1) {
132133
QMetaProperty property = meta->property(index);
133134
if(property.userType() == qMetaTypeId<Template>()) {
134-
value = QVariant::fromValue<Template>(Template(value.toString(), MetaType::type<Actor *>()));
135+
value = QVariant::fromValue(Template(value.toString(), MetaType::name<Actor>()));
135136
}
136137
property.write(this, value);
137138
} else {
@@ -287,7 +288,7 @@ void ProjectSettings::setProjectVersion(const QString &value) {
287288
}
288289

289290
Template ProjectSettings::firstMap() const {
290-
return Template(m_firstMap, MetaType::type<Map *>());
291+
return Template(m_firstMap, MetaType::name<Map>());
291292
}
292293
void ProjectSettings::setFirstMap(const Template &value) {
293294
if(m_firstMap != value.path) {

0 commit comments

Comments
 (0)