Skip to content

Commit

Permalink
Fix jittering sounds on entities (fixes #2974)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlockMen committed Oct 26, 2015
1 parent 2c25107 commit 8a6e921
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 59 deletions.
93 changes: 36 additions & 57 deletions src/collision.cpp
Expand Up @@ -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;
}
Expand All @@ -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;
Expand All @@ -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) &&
Expand All @@ -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;
Expand All @@ -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);
}
}
Expand All @@ -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];

/*
Expand All @@ -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;
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/collision.h
Expand Up @@ -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)
{}
};

Expand Down
2 changes: 1 addition & 1 deletion src/localplayer.cpp
Expand Up @@ -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);

Expand Down

1 comment on commit 8a6e921

@HybridDog
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.