summaryrefslogtreecommitdiff
path: root/src/client/particles.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/particles.h')
-rw-r--r--src/client/particles.h70
1 files changed, 59 insertions, 11 deletions
diff --git a/src/client/particles.h b/src/client/particles.h
index 2011f0262..36be903f1 100644
--- a/src/client/particles.h
+++ b/src/client/particles.h
@@ -31,20 +31,53 @@ class ClientEnvironment;
struct MapNode;
struct ContentFeatures;
+struct ClientTexture
+{
+ /* per-spawner structure used to store the ParticleTexture structs
+ * that spawned particles will refer to through ClientTexRef */
+ ParticleTexture tex;
+ video::ITexture *ref = nullptr;
+
+ ClientTexture() = default;
+ ClientTexture(const ClientTexture&) = default;
+ ClientTexture(const ServerParticleTexture& p, ITextureSource *t):
+ tex(p),
+ ref(t->getTextureForMesh(p.string)) {};
+};
+
+struct ClientTexRef
+{
+ /* per-particle structure used to avoid massively duplicating the
+ * fairly large ParticleTexture struct */
+ ParticleTexture* tex = nullptr;
+ video::ITexture* ref = nullptr;
+ ClientTexRef() = default;
+ ClientTexRef(const ClientTexRef&) = default;
+
+ /* constructor used by particles spawned from a spawner */
+ ClientTexRef(ClientTexture& t):
+ tex(&t.tex), ref(t.ref) {};
+
+ /* constructor used for node particles */
+ ClientTexRef(decltype(ref) tp): ref(tp) {};
+};
+
+class ParticleSpawner;
+
class Particle : public scene::ISceneNode
{
- public:
+public:
Particle(
- IGameDef* gamedef,
+ IGameDef *gamedef,
LocalPlayer *player,
ClientEnvironment *env,
const ParticleParameters &p,
- video::ITexture *texture,
+ const ClientTexRef &texture,
v2f texpos,
v2f texsize,
video::SColor color
);
- ~Particle() = default;
+ ~Particle();
virtual const aabb3f &getBoundingBox() const
{
@@ -69,9 +102,12 @@ class Particle : public scene::ISceneNode
bool get_expired ()
{ return m_expiration < m_time; }
+ ParticleSpawner *m_parent;
+
private:
void updateLight();
void updateVertices();
+ void setVertexAlpha(float a);
video::S3DVertex m_vertices[4];
float m_time = 0.0f;
@@ -81,14 +117,19 @@ private:
IGameDef *m_gamedef;
aabb3f m_box;
aabb3f m_collisionbox;
+ ClientTexRef m_texture;
video::SMaterial m_material;
v2f m_texpos;
v2f m_texsize;
v3f m_pos;
v3f m_velocity;
v3f m_acceleration;
+ v3f m_drag;
+ ParticleParamTypes::v3fRange m_jitter;
+ ParticleParamTypes::f32Range m_bounce;
LocalPlayer *m_player;
float m_size;
+
//! Color without lighting
video::SColor m_base_color;
//! Final rendered color
@@ -102,24 +143,27 @@ private:
float m_animation_time = 0.0f;
int m_animation_frame = 0;
u8 m_glow;
+ float m_alpha = 0.0f;
};
class ParticleSpawner
{
public:
- ParticleSpawner(IGameDef* gamedef,
+ ParticleSpawner(IGameDef *gamedef,
LocalPlayer *player,
const ParticleSpawnerParameters &p,
u16 attached_id,
- video::ITexture *texture,
+ std::unique_ptr<ClientTexture[]> &texpool,
+ size_t texcount,
ParticleManager* p_manager);
- ~ParticleSpawner() = default;
-
void step(float dtime, ClientEnvironment *env);
- bool get_expired ()
- { return p.amount <= 0 && p.time != 0; }
+ size_t m_active;
+
+ bool getExpired() const
+ { return m_dying || (p.amount <= 0 && p.time != 0); }
+ void setDying() { m_dying = true; }
private:
void spawnParticle(ClientEnvironment *env, float radius,
@@ -127,10 +171,12 @@ private:
ParticleManager *m_particlemanager;
float m_time;
+ bool m_dying;
IGameDef *m_gamedef;
LocalPlayer *m_player;
ParticleSpawnerParameters p;
- video::ITexture *m_texture;
+ std::unique_ptr<ClientTexture[]> m_texpool;
+ size_t m_texcount;
std::vector<float> m_spawntimes;
u16 m_attached_id;
};
@@ -156,6 +202,8 @@ public:
void addNodeParticle(IGameDef *gamedef, LocalPlayer *player, v3s16 pos,
const MapNode &n, const ContentFeatures &f);
+ void reserveParticleSpace(size_t max_estimate);
+
/**
* This function is only used by client particle spawners
*