aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Müller <34514239+appgurueu@users.noreply.github.com>2020-10-29 20:15:46 +0100
committerGitHub <noreply@github.com>2020-10-29 20:15:46 +0100
commit2dff3dd03f7ba25f3fab7c360759ddbf93615668 (patch)
treec2f0d42b7b461fcc755155e8db026b91507e7523
parenta701d24a0070f3f581c47e5722aa07d4f89d7b98 (diff)
downloadminetest-2dff3dd03f7ba25f3fab7c360759ddbf93615668.tar.gz
minetest-2dff3dd03f7ba25f3fab7c360759ddbf93615668.tar.bz2
minetest-2dff3dd03f7ba25f3fab7c360759ddbf93615668.zip
Player physics: Ensure larger dtime simulation steps (#10563)
-rw-r--r--src/client/clientenvironment.cpp113
1 files changed, 45 insertions, 68 deletions
diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp
index f831978a8..ea7be4200 100644
--- a/src/client/clientenvironment.cpp
+++ b/src/client/clientenvironment.cpp
@@ -183,84 +183,61 @@ void ClientEnvironment::step(float dtime)
if(dtime > 0.5)
dtime = 0.5;
- f32 dtime_downcount = dtime;
-
/*
Stuff that has a maximum time increment
*/
- u32 loopcount = 0;
- do
- {
- loopcount++;
-
- f32 dtime_part;
- if(dtime_downcount > dtime_max_increment)
- {
- dtime_part = dtime_max_increment;
- dtime_downcount -= dtime_part;
- }
- else
- {
- dtime_part = dtime_downcount;
- /*
- Setting this to 0 (no -=dtime_part) disables an infinite loop
- when dtime_part is so small that dtime_downcount -= dtime_part
- does nothing
- */
- dtime_downcount = 0;
- }
-
+ u32 steps = ceil(dtime / dtime_max_increment);
+ f32 dtime_part = dtime / steps;
+ for (; steps > 0; --steps) {
/*
- Handle local player
+ Local player handling
*/
- {
- // Control local player
- lplayer->applyControl(dtime_part, this);
-
- // Apply physics
- if (!free_move && !is_climbing) {
- // Gravity
- v3f speed = lplayer->getSpeed();
- if (!lplayer->in_liquid)
- speed.Y -= lplayer->movement_gravity *
- lplayer->physics_override_gravity * dtime_part * 2.0f;
-
- // Liquid floating / sinking
- if (lplayer->in_liquid && !lplayer->swimming_vertical &&
- !lplayer->swimming_pitch)
- speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f;
-
- // Liquid resistance
- if (lplayer->in_liquid_stable || lplayer->in_liquid) {
- // How much the node's viscosity blocks movement, ranges
- // between 0 and 1. Should match the scale at which viscosity
- // increase affects other liquid attributes.
- static const f32 viscosity_factor = 0.3f;
-
- v3f d_wanted = -speed / lplayer->movement_liquid_fluidity;
- f32 dl = d_wanted.getLength();
- if (dl > lplayer->movement_liquid_fluidity_smooth)
- dl = lplayer->movement_liquid_fluidity_smooth;
-
- dl *= (lplayer->liquid_viscosity * viscosity_factor) +
- (1 - viscosity_factor);
- v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f);
- speed += d;
- }
-
- lplayer->setSpeed(speed);
+ // Control local player
+ lplayer->applyControl(dtime_part, this);
+
+ // Apply physics
+ if (!free_move && !is_climbing) {
+ // Gravity
+ v3f speed = lplayer->getSpeed();
+ if (!lplayer->in_liquid)
+ speed.Y -= lplayer->movement_gravity *
+ lplayer->physics_override_gravity * dtime_part * 2.0f;
+
+ // Liquid floating / sinking
+ if (lplayer->in_liquid && !lplayer->swimming_vertical &&
+ !lplayer->swimming_pitch)
+ speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f;
+
+ // Liquid resistance
+ if (lplayer->in_liquid_stable || lplayer->in_liquid) {
+ // How much the node's viscosity blocks movement, ranges
+ // between 0 and 1. Should match the scale at which viscosity
+ // increase affects other liquid attributes.
+ static const f32 viscosity_factor = 0.3f;
+
+ v3f d_wanted = -speed / lplayer->movement_liquid_fluidity;
+ f32 dl = d_wanted.getLength();
+ if (dl > lplayer->movement_liquid_fluidity_smooth)
+ dl = lplayer->movement_liquid_fluidity_smooth;
+
+ dl *= (lplayer->liquid_viscosity * viscosity_factor) +
+ (1 - viscosity_factor);
+ v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f);
+ speed += d;
}
- /*
- Move the lplayer.
- This also does collision detection.
- */
- lplayer->move(dtime_part, this, position_max_increment,
- &player_collisions);
+ lplayer->setSpeed(speed);
}
- } while (dtime_downcount > 0.001);
+
+ /*
+ Move the lplayer.
+ This also does collision detection.
+ */
+ lplayer->move(dtime_part, this, position_max_increment,
+ &player_collisions);
+ }
bool player_immortal = lplayer->getCAO() && lplayer->getCAO()->isImmortal();