Jondolf / avian

ECS-driven 2D and 3D physics engine for the Bevy game engine.
https://crates.io/crates/avian3d
Apache License 2.0
1.6k stars 120 forks source link

Remove ball bouncing completely #149

Open volodalexey opened 1 year ago

volodalexey commented 1 year ago

In my game I want to prevent projectile-ball bouncing when it hits other balls in grid. projectile-ball and grid-ball actually created from the same function and I set Restitution { coefficient: 0.0, combine_rule: CoefficientCombine::Multiply } for all balls.

When I shoot with projectile-ball I set it's LinearVelocity.

Some magnetic force is applying for all grid-balls as ExternalForce

That is all that affected both grid-ball and projectile-ball.

I want my ball to completely stop when they started to collide/touch. What I see right now is that balls have some kind of Inertia. For example projectile-ball bounces back (depends on the hit angle):

https://github.com/Jondolf/bevy_xpbd/assets/8973562/9127dc77-43b7-4b46-8e13-012caab4d35e

Enother example is why my projectile-ball pushes other grid-balls:

https://github.com/Jondolf/bevy_xpbd/assets/8973562/b54d5bbd-667e-4623-b2e2-380357d478dc

How can I completely stop balls on the first touch?

Jondolf commented 1 year ago

What happens if you set the friction of the balls to 0? In bevy_xpbd 0.2, dynamic friction was dependent on mass, so it was way too large for most 2D bodies, which could be what's going on here

volodalexey commented 1 year ago

When I set Friction::ZERO for balls it works much better! However sometime I still get unwanter result. For example see my second shoot. Why my blue projectile-ball pushes yellow grid-ball ?

https://github.com/Jondolf/bevy_xpbd/assets/8973562/aa23fad4-c2a4-4fab-91e6-1d82159b6577

What else can I do to prevent this?

Jondolf commented 1 year ago

For example see my second shoot. Why my blue projectile-ball pushes yellow grid-ball ?

The interaction looks normal to me. The blue ball hits the yellow ball from the right side, and the yellow ball gets pushed left because nothing is stopping it from moving there. There's zero friction, so sliding along the surface of the red ball also doesn't slow it down.

Setting restitution to zero doesn't mean that the balls don't get pushed (otherwise collisions wouldn't work), it essentially just means that the balls don't bounce off of each other like they otherwise would.

What else can I do to prevent this?

There's probably not a good and easy way to prevent this behavior currently since it is how the collision is physically supposed to work. In the future, we'll probably have a nice API for contact modification, so you could for example handle contacts differently when the velocity of the projectile ball is above some threshold. This is technically possible on the main branch already, but there is no proper API, so you would have to schedule your systems etc. correctly.

When I set Friction::ZERO for balls it works much better!

Good! Note that you can still add some friction for the balls if you want (maybe 0.01?) and it should be fine. The problem was previously that the friction was way too large, so the balls started rotating due to friction when they were hit from the side, which made them move around more. Friction issues were fixed on the main branch, so there you could probably have a more sensible friction coefficient of e.g. 0.2 or 0.3 without any issues.

volodalexey commented 1 year ago

Thanks for explanation! My goal is to recreate the same physics like in this game:

https://github.com/Jondolf/bevy_xpbd/assets/8973562/15f70580-493d-469f-be0c-428c2aec9af8

What I can assume that in this game ball do not bounce back at all. I assume that this is made with contact modification? I also can see that projectile ball sligtly pushes other balls each time but not much.

bytemunch commented 1 year ago

Thanks for explanation! My goal is to recreate the same physics like in this game:

That looks like the balls are creating a joint with one another on contact? That would kind of let all the balls create a bouncy mesh like your example.

volodalexey commented 1 year ago

I don't think the joints between balls are straightforward. I tried to make prismatic-joint, however ball can rotate around another balls. So I switched with revolute-joint. The problem is that at "hit" moment of time balls in collision are not in ideal position between each other. So revolute joint should allow some distance changing. I tried to concat revolut+prismatic in rapier engine with the help of invisible entity and this leads to not I want.

Is it possible to make two joints with bevy_xpbd ? Something like this: ideal-joint

mattdm commented 1 year ago

I think you should be able to use a DistanceJoint for this.