forked from Mirrorlandia_minetest/minetest
Player physics: Ensure larger dtime simulation steps (#10563)
This commit is contained in:
parent
a701d24a00
commit
2dff3dd03f
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user