@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
21
21
#include < cmath>
22
22
#include " client.h"
23
23
#include " collision.h"
24
+ #include " client/content_cao.h"
24
25
#include " client/clientevent.h"
25
26
#include " client/renderingengine.h"
26
27
#include " util/numeric.h"
@@ -38,9 +39,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
38
39
39
40
v3f random_v3f (v3f min, v3f max)
40
41
{
41
- return v3f ( rand ()/(float )RAND_MAX*(max.X -min.X )+min.X ,
42
- rand ()/(float )RAND_MAX*(max.Y -min.Y )+min.Y ,
43
- rand ()/(float )RAND_MAX*(max.Z -min.Z )+min.Z );
42
+ return v3f (
43
+ rand () / (float )RAND_MAX * (max.X - min.X ) + min.X ,
44
+ rand () / (float )RAND_MAX * (max.Y - min.Y ) + min.Y ,
45
+ rand () / (float )RAND_MAX * (max.Z - min.Z ) + min.Z );
44
46
}
45
47
46
48
Particle::Particle (
@@ -299,16 +301,21 @@ ParticleSpawner::ParticleSpawner(
299
301
}
300
302
301
303
void ParticleSpawner::spawnParticle (ClientEnvironment *env, float radius,
302
- bool is_attached, const v3f &attached_pos, float attached_yaw )
304
+ const core::matrix4 *attached_absolute_pos_rot_matrix )
303
305
{
304
306
v3f ppos = m_player->getPosition () / BS;
305
307
v3f pos = random_v3f (m_minpos, m_maxpos);
306
308
307
309
// Need to apply this first or the following check
308
310
// will be wrong for attached spawners
309
- if (is_attached) {
310
- pos.rotateXZBy (attached_yaw);
311
- pos += attached_pos;
311
+ if (attached_absolute_pos_rot_matrix) {
312
+ pos *= BS;
313
+ attached_absolute_pos_rot_matrix->transformVect (pos);
314
+ pos /= BS;
315
+ v3s16 camera_offset = m_particlemanager->m_env ->getCameraOffset ();
316
+ pos.X += camera_offset.X ;
317
+ pos.Y += camera_offset.Y ;
318
+ pos.Z += camera_offset.Z ;
312
319
}
313
320
314
321
if (pos.getDistanceFrom (ppos) > radius)
@@ -317,18 +324,19 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius,
317
324
v3f vel = random_v3f (m_minvel, m_maxvel);
318
325
v3f acc = random_v3f (m_minacc, m_maxacc);
319
326
320
- if (is_attached ) {
321
- // Apply attachment yaw
322
- vel. rotateXZBy (attached_yaw );
323
- acc. rotateXZBy (attached_yaw );
327
+ if (attached_absolute_pos_rot_matrix ) {
328
+ // Apply attachment rotation
329
+ attached_absolute_pos_rot_matrix-> rotateVect (vel );
330
+ attached_absolute_pos_rot_matrix-> rotateVect (acc );
324
331
}
325
332
326
333
float exptime = rand () / (float )RAND_MAX
327
- * (m_maxexptime - m_minexptime)
328
- + m_minexptime;
334
+ * (m_maxexptime - m_minexptime)
335
+ + m_minexptime;
336
+
329
337
float size = rand () / (float )RAND_MAX
330
- * (m_maxsize - m_minsize)
331
- + m_minsize;
338
+ * (m_maxsize - m_minsize)
339
+ + m_minsize;
332
340
333
341
m_particlemanager->addParticle (new Particle (
334
342
m_gamedef,
@@ -359,14 +367,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
359
367
g_settings->getS16 (" max_block_send_distance" ) * MAP_BLOCKSIZE;
360
368
361
369
bool unloaded = false ;
362
- bool is_attached = false ;
363
- v3f attached_pos = v3f (0 ,0 ,0 );
364
- float attached_yaw = 0 ;
365
- if (m_attached_id != 0 ) {
366
- if (ClientActiveObject *attached = env->getActiveObject (m_attached_id)) {
367
- attached_pos = attached->getPosition () / BS;
368
- attached_yaw = attached->getYaw ();
369
- is_attached = true ;
370
+ const core::matrix4 *attached_absolute_pos_rot_matrix = nullptr ;
371
+ if (m_attached_id) {
372
+ if (GenericCAO *attached = dynamic_cast <GenericCAO *>(env->getActiveObject (m_attached_id))) {
373
+ attached_absolute_pos_rot_matrix = &attached->getAbsolutePosRotMatrix ();
370
374
} else {
371
375
unloaded = true ;
372
376
}
@@ -382,7 +386,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
382
386
// Pretend to, but don't actually spawn a particle if it is
383
387
// attached to an unloaded object or distant from player.
384
388
if (!unloaded)
385
- spawnParticle (env, radius, is_attached, attached_pos, attached_yaw );
389
+ spawnParticle (env, radius, attached_absolute_pos_rot_matrix );
386
390
387
391
i = m_spawntimes.erase (i);
388
392
} else {
@@ -398,7 +402,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
398
402
399
403
for (int i = 0 ; i <= m_amount; i++) {
400
404
if (rand () / (float )RAND_MAX < dtime)
401
- spawnParticle (env, radius, is_attached, attached_pos, attached_yaw );
405
+ spawnParticle (env, radius, attached_absolute_pos_rot_matrix );
402
406
}
403
407
}
404
408
}
@@ -419,7 +423,7 @@ void ParticleManager::step(float dtime)
419
423
stepSpawners (dtime);
420
424
}
421
425
422
- void ParticleManager::stepSpawners (float dtime)
426
+ void ParticleManager::stepSpawners (float dtime)
423
427
{
424
428
MutexAutoLock lock (m_spawner_list_lock);
425
429
for (auto i = m_particle_spawners.begin (); i != m_particle_spawners.end ();) {
@@ -433,7 +437,7 @@ void ParticleManager::stepSpawners (float dtime)
433
437
}
434
438
}
435
439
436
- void ParticleManager::stepParticles (float dtime)
440
+ void ParticleManager::stepParticles (float dtime)
437
441
{
438
442
MutexAutoLock lock (m_particle_list_lock);
439
443
for (auto i = m_particles.begin (); i != m_particles.end ();) {
@@ -448,7 +452,7 @@ void ParticleManager::stepParticles (float dtime)
448
452
}
449
453
}
450
454
451
- void ParticleManager::clearAll ()
455
+ void ParticleManager::clearAll ()
452
456
{
453
457
MutexAutoLock lock (m_spawner_list_lock);
454
458
MutexAutoLock lock2 (m_particle_list_lock);
@@ -457,9 +461,7 @@ void ParticleManager::clearAll ()
457
461
m_particle_spawners.erase (i++);
458
462
}
459
463
460
- for (std::vector<Particle*>::iterator i =
461
- m_particles.begin ();
462
- i != m_particles.end ();)
464
+ for (auto i = m_particles.begin (); i != m_particles.end ();)
463
465
{
464
466
(*i)->remove ();
465
467
delete *i;
0 commit comments