Player physics: Ensure larger dtime simulation steps (#10563)

master
Lars Müller 2020-10-29 20:15:46 +01:00 committed by GitHub
parent a701d24a00
commit 2dff3dd03f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 46 additions and 69 deletions

View File

@ -183,84 +183,61 @@ void ClientEnvironment::step(float dtime)
if(dtime > 0.5) if(dtime > 0.5)
dtime = 0.5; dtime = 0.5;
f32 dtime_downcount = dtime;
/* /*
Stuff that has a maximum time increment Stuff that has a maximum time increment
*/ */
u32 loopcount = 0; u32 steps = ceil(dtime / dtime_max_increment);
do f32 dtime_part = dtime / steps;
{ for (; steps > 0; --steps) {
loopcount++; /*
Local player handling
*/
f32 dtime_part; // Control local player
if(dtime_downcount > dtime_max_increment) lplayer->applyControl(dtime_part, this);
{
dtime_part = dtime_max_increment; // Apply physics
dtime_downcount -= dtime_part; if (!free_move && !is_climbing) {
} // Gravity
else v3f speed = lplayer->getSpeed();
{ if (!lplayer->in_liquid)
dtime_part = dtime_downcount; speed.Y -= lplayer->movement_gravity *
/* lplayer->physics_override_gravity * dtime_part * 2.0f;
Setting this to 0 (no -=dtime_part) disables an infinite loop
when dtime_part is so small that dtime_downcount -= dtime_part // Liquid floating / sinking
does nothing if (lplayer->in_liquid && !lplayer->swimming_vertical &&
*/ !lplayer->swimming_pitch)
dtime_downcount = 0; 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);
} }
/* /*
Handle local player Move the lplayer.
This also does collision detection.
*/ */
lplayer->move(dtime_part, this, position_max_increment,
{ &player_collisions);
// 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);
}
/*
Move the lplayer.
This also does collision detection.
*/
lplayer->move(dtime_part, this, position_max_increment,
&player_collisions);
}
} while (dtime_downcount > 0.001);
bool player_immortal = lplayer->getCAO() && lplayer->getCAO()->isImmortal(); bool player_immortal = lplayer->getCAO() && lplayer->getCAO()->isImmortal();