Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rigidbodies squash and bounce off each other when restitution is zero #593

Open
Pyroglyph opened this issue Dec 13, 2024 · 1 comment
Open
Labels
A-Dynamics Relates to rigid body dynamics: motion, mass, constraint solving, joints, CCD, and so on

Comments

@Pyroglyph
Copy link

Rigidbodies seem to squash and bounce off other bodies despite restitution being disabled on everything. Increasing the density exacerbates this.

Here's a somewhat extreme example, where the yellow cube is very dense. The orientation doesn't matter, but I think it makes the effect more visible.

out.webm

The issue is also visible in the dynamic_character_2d example when jumping on top of the cube. It doesn't happen every time, but it seems to happen more often when jumping on or near the corner of the cube.

I've also attached the code used to reproduce the issue as in the video.

Show code
use avian2d::prelude::*;
use bevy::prelude::*;

fn main() {
	App::new()
		.add_plugins((DefaultPlugins, PhysicsPlugins::default().with_length_unit(10.0)))
		.add_systems(Startup, setup)
		.run();
}

fn setup(mut commands: Commands) {
	// Upper cube (yellow)
	commands.spawn((
		Sprite {
			color: Color::srgb(0.8, 0.8, 0.0),
			custom_size: Some(Vec2::new(3.0, 3.0)),
			..default()
		},
		Transform::from_xyz(5.0, 20.0, 0.0).with_rotation(Quat::from_rotation_z(std::f32::consts::PI / 4.)),
		RigidBody::Dynamic,
		ColliderDensity(1000.),
		Restitution::ZERO.with_combine_rule(CoefficientCombine::Min),
		Collider::rectangle(3.0, 3.0),
	));

	// Lower cube (blue)
	commands.spawn((
		Sprite {
			color: Color::srgb(0.0, 0.8, 0.8),
			custom_size: Some(Vec2::new(3.0, 3.0)),
			..default()
		},
		Transform::from_xyz(5.0, -15.0, 0.0),
		RigidBody::Dynamic,
		ColliderDensity(1.),
		Restitution::ZERO.with_combine_rule(CoefficientCombine::Min),
		Collider::rectangle(3.0, 3.0),
	));

	// Floor
	commands.spawn((
		Sprite {
			color: Color::srgb(0.7, 0.7, 0.8),
			custom_size: Some(Vec2::new(100.0, 5.0)),
			..default()
		},
		Transform::from_xyz(0.0, -20.0, 0.0),
		RigidBody::Static,
		Restitution::ZERO.with_combine_rule(CoefficientCombine::Min),
		Collider::rectangle(100.0, 5.0),
	));

	// Camera
	commands.spawn(Camera2d).insert(OrthographicProjection {
		scale: 0.1,
		..OrthographicProjection::default_2d()
	});
}

For reference, I'm using the latest main: commit c4840dd

@Jondolf Jondolf added the A-Dynamics Relates to rigid body dynamics: motion, mass, constraint solving, joints, CCD, and so on label Dec 13, 2024
@Jondolf
Copy link
Owner

Jondolf commented Dec 13, 2024

This is "expected" behavior, in that it's a known limitation. It is briefly mentioned in the docs under the Accuracy section here.

The issue here is the large mass ratio of 1:1000, which is something that the vast majority of physics engines and constraint solvers struggle with (specifically dual solvers, if you're interested). If you make the masses closer to each other, it should behave more like you'd expect.

The problem is essentially that the contact between the two dynamic boxes only "sees" their masses, while the contact between the lower box and ground only "sees" the mass of that one box. Each individual contact has no real awareness of any other interactions. Thus, the impulse applied by the high-density box will sort of "overpower" the impulse applied by the ground, and it can take many more solver iterations for the impulses to truly stabilize and converge on an accurate solution.

A similar phenomenon could be seen for a chain consisting of light segments connected by joints, and a heavy sphere at the bottom; the chain will stretch more and more the heavier the bottom sphere is.

Now, even with a mass ratio of 1:1, you might see a very small bounce when the upper box hits the lower box. There could be a few reasons for this, like how Avian (similarly to Box2D and Rapier) uses "soft constraints", which solve constraints "softly" and dampen constraint responses. This remaining bounce can be largely mitigated by tweaking some parameters in the SolverConfig resource; in this case, I noticed that e.g. reducing the contact_frequency_factor helped with this particular issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Dynamics Relates to rigid body dynamics: motion, mass, constraint solving, joints, CCD, and so on
Projects
None yet
Development

No branches or pull requests

2 participants