3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "irrlichttypes_extrabloated.h"
24 #include "client/tile.h"
25 #include "localplayer.h"
26 #include "../particles.h"
29 class ParticleManager;
30 class ClientEnvironment;
32 struct ContentFeatures;
36 /* per-spawner structure used to store the ParticleTexture structs
37 * that spawned particles will refer to through ClientTexRef */
39 video::ITexture *ref = nullptr;
41 ClientTexture() = default;
42 ClientTexture(const ServerParticleTexture& p, ITextureSource *t):
44 ref(t->getTextureForMesh(p.string)) {};
49 /* per-particle structure used to avoid massively duplicating the
50 * fairly large ParticleTexture struct */
51 ParticleTexture* tex = nullptr;
52 video::ITexture* ref = nullptr;
53 ClientTexRef() = default;
55 /* constructor used by particles spawned from a spawner */
56 ClientTexRef(ClientTexture& t):
57 tex(&t.tex), ref(t.ref) {};
59 /* constructor used for node particles */
60 ClientTexRef(decltype(ref) tp): ref(tp) {};
63 class ParticleSpawner;
65 class Particle : public scene::ISceneNode
71 ClientEnvironment *env,
72 const ParticleParameters &p,
73 const ClientTexRef &texture,
80 virtual const aabb3f &getBoundingBox() const
85 virtual u32 getMaterialCount() const
90 virtual video::SMaterial& getMaterial(u32 i)
95 virtual void OnRegisterSceneNode();
96 virtual void render();
98 void step(float dtime);
101 { return m_expiration < m_time; }
103 ParticleSpawner *m_parent;
107 void updateVertices();
108 void setVertexAlpha(float a);
110 video::S3DVertex m_vertices[4];
114 ClientEnvironment *m_env;
117 aabb3f m_collisionbox;
118 ClientTexRef m_texture;
119 video::SMaterial m_material;
126 ParticleParamTypes::v3fRange m_jitter;
127 ParticleParamTypes::f32Range m_bounce;
128 LocalPlayer *m_player;
131 //! Color without lighting
132 video::SColor m_base_color;
133 //! Final rendered color
134 video::SColor m_color;
135 bool m_collisiondetection;
136 bool m_collision_removal;
137 bool m_object_collision;
139 v3s16 m_camera_offset;
140 struct TileAnimationParams m_animation;
141 float m_animation_time = 0.0f;
142 int m_animation_frame = 0;
144 float m_alpha = 0.0f;
147 class ParticleSpawner
150 ParticleSpawner(IGameDef *gamedef,
152 const ParticleSpawnerParameters &p,
154 std::unique_ptr<ClientTexture[]> &texpool,
156 ParticleManager* p_manager);
158 void step(float dtime, ClientEnvironment *env);
162 bool getExpired() const
163 { return m_dying || (p.amount <= 0 && p.time != 0); }
164 void setDying() { m_dying = true; }
167 void spawnParticle(ClientEnvironment *env, float radius,
168 const core::matrix4 *attached_absolute_pos_rot_matrix);
170 ParticleManager *m_particlemanager;
174 LocalPlayer *m_player;
175 ParticleSpawnerParameters p;
176 std::unique_ptr<ClientTexture[]> m_texpool;
178 std::vector<float> m_spawntimes;
183 * Class doing particle as well as their spawners handling
185 class ParticleManager
187 friend class ParticleSpawner;
189 ParticleManager(ClientEnvironment* env);
192 void step (float dtime);
194 void handleParticleEvent(ClientEvent *event, Client *client,
195 LocalPlayer *player);
197 void addDiggingParticles(IGameDef *gamedef, LocalPlayer *player, v3s16 pos,
198 const MapNode &n, const ContentFeatures &f);
200 void addNodeParticle(IGameDef *gamedef, LocalPlayer *player, v3s16 pos,
201 const MapNode &n, const ContentFeatures &f);
203 void reserveParticleSpace(size_t max_estimate);
206 * This function is only used by client particle spawners
208 * We don't need to check the particle spawner list because client ID will
209 * never overlap (u64)
212 u64 generateSpawnerId()
214 return m_next_particle_spawner_id++;
218 static bool getNodeParticleParams(const MapNode &n, const ContentFeatures &f,
219 ParticleParameters &p, video::ITexture **texture, v2f &texpos,
220 v2f &texsize, video::SColor *color, u8 tilenum = 0);
222 void addParticle(Particle* toadd);
225 void addParticleSpawner(u64 id, ParticleSpawner *toadd);
226 void deleteParticleSpawner(u64 id);
228 void stepParticles(float dtime);
229 void stepSpawners(float dtime);
233 std::vector<Particle*> m_particles;
234 std::unordered_map<u64, ParticleSpawner*> m_particle_spawners;
235 // Start the particle spawner ids generated from here after u32_max. lower values are
236 // for server sent spawners.
237 u64 m_next_particle_spawner_id = U32_MAX + 1;
239 ClientEnvironment* m_env;
240 std::mutex m_particle_list_lock;
241 std::mutex m_spawner_list_lock;