From 8a6e921cb8c9886db598dd77ddde3e7ba294085a Mon Sep 17 00:00:00 2001 From: BlockMen Date: Wed, 12 Aug 2015 17:13:19 +0200 Subject: [PATCH] Fix jittering sounds on entities (fixes #2974) --- src/collision.cpp | 93 ++++++++++++++++++--------------------------- src/collision.h | 4 +- src/localplayer.cpp | 2 +- 3 files changed, 40 insertions(+), 59 deletions(-) diff --git a/src/collision.cpp b/src/collision.cpp index 193330250..2b64547c3 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -379,16 +379,14 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, int loopcount = 0; - while(dtime > BS*1e-10) - { + while(dtime > BS * 1e-10) { //TimeTaker tt3("collisionMoveSimple dtime loop"); ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG); // Avoid infinite loop loopcount++; - if(loopcount >= 100) - { - warningstream<<"collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop"<= 100) { + warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop" << std::endl; dtime = 0; break; } @@ -404,8 +402,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, /* Go through every nodebox, find nearest collision */ - for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) - { + for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) { // Ignore if already stepped up this nodebox. if(is_step_up[boxindex]) continue; @@ -415,7 +412,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, int collided = axisAlignedCollision( cboxes[boxindex], movingbox, speed_f, d, dtime_tmp); - if(collided == -1 || dtime_tmp >= nearest_dtime) + if (collided == -1 || dtime_tmp >= nearest_dtime) continue; nearest_dtime = dtime_tmp; @@ -423,18 +420,14 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, nearest_boxindex = boxindex; } - if(nearest_collided == -1) - { + if (nearest_collided == -1) { // No collision with any collision box. pos_f += speed_f * dtime; dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers - } - else - { + } else { // Otherwise, a collision occurred. const aabb3f& cbox = cboxes[nearest_boxindex]; - // Check for stairs. bool step_up = (nearest_collided != 1) && // must not be Y direction (movingbox.MinEdge.Y < cbox.MaxEdge.Y) && @@ -448,67 +441,56 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, float bounce = -(float)bouncy_values[nearest_boxindex] / 100.0; // Move to the point of collision and reduce dtime by nearest_dtime - if(nearest_dtime < 0) - { + if (nearest_dtime < 0) { // Handle negative nearest_dtime (can be caused by the d allowance) - if(!step_up) - { - if(nearest_collided == 0) + if (!step_up) { + if (nearest_collided == 0) pos_f.X += speed_f.X * nearest_dtime; - if(nearest_collided == 1) + if (nearest_collided == 1) pos_f.Y += speed_f.Y * nearest_dtime; - if(nearest_collided == 2) + if (nearest_collided == 2) pos_f.Z += speed_f.Z * nearest_dtime; } - } - else - { + } else { pos_f += speed_f * nearest_dtime; dtime -= nearest_dtime; } bool is_collision = true; - if(is_unloaded[nearest_boxindex]) + if (is_unloaded[nearest_boxindex]) is_collision = false; CollisionInfo info; - if (is_object[nearest_boxindex]) { + if (is_object[nearest_boxindex]) info.type = COLLISION_OBJECT; - } - else { + else info.type = COLLISION_NODE; - } + info.node_p = node_positions[nearest_boxindex]; info.bouncy = bouncy; info.old_speed = speed_f; // Set the speed component that caused the collision to zero - if(step_up) - { + if (step_up) { // Special case: Handle stairs is_step_up[nearest_boxindex] = true; is_collision = false; - } - else if(nearest_collided == 0) // X - { - if(fabs(speed_f.X) > BS*3) + } else if(nearest_collided == 0) { // X + if (fabs(speed_f.X) > BS * 3) speed_f.X *= bounce; else speed_f.X = 0; result.collides = true; result.collides_xz = true; } - else if(nearest_collided == 1) // Y - { - if(fabs(speed_f.Y) > BS*3) + else if(nearest_collided == 1) { // Y + if(fabs(speed_f.Y) > BS * 3) speed_f.Y *= bounce; else speed_f.Y = 0; result.collides = true; - } - else if(nearest_collided == 2) // Z - { - if(fabs(speed_f.Z) > BS*3) + } else if(nearest_collided == 2) { // Z + if (fabs(speed_f.Z) > BS * 3) speed_f.Z *= bounce; else speed_f.Z = 0; @@ -517,10 +499,10 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, } info.new_speed = speed_f; - if(info.new_speed.getDistanceFrom(info.old_speed) < 0.1*BS) + if (info.new_speed.getDistanceFrom(info.old_speed) < 0.1 * BS) is_collision = false; - if(is_collision){ + if (is_collision) { result.collisions.push_back(info); } } @@ -532,8 +514,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, aabb3f box = box_0; box.MinEdge += pos_f; box.MaxEdge += pos_f; - for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) - { + for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) { const aabb3f& cbox = cboxes[boxindex]; /* @@ -545,23 +526,21 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, Use 0.15*BS so that it is easier to get on a node. */ - if( - cbox.MaxEdge.X-d > box.MinEdge.X && - cbox.MinEdge.X+d < box.MaxEdge.X && - cbox.MaxEdge.Z-d > box.MinEdge.Z && - cbox.MinEdge.Z+d < box.MaxEdge.Z - ){ - if(is_step_up[boxindex]) - { + if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X && + cbox.MaxEdge.Z - d > box.MinEdge.Z && + cbox.MinEdge.Z + d < box.MaxEdge.Z) { + if (is_step_up[boxindex]) { pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y); box = box_0; box.MinEdge += pos_f; box.MaxEdge += pos_f; } - if(fabs(cbox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS) - { + if (fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.15 * BS) { result.touching_ground = true; - if(is_unloaded[boxindex]) + + if (is_object[boxindex]) + result.standing_on_object = true; + if (is_unloaded[boxindex]) result.standing_on_unloaded = true; } } diff --git a/src/collision.h b/src/collision.h index fc4187eda..d1234bef3 100644 --- a/src/collision.h +++ b/src/collision.h @@ -57,13 +57,15 @@ struct collisionMoveResult bool collides; bool collides_xz; bool standing_on_unloaded; + bool standing_on_object; std::vector collisions; collisionMoveResult(): touching_ground(false), collides(false), collides_xz(false), - standing_on_unloaded(false) + standing_on_unloaded(false), + standing_on_object(false) {} }; diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 77e7a9e16..96e2737c7 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -344,7 +344,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d, } } - if(!touching_ground_was && touching_ground){ + if(!result.standing_on_object && !touching_ground_was && touching_ground) { MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround"); m_gamedef->event()->put(e);