Optionally extend the active object in a players camera direction.

See #6667

By setting active_object_send_range_blocks > active_block_range a server admin
can allow clients to retrieve active objects futher out from the player at
relatively low cost to the server
(only objects in the players' view cone are considered).
This commit is contained in:
Lars Hofhansl 2017-12-03 17:51:58 -08:00
parent 83b12ed481
commit 5a03b1f5f9
2 changed files with 53 additions and 15 deletions

@ -292,8 +292,27 @@ void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list)
}
}
void ActiveBlockList::update(std::vector<v3s16> &active_positions,
s16 radius,
void fillViewConeBlock(v3s16 p0,
const s16 r,
const v3f camera_pos,
const v3f camera_dir,
const float camera_fov,
std::set<v3s16> &list)
{
v3s16 p;
const s16 r_nodes = r * BS * MAP_BLOCKSIZE;
for (p.X = p0.X - r; p.X <= p0.X+r; p.X++)
for (p.Y = p0.Y - r; p.Y <= p0.Y+r; p.Y++)
for (p.Z = p0.Z - r; p.Z <= p0.Z+r; p.Z++) {
if (isBlockInSight(p, camera_pos, camera_dir, camera_fov, r_nodes)) {
list.insert(p);
}
}
}
void ActiveBlockList::update(std::vector<PlayerSAO*> &active_players,
s16 active_block_range,
s16 active_object_range,
std::set<v3s16> &blocks_removed,
std::set<v3s16> &blocks_added)
{
@ -301,8 +320,25 @@ void ActiveBlockList::update(std::vector<v3s16> &active_positions,
Create the new list
*/
std::set<v3s16> newlist = m_forceloaded_list;
for (const v3s16 &active_position : active_positions) {
fillRadiusBlock(active_position, radius, newlist);
m_abm_list = m_forceloaded_list;
for (const PlayerSAO *playersao : active_players) {
v3s16 pos = getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS));
fillRadiusBlock(pos, active_block_range, m_abm_list);
fillRadiusBlock(pos, active_block_range, newlist);
s16 player_ao_range = std::min(active_object_range, playersao->getWantedRange());
// only do this if this would add blocks
if (player_ao_range > active_block_range) {
v3f camera_dir = v3f(0,0,1);
camera_dir.rotateYZBy(playersao->getPitch());
camera_dir.rotateXZBy(playersao->getYaw());
fillViewConeBlock(pos,
player_ao_range,
playersao->getEyePosition(),
camera_dir,
playersao->getFov(),
newlist);
}
}
/*
@ -873,10 +909,6 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
elapsed_timer.position));
}
}
/* Handle ActiveBlockModifiers */
ABMHandler abmhandler(m_abms, dtime_s, this, false);
abmhandler.apply(block);
}
void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm)
@ -1140,7 +1172,7 @@ void ServerEnvironment::step(float dtime)
/*
Get player block positions
*/
std::vector<v3s16> players_blockpos;
std::vector<PlayerSAO*> players;
for (RemotePlayer *player: m_players) {
// Ignore disconnected players
if (player->getPeerId() == PEER_ID_INEXISTENT)
@ -1149,18 +1181,21 @@ void ServerEnvironment::step(float dtime)
PlayerSAO *playersao = player->getPlayerSAO();
assert(playersao);
players_blockpos.push_back(
getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS)));
players.push_back(playersao);
}
/*
Update list of active blocks, collecting changes
*/
// use active_object_send_range_blocks since that is max distance
// for active objects sent the client anyway
static thread_local const s16 active_object_range =
g_settings->getS16("active_object_send_range_blocks");
static thread_local const s16 active_block_range =
g_settings->getS16("active_block_range");
std::set<v3s16> blocks_removed;
std::set<v3s16> blocks_added;
m_active_blocks.update(players_blockpos, active_block_range,
m_active_blocks.update(players, active_block_range, active_object_range,
blocks_removed, blocks_added);
/*
@ -1187,6 +1222,7 @@ void ServerEnvironment::step(float dtime)
MapBlock *block = m_map->getBlockOrEmerge(p);
if (!block) {
m_active_blocks.m_list.erase(p);
m_active_blocks.m_abm_list.erase(p);
continue;
}
@ -1248,7 +1284,7 @@ void ServerEnvironment::step(float dtime)
// Initialize handling of ActiveBlockModifiers
ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true);
for (const v3s16 &p : m_active_blocks.m_list) {
for (const v3s16 &p : m_active_blocks.m_abm_list) {
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
if (!block)
continue;

@ -154,8 +154,9 @@ private:
class ActiveBlockList
{
public:
void update(std::vector<v3s16> &active_positions,
s16 radius,
void update(std::vector<PlayerSAO*> &active_players,
s16 active_block_range,
s16 active_object_range,
std::set<v3s16> &blocks_removed,
std::set<v3s16> &blocks_added);
@ -168,6 +169,7 @@ public:
}
std::set<v3s16> m_list;
std::set<v3s16> m_abm_list;
std::set<v3s16> m_forceloaded_list;
private: