1 // SuperTuxKart - a fun racing game with go-kart 2 // Copyright (C) 2017 SuperTuxKart-Team 3 // 4 // This program is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU General Public License 6 // as published by the Free Software Foundation; either version 3 7 // of the License, or (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 #ifndef SERVER_ONLY 19 20 #ifndef HEADER_STK_PARTICLE_HPP 21 #define HEADER_STK_PARTICLE_HPP 22 23 #include "graphics/gl_headers.hpp" 24 #include "../lib/irrlicht/source/Irrlicht/CParticleSystemSceneNode.h" 25 #include <cassert> 26 #include <vector> 27 28 using namespace irr; 29 30 struct CPUParticle; 31 32 class STKParticle : public scene::CParticleSystemSceneNode 33 { 34 private: 35 // ------------------------------------------------------------------------ 36 struct HeightMapData 37 { 38 const std::vector<std::vector<float> > m_array; 39 const float m_x; 40 const float m_z; 41 const float m_x_len; 42 const float m_z_len; 43 // -------------------------------------------------------------------- HeightMapDataSTKParticle::HeightMapData44 HeightMapData(std::vector<std::vector<float> >& array, 45 float track_x, float track_z, float track_x_len, 46 float track_z_len) 47 : m_array(std::move(array)), m_x(track_x), m_z(track_z), 48 m_x_len(track_x_len), m_z_len(track_z_len) {} 49 }; 50 // ------------------------------------------------------------------------ 51 struct ParticleData 52 { 53 core::vector3df m_position; 54 float m_lifetime; 55 core::vector3df m_direction; 56 float m_size; 57 }; 58 // ------------------------------------------------------------------------ 59 HeightMapData* m_hm; 60 61 std::vector<ParticleData> m_particles_generating, m_initial_particles; 62 63 core::vector3df m_color_from, m_color_to; 64 65 float m_size_increase_factor; 66 67 bool m_first_execution, m_randomize_initial_y, m_flips, m_pre_generating; 68 69 /** Previous frame particles emitter source matrix */ 70 core::matrix4 m_previous_frame_matrix; 71 72 /** Maximum count of particles. */ 73 unsigned m_max_count; 74 75 static std::vector<float> m_flips_data; 76 77 static GLuint m_flips_buffer; 78 79 // ------------------------------------------------------------------------ 80 void generateParticlesFromPointEmitter(scene::IParticlePointEmitter*); 81 // ------------------------------------------------------------------------ 82 void generateParticlesFromBoxEmitter(scene::IParticleBoxEmitter*); 83 // ------------------------------------------------------------------------ 84 void generateParticlesFromSphereEmitter(scene::IParticleSphereEmitter*); 85 // ------------------------------------------------------------------------ 86 void stimulateHeightMap(float, unsigned int, std::vector<CPUParticle>*); 87 // ------------------------------------------------------------------------ 88 void stimulateNormal(float, unsigned int, std::vector<CPUParticle>*); 89 90 public: 91 // ------------------------------------------------------------------------ 92 STKParticle(bool randomize_initial_y = false, 93 ISceneNode* parent = 0, s32 id = -1, 94 const core::vector3df& position = core::vector3df(0, 0, 0), 95 const core::vector3df& rotation = core::vector3df(0, 0, 0), 96 const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); 97 // ------------------------------------------------------------------------ ~STKParticle()98 ~STKParticle() 99 { 100 delete m_hm; 101 } 102 // ------------------------------------------------------------------------ setColorFrom(float r,float g,float b)103 void setColorFrom(float r, float g, float b) 104 { 105 m_color_from.X = r; 106 m_color_from.Y = g; 107 m_color_from.Z = b; 108 } 109 // ------------------------------------------------------------------------ setColorTo(float r,float g,float b)110 void setColorTo(float r, float g, float b) 111 { 112 m_color_to.X = r; 113 m_color_to.Y = g; 114 m_color_to.Z = b; 115 } 116 // ------------------------------------------------------------------------ 117 virtual void setEmitter(scene::IParticleEmitter* emitter); 118 // ------------------------------------------------------------------------ 119 virtual void OnRegisterSceneNode(); 120 // ------------------------------------------------------------------------ setIncreaseFactor(float val)121 void setIncreaseFactor(float val) { m_size_increase_factor = val; } 122 // ------------------------------------------------------------------------ setHeightmap(std::vector<std::vector<float>> & array,float track_x,float track_z,float track_x_len,float track_z_len)123 void setHeightmap(std::vector<std::vector<float> >& array, float track_x, 124 float track_z, float track_x_len, float track_z_len) 125 { 126 m_hm = new HeightMapData(array, track_x, track_z, track_x_len, 127 track_z_len); 128 } 129 // ------------------------------------------------------------------------ 130 void generate(std::vector<CPUParticle>* out); 131 // ------------------------------------------------------------------------ setFlips()132 void setFlips() { m_flips = true; } 133 // ------------------------------------------------------------------------ getFlips() const134 bool getFlips() const { return m_flips; } 135 // ------------------------------------------------------------------------ getMaxCount() const136 unsigned getMaxCount() const { return m_max_count; } 137 // ------------------------------------------------------------------------ setPreGenerating(bool val)138 void setPreGenerating(bool val) { m_pre_generating = val; } 139 // ------------------------------------------------------------------------ 140 static void updateFlips(unsigned maximum_particle_count); 141 // ------------------------------------------------------------------------ destroyFlipsBuffer()142 static void destroyFlipsBuffer() 143 { 144 if (m_flips_buffer != 0) 145 { 146 glDeleteBuffers(1, &m_flips_buffer); 147 m_flips_buffer = 0; 148 } 149 m_flips_data.clear(); 150 } 151 // ------------------------------------------------------------------------ getFlipsBuffer()152 static GLuint getFlipsBuffer() 153 { 154 assert(m_flips_buffer != 0); 155 return m_flips_buffer; 156 } 157 }; 158 159 #endif 160 161 #endif // !SERVER_ONLY 162