summaryrefslogtreecommitdiff
path: root/src/clientiface.cpp
diff options
context:
space:
mode:
authorLars Hofhansl <larsh@apache.org>2017-09-30 18:54:43 -0700
committerLars Hofhansl <larsh@apache.org>2017-10-13 20:43:58 -0700
commitb97b9a550fe6c0028daf87fdff262d25d91e1c53 (patch)
tree7f7033c4f5d1ab1c79dfc7ac5732fa402f00a462 /src/clientiface.cpp
parent6b23cabe512e5a8facd9ea9d27417e3ff81f38e2 (diff)
downloadminetest-b97b9a550fe6c0028daf87fdff262d25d91e1c53.tar.gz
minetest-b97b9a550fe6c0028daf87fdff262d25d91e1c53.tar.bz2
minetest-b97b9a550fe6c0028daf87fdff262d25d91e1c53.zip
Retrieve a small cone of blocks in the direction of the players velocity.
This helps retrieving the right set of blocks when the player is falling, traveling on cart, or in general traveling in a direction different from the view direction.
Diffstat (limited to 'src/clientiface.cpp')
-rw-r--r--src/clientiface.cpp39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/clientiface.cpp b/src/clientiface.cpp
index 852211037..89ce55da5 100644
--- a/src/clientiface.cpp
+++ b/src/clientiface.cpp
@@ -60,6 +60,24 @@ void RemoteClient::ResendBlockIfOnWire(v3s16 p)
}
}
+LuaEntitySAO *getAttachedObject(PlayerSAO *sao, ServerEnvironment *env)
+{
+ if (!sao->isAttached())
+ return nullptr;
+
+ int id;
+ std::string bone;
+ v3f dummy;
+ sao->getAttachment(&id, &bone, &dummy, &dummy);
+ ServerActiveObject *ao = env->getActiveObject(id);
+ while (id && ao) {
+ ao->getAttachment(&id, &bone, &dummy, &dummy);
+ if (id)
+ ao = env->getActiveObject(id);
+ }
+ return dynamic_cast<LuaEntitySAO *>(ao);
+}
+
void RemoteClient::GetNextBlocks (
ServerEnvironment *env,
EmergeManager * emerge,
@@ -91,7 +109,9 @@ void RemoteClient::GetNextBlocks (
}
v3f playerpos = sao->getBasePosition();
- const v3f &playerspeed = player->getSpeed();
+ // if the player is attached, get the velocity from the attached object
+ LuaEntitySAO *lsao = getAttachedObject(sao, env);
+ const v3f &playerspeed = lsao? lsao->getVelocity() : player->getSpeed();
v3f playerspeeddir(0,0,0);
if(playerspeed.getLength() > 1.0*BS)
playerspeeddir = playerspeed / playerspeed.getLength();
@@ -170,11 +190,8 @@ void RemoteClient::GetNextBlocks (
s32 new_nearest_unsent_d = -1;
// get view range and camera fov from the client
- s16 wanted_range = sao->getWantedRange();
+ s16 wanted_range = sao->getWantedRange() + 1;
float camera_fov = sao->getFov();
- // if FOV, wanted_range are not available (old client), fall back to old default
- if (wanted_range <= 0) wanted_range = 1000;
- if (camera_fov <= 0) camera_fov = (72.0*M_PI/180) * 4./3.;
const s16 full_d_max = MYMIN(g_settings->getS16("max_block_send_distance"), wanted_range);
const s16 d_opt = MYMIN(g_settings->getS16("block_send_optimize_distance"), wanted_range);
@@ -185,7 +202,7 @@ void RemoteClient::GetNextBlocks (
s16 d_max_gen = MYMIN(g_settings->getS16("max_block_generate_distance"), wanted_range);
// Don't loop very much at a time
- s16 max_d_increment_at_time = 2;
+ s16 max_d_increment_at_time = 1;
if(d_max > d_start + max_d_increment_at_time)
d_max = d_start + max_d_increment_at_time;
@@ -247,10 +264,16 @@ void RemoteClient::GetNextBlocks (
Don't generate or send if not in sight
FIXME This only works if the client uses a small enough
FOV setting. The default of 72 degrees is fine.
+ Also retrieve a smaller view cone in the direction of the player's
+ movement.
+ (0.1 is about 4 degrees)
*/
-
f32 dist;
- if (!isBlockInSight(p, camera_pos, camera_dir, camera_fov, d_blocks_in_sight, &dist)) {
+ if (!(isBlockInSight(p, camera_pos, camera_dir, camera_fov,
+ d_blocks_in_sight, &dist) ||
+ (playerspeed.getLength() > 1.0f * BS &&
+ isBlockInSight(p, camera_pos, playerspeeddir, 0.1f,
+ d_blocks_in_sight)))) {
continue;
}