mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Fix jittering sounds on entities (fixes #2974)
This commit is contained in:
		@@ -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,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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user