LCOV - code coverage report
Current view: top level - src - particles.cpp (source / functions) Hit Total Coverage
Test: report Lines: 214 293 73.0 %
Date: 2015-07-11 18:23:49 Functions: 22 27 81.5 %

          Line data    Source code
       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             : #include "particles.h"
      21             : #include "constants.h"
      22             : #include "debug.h"
      23             : #include "settings.h"
      24             : #include "client/tile.h"
      25             : #include "gamedef.h"
      26             : #include "collision.h"
      27             : #include <stdlib.h>
      28             : #include "util/numeric.h"
      29             : #include "light.h"
      30             : #include "environment.h"
      31             : #include "clientmap.h"
      32             : #include "mapnode.h"
      33             : #include "client.h"
      34             : 
      35             : /*
      36             :         Utility
      37             : */
      38             : 
      39         675 : v3f random_v3f(v3f min, v3f max)
      40             : {
      41         675 :         return v3f( rand()/(float)RAND_MAX*(max.X-min.X)+min.X,
      42         675 :                         rand()/(float)RAND_MAX*(max.Y-min.Y)+min.Y,
      43        2025 :                         rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z);
      44             : }
      45             : 
      46         225 : Particle::Particle(
      47             :         IGameDef *gamedef,
      48             :         scene::ISceneManager* smgr,
      49             :         LocalPlayer *player,
      50             :         ClientEnvironment *env,
      51             :         v3f pos,
      52             :         v3f velocity,
      53             :         v3f acceleration,
      54             :         float expirationtime,
      55             :         float size,
      56             :         bool collisiondetection,
      57             :         bool vertical,
      58             :         video::ITexture *texture,
      59             :         v2f texpos,
      60             :         v2f texsize
      61             : ):
      62         225 :         scene::ISceneNode(smgr->getRootSceneNode(), smgr)
      63             : {
      64             :         // Misc
      65         225 :         m_gamedef = gamedef;
      66         225 :         m_env = env;
      67             : 
      68             :         // Texture
      69         225 :         m_material.setFlag(video::EMF_LIGHTING, false);
      70         225 :         m_material.setFlag(video::EMF_BACK_FACE_CULLING, false);
      71         225 :         m_material.setFlag(video::EMF_BILINEAR_FILTER, false);
      72         225 :         m_material.setFlag(video::EMF_FOG_ENABLE, true);
      73         225 :         m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
      74         225 :         m_material.setTexture(0, texture);
      75         225 :         m_texpos = texpos;
      76         225 :         m_texsize = texsize;
      77             : 
      78             : 
      79             :         // Particle related
      80         225 :         m_pos = pos;
      81         225 :         m_velocity = velocity;
      82         225 :         m_acceleration = acceleration;
      83         225 :         m_expiration = expirationtime;
      84         225 :         m_time = 0;
      85         225 :         m_player = player;
      86         225 :         m_size = size;
      87         225 :         m_collisiondetection = collisiondetection;
      88         225 :         m_vertical = vertical;
      89             : 
      90             :         // Irrlicht stuff
      91         450 :         m_collisionbox = core::aabbox3d<f32>
      92         225 :                         (-size/2,-size/2,-size/2,size/2,size/2,size/2);
      93         225 :         this->setAutomaticCulling(scene::EAC_OFF);
      94             : 
      95             :         // Init lighting
      96         225 :         updateLight();
      97             : 
      98             :         // Init model
      99         225 :         updateVertices();
     100         225 : }
     101             : 
     102         450 : Particle::~Particle()
     103             : {
     104         450 : }
     105             : 
     106       30030 : void Particle::OnRegisterSceneNode()
     107             : {
     108       30030 :         if (IsVisible)
     109       30030 :                 SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT_EFFECT);
     110             : 
     111       30030 :         ISceneNode::OnRegisterSceneNode();
     112       30030 : }
     113             : 
     114       30030 : void Particle::render()
     115             : {
     116       30030 :         video::IVideoDriver* driver = SceneManager->getVideoDriver();
     117       30030 :         driver->setMaterial(m_material);
     118       30030 :         driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
     119             : 
     120       30030 :         u16 indices[] = {0,1,2, 2,3,0};
     121       30030 :         driver->drawVertexPrimitiveList(m_vertices, 4,
     122             :                         indices, 2, video::EVT_STANDARD,
     123       60060 :                         scene::EPT_TRIANGLES, video::EIT_16BIT);
     124       30030 : }
     125             : 
     126       29805 : void Particle::step(float dtime)
     127             : {
     128       29805 :         m_time += dtime;
     129       29805 :         if (m_collisiondetection)
     130             :         {
     131           0 :                 core::aabbox3d<f32> box = m_collisionbox;
     132           0 :                 v3f p_pos = m_pos*BS;
     133           0 :                 v3f p_velocity = m_velocity*BS;
     134           0 :                 v3f p_acceleration = m_acceleration*BS;
     135           0 :                 collisionMoveSimple(m_env, m_gamedef,
     136             :                         BS*0.5, box,
     137             :                         0, dtime,
     138           0 :                         p_pos, p_velocity, p_acceleration);
     139           0 :                 m_pos = p_pos/BS;
     140           0 :                 m_velocity = p_velocity/BS;
     141           0 :                 m_acceleration = p_acceleration/BS;
     142             :         }
     143             :         else
     144             :         {
     145       29805 :                 m_velocity += m_acceleration * dtime;
     146       29805 :                 m_pos += m_velocity * dtime;
     147             :         }
     148             : 
     149             :         // Update lighting
     150       29805 :         updateLight();
     151             : 
     152             :         // Update model
     153       29805 :         updateVertices();
     154       29805 : }
     155             : 
     156       30030 : void Particle::updateLight()
     157             : {
     158       30030 :         u8 light = 0;
     159             :         bool pos_ok;
     160             : 
     161             :         v3s16 p = v3s16(
     162       30030 :                 floor(m_pos.X+0.5),
     163       30030 :                 floor(m_pos.Y+0.5),
     164       30030 :                 floor(m_pos.Z+0.5)
     165       90090 :         );
     166       30030 :         MapNode n = m_env->getClientMap().getNodeNoEx(p, &pos_ok);
     167       30030 :         if (pos_ok)
     168       30030 :                 light = n.getLightBlend(m_env->getDayNightRatio(), m_gamedef->ndef());
     169             :         else
     170           0 :                 light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0);
     171             : 
     172       30030 :         m_light = decode_light(light);
     173       30030 : }
     174             : 
     175       30030 : void Particle::updateVertices()
     176             : {
     177       30030 :         video::SColor c(255, m_light, m_light, m_light);
     178       30030 :         f32 tx0 = m_texpos.X;
     179       30030 :         f32 tx1 = m_texpos.X + m_texsize.X;
     180       30030 :         f32 ty0 = m_texpos.Y;
     181       30030 :         f32 ty1 = m_texpos.Y + m_texsize.Y;
     182             : 
     183       60060 :         m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0,
     184       30030 :                         c, tx0, ty1);
     185       60060 :         m_vertices[1] = video::S3DVertex(m_size/2,-m_size/2,0, 0,0,0,
     186       30030 :                         c, tx1, ty1);
     187       60060 :         m_vertices[2] = video::S3DVertex(m_size/2,m_size/2,0, 0,0,0,
     188       30030 :                         c, tx1, ty0);
     189       60060 :         m_vertices[3] = video::S3DVertex(-m_size/2,m_size/2,0, 0,0,0,
     190       30030 :                         c, tx0, ty0);
     191             : 
     192       30030 :         v3s16 camera_offset = m_env->getCameraOffset();
     193      150150 :         for(u16 i=0; i<4; i++)
     194             :         {
     195      120120 :                 if (m_vertical) {
     196      120120 :                         v3f ppos = m_player->getPosition()/BS;
     197      120120 :                         m_vertices[i].Pos.rotateXZBy(atan2(ppos.Z-m_pos.Z, ppos.X-m_pos.X)/core::DEGTORAD+90);
     198             :                 } else {
     199           0 :                         m_vertices[i].Pos.rotateYZBy(m_player->getPitch());
     200           0 :                         m_vertices[i].Pos.rotateXZBy(m_player->getYaw());
     201             :                 }
     202      120120 :                 m_box.addInternalPoint(m_vertices[i].Pos);
     203      120120 :                 m_vertices[i].Pos += m_pos*BS - intToFloat(camera_offset, BS);
     204             :         }
     205       30030 : }
     206             : 
     207             : /*
     208             :         ParticleSpawner
     209             : */
     210             : 
     211           9 : ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, LocalPlayer *player,
     212             :         u16 amount, float time,
     213             :         v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
     214             :         float minexptime, float maxexptime, float minsize, float maxsize,
     215             :         bool collisiondetection, bool vertical, video::ITexture *texture, u32 id,
     216             :         ParticleManager *p_manager) :
     217           9 :         m_particlemanager(p_manager)
     218             : {
     219           9 :         m_gamedef = gamedef;
     220           9 :         m_smgr = smgr;
     221           9 :         m_player = player;
     222           9 :         m_amount = amount;
     223           9 :         m_spawntime = time;
     224           9 :         m_minpos = minpos;
     225           9 :         m_maxpos = maxpos;
     226           9 :         m_minvel = minvel;
     227           9 :         m_maxvel = maxvel;
     228           9 :         m_minacc = minacc;
     229           9 :         m_maxacc = maxacc;
     230           9 :         m_minexptime = minexptime;
     231           9 :         m_maxexptime = maxexptime;
     232           9 :         m_minsize = minsize;
     233           9 :         m_maxsize = maxsize;
     234           9 :         m_collisiondetection = collisiondetection;
     235           9 :         m_vertical = vertical;
     236           9 :         m_texture = texture;
     237           9 :         m_time = 0;
     238             : 
     239         288 :         for (u16 i = 0; i<=m_amount; i++)
     240             :         {
     241         279 :                 float spawntime = (float)rand()/(float)RAND_MAX*m_spawntime;
     242         279 :                 m_spawntimes.push_back(spawntime);
     243             :         }
     244           9 : }
     245             : 
     246           9 : ParticleSpawner::~ParticleSpawner() {}
     247             : 
     248        7970 : void ParticleSpawner::step(float dtime, ClientEnvironment* env)
     249             : {
     250        7970 :         m_time += dtime;
     251             : 
     252        7970 :         if (m_spawntime != 0) // Spawner exists for a predefined timespan
     253             :         {
     254      489051 :                 for(std::vector<float>::iterator i = m_spawntimes.begin();
     255      326034 :                                 i != m_spawntimes.end();)
     256             :                 {
     257      155047 :                         if ((*i) <= m_time && m_amount > 0)
     258             :                         {
     259         225 :                                 m_amount--;
     260             : 
     261         225 :                                 v3f pos = random_v3f(m_minpos, m_maxpos);
     262         225 :                                 v3f vel = random_v3f(m_minvel, m_maxvel);
     263         225 :                                 v3f acc = random_v3f(m_minacc, m_maxacc);
     264         225 :                                 float exptime = rand()/(float)RAND_MAX
     265         225 :                                                 *(m_maxexptime-m_minexptime)
     266         225 :                                                 +m_minexptime;
     267         225 :                                 float size = rand()/(float)RAND_MAX
     268         225 :                                                 *(m_maxsize-m_minsize)
     269         225 :                                                 +m_minsize;
     270             : 
     271             :                                 Particle* toadd = new Particle(
     272             :                                         m_gamedef,
     273             :                                         m_smgr,
     274             :                                         m_player,
     275             :                                         env,
     276             :                                         pos,
     277             :                                         vel,
     278             :                                         acc,
     279             :                                         exptime,
     280             :                                         size,
     281         225 :                                         m_collisiondetection,
     282         225 :                                         m_vertical,
     283             :                                         m_texture,
     284             :                                         v2f(0.0, 0.0),
     285         675 :                                         v2f(1.0, 1.0));
     286         225 :                                 m_particlemanager->addParticle(toadd);
     287         225 :                                 i = m_spawntimes.erase(i);
     288             :                         }
     289             :                         else
     290             :                         {
     291      154822 :                                 i++;
     292             :                         }
     293             :                 }
     294             :         }
     295             :         else // Spawner exists for an infinity timespan, spawn on a per-second base
     296             :         {
     297           0 :                 for (int i = 0; i <= m_amount; i++)
     298             :                 {
     299           0 :                         if (rand()/(float)RAND_MAX < dtime)
     300             :                         {
     301           0 :                                 v3f pos = random_v3f(m_minpos, m_maxpos);
     302           0 :                                 v3f vel = random_v3f(m_minvel, m_maxvel);
     303           0 :                                 v3f acc = random_v3f(m_minacc, m_maxacc);
     304           0 :                                 float exptime = rand()/(float)RAND_MAX
     305           0 :                                                 *(m_maxexptime-m_minexptime)
     306           0 :                                                 +m_minexptime;
     307           0 :                                 float size = rand()/(float)RAND_MAX
     308           0 :                                                 *(m_maxsize-m_minsize)
     309           0 :                                                 +m_minsize;
     310             : 
     311             :                                 Particle* toadd = new Particle(
     312             :                                         m_gamedef,
     313             :                                         m_smgr,
     314             :                                         m_player,
     315             :                                         env,
     316             :                                         pos,
     317             :                                         vel,
     318             :                                         acc,
     319             :                                         exptime,
     320             :                                         size,
     321           0 :                                         m_collisiondetection,
     322           0 :                                         m_vertical,
     323             :                                         m_texture,
     324             :                                         v2f(0.0, 0.0),
     325           0 :                                         v2f(1.0, 1.0));
     326           0 :                                 m_particlemanager->addParticle(toadd);
     327             :                         }
     328             :                 }
     329             :         }
     330        7970 : }
     331             : 
     332             : 
     333           1 : ParticleManager::ParticleManager(ClientEnvironment* env) :
     334           1 :         m_env(env)
     335           1 : {}
     336             : 
     337           2 : ParticleManager::~ParticleManager()
     338             : {
     339           1 :         clearAll();
     340           1 : }
     341             : 
     342        1166 : void ParticleManager::step(float dtime)
     343             : {
     344        1166 :         stepParticles (dtime);
     345        1166 :         stepSpawners (dtime);
     346        1166 : }
     347             : 
     348        1166 : void ParticleManager::stepSpawners (float dtime)
     349             : {
     350        2332 :         JMutexAutoLock lock(m_spawner_list_lock);
     351       26260 :         for(std::map<u32, ParticleSpawner*>::iterator i = 
     352        1166 :                         m_particle_spawners.begin();
     353       18284 :                         i != m_particle_spawners.end();)
     354             :         {
     355        7976 :                 if (i->second->get_expired())
     356             :                 {
     357           6 :                         delete i->second;
     358           6 :                         m_particle_spawners.erase(i++);
     359             :                 }
     360             :                 else
     361             :                 {
     362        7970 :                         i->second->step(dtime, m_env);
     363        7970 :                         i++;
     364             :                 }
     365             :         }
     366        1166 : }
     367             : 
     368        1166 : void ParticleManager::stepParticles (float dtime)
     369             : {
     370        2332 :         JMutexAutoLock lock(m_particle_list_lock);
     371       93504 :         for(std::vector<Particle*>::iterator i = m_particles.begin();
     372       62336 :                         i != m_particles.end();)
     373             :         {
     374       30002 :                 if ((*i)->get_expired())
     375             :                 {
     376         197 :                         (*i)->remove();
     377         197 :                         delete *i;
     378         197 :                         i = m_particles.erase(i);
     379             :                 }
     380             :                 else
     381             :                 {
     382       29805 :                         (*i)->step(dtime);
     383       29805 :                         i++;
     384             :                 }
     385             :         }
     386        1166 : }
     387             : 
     388           1 : void ParticleManager::clearAll ()
     389             : {
     390           2 :         JMutexAutoLock lock(m_spawner_list_lock);
     391           2 :         JMutexAutoLock lock2(m_particle_list_lock);
     392          11 :         for(std::map<u32, ParticleSpawner*>::iterator i =
     393           1 :                         m_particle_spawners.begin();
     394           8 :                         i != m_particle_spawners.end();)
     395             :         {
     396           3 :                 delete i->second;
     397           3 :                 m_particle_spawners.erase(i++);
     398             :         }
     399             : 
     400          86 :         for(std::vector<Particle*>::iterator i =
     401           1 :                         m_particles.begin();
     402          58 :                         i != m_particles.end();)
     403             :         {
     404          28 :                 (*i)->remove();
     405          28 :                 delete *i;
     406          28 :                 i = m_particles.erase(i);
     407             :         }
     408           1 : }
     409             : 
     410           9 : void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
     411             :                 scene::ISceneManager* smgr, LocalPlayer *player)
     412             : {
     413           9 :         if (event->type == CE_DELETE_PARTICLESPAWNER) {
     414           0 :                 JMutexAutoLock lock(m_spawner_list_lock);
     415           0 :                 if (m_particle_spawners.find(event->delete_particlespawner.id) !=
     416           0 :                                 m_particle_spawners.end())
     417             :                 {
     418           0 :                         delete m_particle_spawners.find(event->delete_particlespawner.id)->second;
     419           0 :                         m_particle_spawners.erase(event->delete_particlespawner.id);
     420             :                 }
     421             :                 // no allocated memory in delete event
     422           0 :                 return;
     423             :         }
     424             : 
     425           9 :         if (event->type == CE_ADD_PARTICLESPAWNER) {
     426             : 
     427             :                 {
     428          18 :                         JMutexAutoLock lock(m_spawner_list_lock);
     429          18 :                         if (m_particle_spawners.find(event->add_particlespawner.id) !=
     430          18 :                                                         m_particle_spawners.end())
     431             :                         {
     432           0 :                                 delete m_particle_spawners.find(event->add_particlespawner.id)->second;
     433           0 :                                 m_particle_spawners.erase(event->add_particlespawner.id);
     434             :                         }
     435             :                 }
     436             :                 video::ITexture *texture =
     437           9 :                         gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture));
     438             : 
     439             :                 ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player,
     440           9 :                                 event->add_particlespawner.amount,
     441             :                                 event->add_particlespawner.spawntime,
     442           9 :                                 *event->add_particlespawner.minpos,
     443           9 :                                 *event->add_particlespawner.maxpos,
     444           9 :                                 *event->add_particlespawner.minvel,
     445           9 :                                 *event->add_particlespawner.maxvel,
     446           9 :                                 *event->add_particlespawner.minacc,
     447           9 :                                 *event->add_particlespawner.maxacc,
     448             :                                 event->add_particlespawner.minexptime,
     449             :                                 event->add_particlespawner.maxexptime,
     450             :                                 event->add_particlespawner.minsize,
     451             :                                 event->add_particlespawner.maxsize,
     452           9 :                                 event->add_particlespawner.collisiondetection,
     453           9 :                                 event->add_particlespawner.vertical,
     454             :                                 texture,
     455             :                                 event->add_particlespawner.id,
     456          81 :                                 this);
     457             : 
     458             :                 /* delete allocated content of event */
     459           9 :                 delete event->add_particlespawner.minpos;
     460           9 :                 delete event->add_particlespawner.maxpos;
     461           9 :                 delete event->add_particlespawner.minvel;
     462           9 :                 delete event->add_particlespawner.maxvel;
     463           9 :                 delete event->add_particlespawner.minacc;
     464           9 :                 delete event->add_particlespawner.texture;
     465           9 :                 delete event->add_particlespawner.maxacc;
     466             : 
     467             :                 {
     468          18 :                         JMutexAutoLock lock(m_spawner_list_lock);
     469             :                         m_particle_spawners.insert(
     470             :                                         std::pair<u32, ParticleSpawner*>(
     471             :                                                         event->add_particlespawner.id,
     472           9 :                                                         toadd));
     473             :                 }
     474             : 
     475           9 :                 return;
     476             :         }
     477             : 
     478           0 :         if (event->type == CE_SPAWN_PARTICLE) {
     479             :                 video::ITexture *texture =
     480           0 :                         gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture));
     481             : 
     482             :                 Particle* toadd = new Particle(gamedef, smgr, player, m_env,
     483           0 :                                 *event->spawn_particle.pos,
     484           0 :                                 *event->spawn_particle.vel,
     485           0 :                                 *event->spawn_particle.acc,
     486             :                                 event->spawn_particle.expirationtime,
     487             :                                 event->spawn_particle.size,
     488           0 :                                 event->spawn_particle.collisiondetection,
     489           0 :                                 event->spawn_particle.vertical,
     490             :                                 texture,
     491             :                                 v2f(0.0, 0.0),
     492           0 :                                 v2f(1.0, 1.0));
     493             : 
     494           0 :                 addParticle(toadd);
     495             : 
     496           0 :                 delete event->spawn_particle.pos;
     497           0 :                 delete event->spawn_particle.vel;
     498           0 :                 delete event->spawn_particle.acc;
     499             : 
     500           0 :                 return;
     501             :         }
     502             : }
     503             : 
     504           0 : void ParticleManager::addDiggingParticles(IGameDef* gamedef, scene::ISceneManager* smgr,
     505             :                 LocalPlayer *player, v3s16 pos, const TileSpec tiles[])
     506             : {
     507           0 :         for (u16 j = 0; j < 32; j++) // set the amount of particles here
     508             :         {
     509           0 :                 addNodeParticle(gamedef, smgr, player, pos, tiles);
     510             :         }
     511           0 : }
     512             : 
     513           0 : void ParticleManager::addPunchingParticles(IGameDef* gamedef, scene::ISceneManager* smgr,
     514             :                 LocalPlayer *player, v3s16 pos, const TileSpec tiles[])
     515             : {
     516           0 :         addNodeParticle(gamedef, smgr, player, pos, tiles);
     517           0 : }
     518             : 
     519           0 : void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr,
     520             :                 LocalPlayer *player, v3s16 pos, const TileSpec tiles[])
     521             : {
     522             :         // Texture
     523           0 :         u8 texid = myrand_range(0, 5);
     524           0 :         video::ITexture *texture = tiles[texid].texture;
     525             : 
     526             :         // Only use first frame of animated texture
     527           0 :         f32 ymax = 1;
     528           0 :         if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
     529           0 :                 ymax /= tiles[texid].animation_frame_count;
     530             : 
     531           0 :         float size = rand() % 64 / 512.;
     532           0 :         float visual_size = BS * size;
     533           0 :         v2f texsize(size * 2, ymax * size * 2);
     534           0 :         v2f texpos;
     535           0 :         texpos.X = ((rand() % 64) / 64. - texsize.X);
     536           0 :         texpos.Y = ymax * ((rand() % 64) / 64. - texsize.Y);
     537             : 
     538             :         // Physics
     539           0 :         v3f velocity((rand() % 100 / 50. - 1) / 1.5,
     540           0 :                         rand() % 100 / 35.,
     541           0 :                         (rand() % 100 / 50. - 1) / 1.5);
     542             : 
     543           0 :         v3f acceleration(0,-9,0);
     544             :         v3f particlepos = v3f(
     545           0 :                 (f32) pos.X + rand() %100 /200. - 0.25,
     546           0 :                 (f32) pos.Y + rand() %100 /200. - 0.25,
     547           0 :                 (f32) pos.Z + rand() %100 /200. - 0.25
     548           0 :         );
     549             : 
     550             :         Particle* toadd = new Particle(
     551             :                 gamedef,
     552             :                 smgr,
     553             :                 player,
     554             :                 m_env,
     555             :                 particlepos,
     556             :                 velocity,
     557             :                 acceleration,
     558           0 :                 rand() % 100 / 100., // expiration time
     559             :                 visual_size,
     560             :                 true,
     561             :                 false,
     562             :                 texture,
     563             :                 texpos,
     564           0 :                 texsize);
     565             : 
     566           0 :         addParticle(toadd);
     567           0 : }
     568             : 
     569         225 : void ParticleManager::addParticle(Particle* toadd)
     570             : {
     571         450 :         JMutexAutoLock lock(m_particle_list_lock);
     572         225 :         m_particles.push_back(toadd);
     573         228 : }

Generated by: LCOV version 1.11