Particles: Do not send single particles to distant clients (#5760)

Previously, every individual particle on a server is sent to, and rendered by
(even if not actually visible), every client regardless of distance. This
significantly reduces client FPS and creates unnecessary network traffic.
Maximum distance is set by 'max block send distance' as this determines how far
a client is able to see.
This commit is contained in:
Paramat 2017-05-17 09:37:28 +01:00 committed by Loïc Blot
parent d93a959f9b
commit f61973f628

View File

@ -1707,13 +1707,25 @@ void Server::SendSpawnParticle(u16 peer_id, u16 protocol_version,
const struct TileAnimationParams &animation, u8 glow) const struct TileAnimationParams &animation, u8 glow)
{ {
DSTACK(FUNCTION_NAME); DSTACK(FUNCTION_NAME);
static const float radius =
g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE * BS;
if (peer_id == PEER_ID_INEXISTENT) { if (peer_id == PEER_ID_INEXISTENT) {
// This sucks and should be replaced by a better solution in a refactor:
std::vector<u16> clients = m_clients.getClientIDs(); std::vector<u16> clients = m_clients.getClientIDs();
for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) { for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
RemotePlayer *player = m_env->getPlayer(*i); RemotePlayer *player = m_env->getPlayer(*i);
if (!player) if (!player)
continue; continue;
PlayerSAO *sao = player->getPlayerSAO();
if (!sao)
continue;
// Do not send to distant clients
if (sao->getBasePosition().getDistanceFrom(pos * BS) > radius)
continue;
SendSpawnParticle(*i, player->protocol_version, SendSpawnParticle(*i, player->protocol_version,
pos, velocity, acceleration, pos, velocity, acceleration,
expirationtime, size, collisiondetection, expirationtime, size, collisiondetection,