mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
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.
This commit is contained in:
parent
af2f02552f
commit
60baf8120c
@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "clientmap.h"
|
#include "clientmap.h"
|
||||||
#include "mapnode.h"
|
#include "mapnode.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Utility
|
Utility
|
||||||
@ -293,6 +294,9 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
{
|
{
|
||||||
m_time += dtime;
|
m_time += dtime;
|
||||||
|
|
||||||
|
static const float radius =
|
||||||
|
g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
bool unloaded = false;
|
bool unloaded = false;
|
||||||
bool is_attached = false;
|
bool is_attached = false;
|
||||||
v3f attached_pos = v3f(0,0,0);
|
v3f attached_pos = v3f(0,0,0);
|
||||||
@ -316,11 +320,74 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
{
|
{
|
||||||
m_amount--;
|
m_amount--;
|
||||||
|
|
||||||
// Pretend to, but don't actually spawn a
|
// Pretend to, but don't actually spawn a particle if it is
|
||||||
// particle if it is attached to an unloaded
|
// attached to an unloaded object or distant from player.
|
||||||
// object.
|
|
||||||
if (!unloaded) {
|
if (!unloaded) {
|
||||||
|
v3f ppos = m_player->getPosition() / BS;
|
||||||
v3f pos = random_v3f(m_minpos, m_maxpos);
|
v3f pos = random_v3f(m_minpos, m_maxpos);
|
||||||
|
|
||||||
|
if (pos.getDistanceFrom(ppos) <= radius) {
|
||||||
|
v3f vel = random_v3f(m_minvel, m_maxvel);
|
||||||
|
v3f acc = random_v3f(m_minacc, m_maxacc);
|
||||||
|
|
||||||
|
if (is_attached) {
|
||||||
|
// Apply attachment yaw and position
|
||||||
|
pos.rotateXZBy(attached_yaw);
|
||||||
|
pos += attached_pos;
|
||||||
|
vel.rotateXZBy(attached_yaw);
|
||||||
|
acc.rotateXZBy(attached_yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
float exptime = rand()/(float)RAND_MAX
|
||||||
|
*(m_maxexptime-m_minexptime)
|
||||||
|
+m_minexptime;
|
||||||
|
float size = rand()/(float)RAND_MAX
|
||||||
|
*(m_maxsize-m_minsize)
|
||||||
|
+m_minsize;
|
||||||
|
|
||||||
|
Particle* toadd = new Particle(
|
||||||
|
m_gamedef,
|
||||||
|
m_smgr,
|
||||||
|
m_player,
|
||||||
|
env,
|
||||||
|
pos,
|
||||||
|
vel,
|
||||||
|
acc,
|
||||||
|
exptime,
|
||||||
|
size,
|
||||||
|
m_collisiondetection,
|
||||||
|
m_collision_removal,
|
||||||
|
m_vertical,
|
||||||
|
m_texture,
|
||||||
|
v2f(0.0, 0.0),
|
||||||
|
v2f(1.0, 1.0),
|
||||||
|
m_animation,
|
||||||
|
m_glow);
|
||||||
|
m_particlemanager->addParticle(toadd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = m_spawntimes.erase(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Spawner exists for an infinity timespan, spawn on a per-second base
|
||||||
|
{
|
||||||
|
// Skip this step if attached to an unloaded object
|
||||||
|
if (unloaded)
|
||||||
|
return;
|
||||||
|
for (int i = 0; i <= m_amount; i++)
|
||||||
|
{
|
||||||
|
if (rand()/(float)RAND_MAX < dtime)
|
||||||
|
{
|
||||||
|
// Do not spawn particle if distant from player
|
||||||
|
v3f ppos = m_player->getPosition() / BS;
|
||||||
|
v3f pos = random_v3f(m_minpos, m_maxpos);
|
||||||
|
|
||||||
|
if (pos.getDistanceFrom(ppos) <= radius) {
|
||||||
v3f vel = random_v3f(m_minvel, m_maxvel);
|
v3f vel = random_v3f(m_minvel, m_maxvel);
|
||||||
v3f acc = random_v3f(m_minacc, m_maxacc);
|
v3f acc = random_v3f(m_minacc, m_maxacc);
|
||||||
|
|
||||||
@ -359,61 +426,6 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
m_glow);
|
m_glow);
|
||||||
m_particlemanager->addParticle(toadd);
|
m_particlemanager->addParticle(toadd);
|
||||||
}
|
}
|
||||||
i = m_spawntimes.erase(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Spawner exists for an infinity timespan, spawn on a per-second base
|
|
||||||
{
|
|
||||||
// Skip this step if attached to an unloaded object
|
|
||||||
if (unloaded)
|
|
||||||
return;
|
|
||||||
for (int i = 0; i <= m_amount; i++)
|
|
||||||
{
|
|
||||||
if (rand()/(float)RAND_MAX < dtime)
|
|
||||||
{
|
|
||||||
v3f pos = random_v3f(m_minpos, m_maxpos);
|
|
||||||
v3f vel = random_v3f(m_minvel, m_maxvel);
|
|
||||||
v3f acc = random_v3f(m_minacc, m_maxacc);
|
|
||||||
|
|
||||||
if (is_attached) {
|
|
||||||
// Apply attachment yaw and position
|
|
||||||
pos.rotateXZBy(attached_yaw);
|
|
||||||
pos += attached_pos;
|
|
||||||
vel.rotateXZBy(attached_yaw);
|
|
||||||
acc.rotateXZBy(attached_yaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
float exptime = rand()/(float)RAND_MAX
|
|
||||||
*(m_maxexptime-m_minexptime)
|
|
||||||
+m_minexptime;
|
|
||||||
float size = rand()/(float)RAND_MAX
|
|
||||||
*(m_maxsize-m_minsize)
|
|
||||||
+m_minsize;
|
|
||||||
|
|
||||||
Particle* toadd = new Particle(
|
|
||||||
m_gamedef,
|
|
||||||
m_smgr,
|
|
||||||
m_player,
|
|
||||||
env,
|
|
||||||
pos,
|
|
||||||
vel,
|
|
||||||
acc,
|
|
||||||
exptime,
|
|
||||||
size,
|
|
||||||
m_collisiondetection,
|
|
||||||
m_collision_removal,
|
|
||||||
m_vertical,
|
|
||||||
m_texture,
|
|
||||||
v2f(0.0, 0.0),
|
|
||||||
v2f(1.0, 1.0),
|
|
||||||
m_animation,
|
|
||||||
m_glow);
|
|
||||||
m_particlemanager->addParticle(toadd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user