Skip to content
Permalink
Browse files

Fix jittering sounds on entities (fixes #2974)

  • Loading branch information
BlockMen committed Oct 26, 2015
1 parent 2c25107 commit 8a6e921cb8c9886db598dd77ddde3e7ba294085a
Showing with 40 additions and 59 deletions.
  1. +36 −57 src/collision.cpp
  2. +3 −1 src/collision.h
  3. +1 −1 src/localplayer.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"<<std::endl;
if (loopcount >= 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,26 +412,22 @@ 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;
nearest_collided = collided;
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;
}
}
@@ -57,13 +57,15 @@ struct collisionMoveResult
bool collides;
bool collides_xz;
bool standing_on_unloaded;
bool standing_on_object;
std::vector<CollisionInfo> collisions;

collisionMoveResult():
touching_ground(false),
collides(false),
collides_xz(false),
standing_on_unloaded(false)
standing_on_unloaded(false),
standing_on_object(false)
{}
};

@@ -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);

1 comment on commit 8a6e921

@HybridDog

This comment has been minimized.

Copy link
Contributor

@HybridDog HybridDog commented on 8a6e921 Oct 31, 2015

If you stand on an object and it suddenly moves up, you fall through it, don't you?
Maybe you could assign the player to it if he/she is standing on it.

Please sign in to comment.