Skip to content

Commit 60baf81

Browse files
paramatnerzhul
authored andcommittedMay 20, 2017
Particle spawner: Do not spawn particles distant from player (#5766)
Previously, every particle was rendered by (even if not actually visible to) the client regardless of distance. This significantly reduced client FPS. Acts clientside, particle spawners are always sent to clients, but each particle is checked for distance from the player. As with 'add particle' the distance limit is set to 'max block send distance' as this determines how far a client can see.
1 parent af2f025 commit 60baf81

File tree

1 file changed

+70
-58
lines changed

1 file changed

+70
-58
lines changed
 

Diff for: ‎src/particles.cpp

+70-58
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2727
#include "clientmap.h"
2828
#include "mapnode.h"
2929
#include "client.h"
30+
#include "settings.h"
3031

3132
/*
3233
Utility
@@ -293,6 +294,9 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
293294
{
294295
m_time += dtime;
295296

297+
static const float radius =
298+
g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE;
299+
296300
bool unloaded = false;
297301
bool is_attached = false;
298302
v3f attached_pos = v3f(0,0,0);
@@ -316,11 +320,74 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
316320
{
317321
m_amount--;
318322

319-
// Pretend to, but don't actually spawn a
320-
// particle if it is attached to an unloaded
321-
// object.
323+
// Pretend to, but don't actually spawn a particle if it is
324+
// attached to an unloaded object or distant from player.
322325
if (!unloaded) {
326+
v3f ppos = m_player->getPosition() / BS;
323327
v3f pos = random_v3f(m_minpos, m_maxpos);
328+
329+
if (pos.getDistanceFrom(ppos) <= radius) {
330+
v3f vel = random_v3f(m_minvel, m_maxvel);
331+
v3f acc = random_v3f(m_minacc, m_maxacc);
332+
333+
if (is_attached) {
334+
// Apply attachment yaw and position
335+
pos.rotateXZBy(attached_yaw);
336+
pos += attached_pos;
337+
vel.rotateXZBy(attached_yaw);
338+
acc.rotateXZBy(attached_yaw);
339+
}
340+
341+
float exptime = rand()/(float)RAND_MAX
342+
*(m_maxexptime-m_minexptime)
343+
+m_minexptime;
344+
float size = rand()/(float)RAND_MAX
345+
*(m_maxsize-m_minsize)
346+
+m_minsize;
347+
348+
Particle* toadd = new Particle(
349+
m_gamedef,
350+
m_smgr,
351+
m_player,
352+
env,
353+
pos,
354+
vel,
355+
acc,
356+
exptime,
357+
size,
358+
m_collisiondetection,
359+
m_collision_removal,
360+
m_vertical,
361+
m_texture,
362+
v2f(0.0, 0.0),
363+
v2f(1.0, 1.0),
364+
m_animation,
365+
m_glow);
366+
m_particlemanager->addParticle(toadd);
367+
}
368+
}
369+
i = m_spawntimes.erase(i);
370+
}
371+
else
372+
{
373+
++i;
374+
}
375+
}
376+
}
377+
else // Spawner exists for an infinity timespan, spawn on a per-second base
378+
{
379+
// Skip this step if attached to an unloaded object
380+
if (unloaded)
381+
return;
382+
for (int i = 0; i <= m_amount; i++)
383+
{
384+
if (rand()/(float)RAND_MAX < dtime)
385+
{
386+
// Do not spawn particle if distant from player
387+
v3f ppos = m_player->getPosition() / BS;
388+
v3f pos = random_v3f(m_minpos, m_maxpos);
389+
390+
if (pos.getDistanceFrom(ppos) <= radius) {
324391
v3f vel = random_v3f(m_minvel, m_maxvel);
325392
v3f acc = random_v3f(m_minacc, m_maxacc);
326393

@@ -359,61 +426,6 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
359426
m_glow);
360427
m_particlemanager->addParticle(toadd);
361428
}
362-
i = m_spawntimes.erase(i);
363-
}
364-
else
365-
{
366-
++i;
367-
}
368-
}
369-
}
370-
else // Spawner exists for an infinity timespan, spawn on a per-second base
371-
{
372-
// Skip this step if attached to an unloaded object
373-
if (unloaded)
374-
return;
375-
for (int i = 0; i <= m_amount; i++)
376-
{
377-
if (rand()/(float)RAND_MAX < dtime)
378-
{
379-
v3f pos = random_v3f(m_minpos, m_maxpos);
380-
v3f vel = random_v3f(m_minvel, m_maxvel);
381-
v3f acc = random_v3f(m_minacc, m_maxacc);
382-
383-
if (is_attached) {
384-
// Apply attachment yaw and position
385-
pos.rotateXZBy(attached_yaw);
386-
pos += attached_pos;
387-
vel.rotateXZBy(attached_yaw);
388-
acc.rotateXZBy(attached_yaw);
389-
}
390-
391-
float exptime = rand()/(float)RAND_MAX
392-
*(m_maxexptime-m_minexptime)
393-
+m_minexptime;
394-
float size = rand()/(float)RAND_MAX
395-
*(m_maxsize-m_minsize)
396-
+m_minsize;
397-
398-
Particle* toadd = new Particle(
399-
m_gamedef,
400-
m_smgr,
401-
m_player,
402-
env,
403-
pos,
404-
vel,
405-
acc,
406-
exptime,
407-
size,
408-
m_collisiondetection,
409-
m_collision_removal,
410-
m_vertical,
411-
m_texture,
412-
v2f(0.0, 0.0),
413-
v2f(1.0, 1.0),
414-
m_animation,
415-
m_glow);
416-
m_particlemanager->addParticle(toadd);
417429
}
418430
}
419431
}

0 commit comments

Comments
 (0)
Please sign in to comment.