]> git.lizzy.rs Git - minetest.git/blob - src/particles.h
[CSM] Add functions to create particles and particlespawners. (#6072)
[minetest.git] / src / particles.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #pragma once
21
22 #include <iostream>
23 #include "irrlichttypes_extrabloated.h"
24 #include "client/tile.h"
25 #include "localplayer.h"
26 #include "tileanimation.h"
27
28 struct ClientEvent;
29 class ParticleManager;
30 class ClientEnvironment;
31 struct MapNode;
32 struct ContentFeatures;
33
34 class Particle : public scene::ISceneNode
35 {
36         public:
37         Particle(
38                 IGameDef* gamedef,
39                 LocalPlayer *player,
40                 ClientEnvironment *env,
41                 v3f pos,
42                 v3f velocity,
43                 v3f acceleration,
44                 float expirationtime,
45                 float size,
46                 bool collisiondetection,
47                 bool collision_removal,
48                 bool vertical,
49                 video::ITexture *texture,
50                 v2f texpos,
51                 v2f texsize,
52                 const struct TileAnimationParams &anim,
53                 u8 glow,
54                 video::SColor color = video::SColor(0xFFFFFFFF)
55         );
56         ~Particle() = default;
57
58         virtual const aabb3f &getBoundingBox() const
59         {
60                 return m_box;
61         }
62
63         virtual u32 getMaterialCount() const
64         {
65                 return 1;
66         }
67
68         virtual video::SMaterial& getMaterial(u32 i)
69         {
70                 return m_material;
71         }
72
73         virtual void OnRegisterSceneNode();
74         virtual void render();
75
76         void step(float dtime);
77
78         bool get_expired ()
79         { return m_expiration < m_time; }
80
81 private:
82         void updateLight();
83         void updateVertices();
84
85         video::S3DVertex m_vertices[4];
86         float m_time = 0.0f;
87         float m_expiration;
88
89         ClientEnvironment *m_env;
90         IGameDef *m_gamedef;
91         aabb3f m_box;
92         aabb3f m_collisionbox;
93         video::SMaterial m_material;
94         v2f m_texpos;
95         v2f m_texsize;
96         v3f m_pos;
97         v3f m_velocity;
98         v3f m_acceleration;
99         LocalPlayer *m_player;
100         float m_size;
101         //! Color without lighting
102         video::SColor m_base_color;
103         //! Final rendered color
104         video::SColor m_color;
105         bool m_collisiondetection;
106         bool m_collision_removal;
107         bool m_vertical;
108         v3s16 m_camera_offset;
109         struct TileAnimationParams m_animation;
110         float m_animation_time = 0.0f;
111         int m_animation_frame = 0;
112         u8 m_glow;
113 };
114
115 class ParticleSpawner
116 {
117 public:
118         ParticleSpawner(IGameDef* gamedef,
119                 LocalPlayer *player,
120                 u16 amount,
121                 float time,
122                 v3f minp, v3f maxp,
123                 v3f minvel, v3f maxvel,
124                 v3f minacc, v3f maxacc,
125                 float minexptime, float maxexptime,
126                 float minsize, float maxsize,
127                 bool collisiondetection,
128                 bool collision_removal,
129                 u16 attached_id,
130                 bool vertical,
131                 video::ITexture *texture,
132                 u32 id,
133                 const struct TileAnimationParams &anim, u8 glow,
134                 ParticleManager* p_manager);
135
136         ~ParticleSpawner() = default;
137
138         void step(float dtime, ClientEnvironment *env);
139
140         bool get_expired ()
141         { return (m_amount <= 0) && m_spawntime != 0; }
142
143 private:
144         void spawnParticle(ClientEnvironment *env, float radius,
145                         bool is_attached, const v3f &attached_pos,
146                         float attached_yaw);
147
148         ParticleManager *m_particlemanager;
149         float m_time;
150         IGameDef *m_gamedef;
151         LocalPlayer *m_player;
152         u16 m_amount;
153         float m_spawntime;
154         v3f m_minpos;
155         v3f m_maxpos;
156         v3f m_minvel;
157         v3f m_maxvel;
158         v3f m_minacc;
159         v3f m_maxacc;
160         float m_minexptime;
161         float m_maxexptime;
162         float m_minsize;
163         float m_maxsize;
164         video::ITexture *m_texture;
165         std::vector<float> m_spawntimes;
166         bool m_collisiondetection;
167         bool m_collision_removal;
168         bool m_vertical;
169         u16 m_attached_id;
170         struct TileAnimationParams m_animation;
171         u8 m_glow;
172 };
173
174 /**
175  * Class doing particle as well as their spawners handling
176  */
177 class ParticleManager
178 {
179 friend class ParticleSpawner;
180 public:
181         ParticleManager(ClientEnvironment* env);
182         ~ParticleManager();
183
184         void step (float dtime);
185
186         void handleParticleEvent(ClientEvent *event, Client *client,
187                         LocalPlayer *player);
188
189         void addDiggingParticles(IGameDef *gamedef, LocalPlayer *player, v3s16 pos,
190                 const MapNode &n, const ContentFeatures &f);
191
192         void addNodeParticle(IGameDef *gamedef, LocalPlayer *player, v3s16 pos,
193                 const MapNode &n, const ContentFeatures &f);
194
195         u32 getSpawnerId() const
196         {
197                 for (u32 id = 0;; ++id) { // look for unused particlespawner id
198                         if (m_particle_spawners.find(id) == m_particle_spawners.end())
199                                 return id;
200                 }
201         }
202
203 protected:
204         void addParticle(Particle* toadd);
205
206 private:
207
208         void stepParticles (float dtime);
209         void stepSpawners (float dtime);
210
211         void clearAll ();
212
213         std::vector<Particle*> m_particles;
214         std::map<u32, ParticleSpawner*> m_particle_spawners;
215
216         ClientEnvironment* m_env;
217         std::mutex m_particle_list_lock;
218         std::mutex m_spawner_list_lock;
219 };