1
0
mirror of https://github.com/minetest/minetest.git synced 2025-01-31 04:00:17 +01:00

Fix jittering sounds on entities (fixes #2974)

This commit is contained in:
BlockMen 2015-08-12 17:13:19 +02:00
parent 2c25107c31
commit 8a6e921cb8
3 changed files with 40 additions and 59 deletions

View File

@ -379,15 +379,13 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
int loopcount = 0; int loopcount = 0;
while(dtime > BS*1e-10) while(dtime > BS * 1e-10) {
{
//TimeTaker tt3("collisionMoveSimple dtime loop"); //TimeTaker tt3("collisionMoveSimple dtime loop");
ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG); ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG);
// Avoid infinite loop // Avoid infinite loop
loopcount++; loopcount++;
if(loopcount >= 100) if (loopcount >= 100) {
{
warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop" << std::endl; warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop" << std::endl;
dtime = 0; dtime = 0;
break; break;
@ -404,8 +402,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
/* /*
Go through every nodebox, find nearest collision 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. // Ignore if already stepped up this nodebox.
if(is_step_up[boxindex]) if(is_step_up[boxindex])
continue; continue;
@ -423,18 +420,14 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
nearest_boxindex = boxindex; nearest_boxindex = boxindex;
} }
if(nearest_collided == -1) if (nearest_collided == -1) {
{
// No collision with any collision box. // No collision with any collision box.
pos_f += speed_f * dtime; pos_f += speed_f * dtime;
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
} } else {
else
{
// Otherwise, a collision occurred. // Otherwise, a collision occurred.
const aabb3f& cbox = cboxes[nearest_boxindex]; const aabb3f& cbox = cboxes[nearest_boxindex];
// Check for stairs. // Check for stairs.
bool step_up = (nearest_collided != 1) && // must not be Y direction bool step_up = (nearest_collided != 1) && // must not be Y direction
(movingbox.MinEdge.Y < cbox.MaxEdge.Y) && (movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
@ -448,11 +441,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
float bounce = -(float)bouncy_values[nearest_boxindex] / 100.0; float bounce = -(float)bouncy_values[nearest_boxindex] / 100.0;
// Move to the point of collision and reduce dtime by nearest_dtime // 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) // Handle negative nearest_dtime (can be caused by the d allowance)
if(!step_up) if (!step_up) {
{
if (nearest_collided == 0) if (nearest_collided == 0)
pos_f.X += speed_f.X * nearest_dtime; pos_f.X += speed_f.X * nearest_dtime;
if (nearest_collided == 1) if (nearest_collided == 1)
@ -460,9 +451,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
if (nearest_collided == 2) if (nearest_collided == 2)
pos_f.Z += speed_f.Z * nearest_dtime; pos_f.Z += speed_f.Z * nearest_dtime;
} }
} } else {
else
{
pos_f += speed_f * nearest_dtime; pos_f += speed_f * nearest_dtime;
dtime -= nearest_dtime; dtime -= nearest_dtime;
} }
@ -472,25 +461,21 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
is_collision = false; is_collision = false;
CollisionInfo info; CollisionInfo info;
if (is_object[nearest_boxindex]) { if (is_object[nearest_boxindex])
info.type = COLLISION_OBJECT; info.type = COLLISION_OBJECT;
} else
else {
info.type = COLLISION_NODE; info.type = COLLISION_NODE;
}
info.node_p = node_positions[nearest_boxindex]; info.node_p = node_positions[nearest_boxindex];
info.bouncy = bouncy; info.bouncy = bouncy;
info.old_speed = speed_f; info.old_speed = speed_f;
// Set the speed component that caused the collision to zero // Set the speed component that caused the collision to zero
if(step_up) if (step_up) {
{
// Special case: Handle stairs // Special case: Handle stairs
is_step_up[nearest_boxindex] = true; is_step_up[nearest_boxindex] = true;
is_collision = false; is_collision = false;
} } else if(nearest_collided == 0) { // X
else if(nearest_collided == 0) // X
{
if (fabs(speed_f.X) > BS * 3) if (fabs(speed_f.X) > BS * 3)
speed_f.X *= bounce; speed_f.X *= bounce;
else else
@ -498,16 +483,13 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
result.collides = true; result.collides = true;
result.collides_xz = true; result.collides_xz = true;
} }
else if(nearest_collided == 1) // Y else if(nearest_collided == 1) { // Y
{
if(fabs(speed_f.Y) > BS * 3) if(fabs(speed_f.Y) > BS * 3)
speed_f.Y *= bounce; speed_f.Y *= bounce;
else else
speed_f.Y = 0; speed_f.Y = 0;
result.collides = true; result.collides = true;
} } else if(nearest_collided == 2) { // Z
else if(nearest_collided == 2) // Z
{
if (fabs(speed_f.Z) > BS * 3) if (fabs(speed_f.Z) > BS * 3)
speed_f.Z *= bounce; speed_f.Z *= bounce;
else else
@ -532,8 +514,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
aabb3f box = box_0; aabb3f box = box_0;
box.MinEdge += pos_f; box.MinEdge += pos_f;
box.MaxEdge += 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]; const aabb3f& cbox = cboxes[boxindex];
/* /*
@ -545,22 +526,20 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
Use 0.15*BS so that it is easier to get on a node. Use 0.15*BS so that it is easier to get on a node.
*/ */
if( if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X &&
cbox.MaxEdge.X-d > box.MinEdge.X &&
cbox.MinEdge.X+d < box.MaxEdge.X &&
cbox.MaxEdge.Z - d > box.MinEdge.Z && cbox.MaxEdge.Z - d > box.MinEdge.Z &&
cbox.MinEdge.Z+d < box.MaxEdge.Z cbox.MinEdge.Z + d < box.MaxEdge.Z) {
){ if (is_step_up[boxindex]) {
if(is_step_up[boxindex])
{
pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y); pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
box = box_0; box = box_0;
box.MinEdge += pos_f; box.MinEdge += pos_f;
box.MaxEdge += 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; result.touching_ground = true;
if (is_object[boxindex])
result.standing_on_object = true;
if (is_unloaded[boxindex]) if (is_unloaded[boxindex])
result.standing_on_unloaded = true; result.standing_on_unloaded = true;
} }

View File

@ -57,13 +57,15 @@ struct collisionMoveResult
bool collides; bool collides;
bool collides_xz; bool collides_xz;
bool standing_on_unloaded; bool standing_on_unloaded;
bool standing_on_object;
std::vector<CollisionInfo> collisions; std::vector<CollisionInfo> collisions;
collisionMoveResult(): collisionMoveResult():
touching_ground(false), touching_ground(false),
collides(false), collides(false),
collides_xz(false), collides_xz(false),
standing_on_unloaded(false) standing_on_unloaded(false),
standing_on_object(false)
{} {}
}; };

View File

@ -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"); MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
m_gamedef->event()->put(e); m_gamedef->event()->put(e);