Fix formula used for acceleration (#12353)

This commit is contained in:
Lars Müller 2022-09-20 10:55:51 +02:00 committed by GitHub
parent 11905a6db6
commit 1317cd12d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 29 additions and 16 deletions

@ -3,6 +3,7 @@
This document contains a list of breaking changes to be made in the next major version. This document contains a list of breaking changes to be made in the next major version.
* Remove attachment space multiplier (*10) * Remove attachment space multiplier (*10)
* Remove player gravity multiplier (*2)
* `get_sky()` returns a table (without arg) * `get_sky()` returns a table (without arg)
* `game.conf` name/id mess * `game.conf` name/id mess
* remove `depends.txt` / `description.txt` (would simplify ContentDB and Minetest code a little) * remove `depends.txt` / `description.txt` (would simplify ContentDB and Minetest code a little)

@ -195,21 +195,24 @@ void ClientEnvironment::step(float dtime)
lplayer->applyControl(dtime_part, this); lplayer->applyControl(dtime_part, this);
// Apply physics // Apply physics
lplayer->gravity = 0;
if (!free_move) { if (!free_move) {
// Gravity // Gravity
v3f speed = lplayer->getSpeed();
if (!is_climbing && !lplayer->in_liquid) if (!is_climbing && !lplayer->in_liquid)
speed.Y -= lplayer->movement_gravity * // HACK the factor 2 for gravity is arbitrary and should be removed eventually
lplayer->physics_override.gravity * dtime_part * 2.0f; lplayer->gravity = 2 * lplayer->movement_gravity * lplayer->physics_override.gravity;
// Liquid floating / sinking // Liquid floating / sinking
if (!is_climbing && lplayer->in_liquid && if (!is_climbing && lplayer->in_liquid &&
!lplayer->swimming_vertical && !lplayer->swimming_vertical &&
!lplayer->swimming_pitch) !lplayer->swimming_pitch)
speed.Y -= lplayer->movement_liquid_sink * dtime_part * 2.0f; // HACK the factor 2 for gravity is arbitrary and should be removed eventually
lplayer->gravity = 2 * lplayer->movement_liquid_sink;
// Movement resistance // Movement resistance
if (lplayer->move_resistance > 0) { if (lplayer->move_resistance > 0) {
v3f speed = lplayer->getSpeed();
// How much the node's move_resistance blocks movement, ranges // How much the node's move_resistance blocks movement, ranges
// between 0 and 1. Should match the scale at which liquid_viscosity // between 0 and 1. Should match the scale at which liquid_viscosity
// increase affects other liquid attributes. // increase affects other liquid attributes.
@ -232,15 +235,16 @@ void ClientEnvironment::step(float dtime)
(1 - resistance_factor); (1 - resistance_factor);
v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f); v3f d = d_wanted.normalize() * (dl * dtime_part * 100.0f);
speed += d; speed += d;
}
lplayer->setSpeed(speed); lplayer->setSpeed(speed);
} }
}
/* /*
Move the lplayer. Move the lplayer.
This also does collision detection. This also does collision detection.
*/ */
lplayer->move(dtime_part, this, position_max_increment, lplayer->move(dtime_part, this, position_max_increment,
&player_collisions); &player_collisions);
} }

@ -292,7 +292,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
float player_stepheight = (m_cao == nullptr) ? 0.0f : float player_stepheight = (m_cao == nullptr) ? 0.0f :
(touching_ground ? m_cao->getStepHeight() : (0.2f * BS)); (touching_ground ? m_cao->getStepHeight() : (0.2f * BS));
v3f accel_f; v3f accel_f(0, -gravity, 0);
const v3f initial_position = position; const v3f initial_position = position;
const v3f initial_speed = m_speed; const v3f initial_speed = m_speed;
@ -778,6 +778,9 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
m_speed += m_added_velocity; m_speed += m_added_velocity;
m_added_velocity = v3f(0.0f); m_added_velocity = v3f(0.0f);
// Apply gravity (note: this is broken, but kept since this is *old* move code)
m_speed.Y -= gravity * dtime;
/* /*
Collision detection Collision detection
*/ */
@ -1117,8 +1120,10 @@ void LocalPlayer::handleAutojump(f32 dtime, Environment *env,
} }
} }
float jump_height = 1.1f; // TODO: better than a magic number float jumpspeed = movement_speed_jump * physics_override.jump;
v3f jump_pos = initial_position + v3f(0.0f, jump_height * BS, 0.0f); float peak_dtime = jumpspeed / gravity; // at the peak of the jump v = gt <=> t = v / g
float jump_height = (jumpspeed - 0.5f * gravity * peak_dtime) * peak_dtime; // s = vt - 1/2 gt^2
v3f jump_pos = initial_position + v3f(0.0f, jump_height, 0.0f);
v3f jump_speed = initial_speed; v3f jump_speed = initial_speed;
// try at peak of jump, zero step height // try at peak of jump, zero step height

@ -62,6 +62,8 @@ public:
bool swimming_vertical = false; bool swimming_vertical = false;
bool swimming_pitch = false; bool swimming_pitch = false;
f32 gravity = 0; // total downwards acceleration
void move(f32 dtime, Environment *env, f32 pos_max_d); void move(f32 dtime, Environment *env, f32 pos_max_d);
void move(f32 dtime, Environment *env, f32 pos_max_d, void move(f32 dtime, Environment *env, f32 pos_max_d,
std::vector<CollisionInfo> *collision_info); std::vector<CollisionInfo> *collision_info);

@ -217,9 +217,10 @@ void Particle::step(float dtime)
} }
m_pos = p_pos / BS; m_pos = p_pos / BS;
} else { } else {
// apply acceleration // apply velocity and acceleration to position
m_pos += (m_velocity + m_acceleration * 0.5f * dtime) * dtime;
// apply acceleration to velocity
m_velocity += m_acceleration * dtime; m_velocity += m_acceleration * dtime;
m_pos += m_velocity * dtime;
} }
if (m_animation.type != TAT_NONE) { if (m_animation.type != TAT_NONE) {

@ -249,10 +249,12 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
} else { } else {
time_notification_done = false; time_notification_done = false;
} }
v3f newpos_f = *pos_f + (*speed_f + accel_f * 0.5f * dtime) * dtime;
*speed_f += accel_f * dtime; *speed_f += accel_f * dtime;
// If there is no speed, there are no collisions // If the object is static, there are no collisions
if (speed_f->getLength() == 0) if (newpos_f == *pos_f)
return result; return result;
// Limit speed for avoiding hangs // Limit speed for avoiding hangs
@ -270,7 +272,6 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
//TimeTaker tt2("collisionMoveSimple collect boxes"); //TimeTaker tt2("collisionMoveSimple collect boxes");
ScopeProfiler sp2(g_profiler, "collisionMoveSimple(): collect boxes", SPT_AVG); ScopeProfiler sp2(g_profiler, "collisionMoveSimple(): collect boxes", SPT_AVG);
v3f newpos_f = *pos_f + *speed_f * dtime;
v3f minpos_f( v3f minpos_f(
MYMIN(pos_f->X, newpos_f.X), MYMIN(pos_f->X, newpos_f.X),
MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5 MYMIN(pos_f->Y, newpos_f.Y) + 0.01f * BS, // bias rounding, player often at +/-n.5

@ -175,8 +175,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
m_velocity = p_velocity; m_velocity = p_velocity;
m_acceleration = p_acceleration; m_acceleration = p_acceleration;
} else { } else {
m_base_position += dtime * m_velocity + 0.5 * dtime m_base_position += (m_velocity + m_acceleration * 0.5f * dtime) * dtime;
* dtime * m_acceleration;
m_velocity += dtime * m_acceleration; m_velocity += dtime * m_acceleration;
} }