godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.29k stars 21.05k forks source link

`PhysicsDirectBodyState3D.get_contact_impulse()` returns zero vector on first frame of collision #73541

Open krokoschlange opened 1 year ago

krokoschlange commented 1 year ago

Godot version

v4.0.rc2.official [d2699dc7a]

System information

EndeavourOS, Vulkan

Issue description

Calling the get_contact_impulse() method on the PhysicsDirectState3D object provided in the _integrate_forces() method of RigidBody3D returns Vector3.ZERO for contacts that were created in the current frame. I would expect this method to return the impulse applied to the rigidbody by the contact, even during the first frame. This becomes an issue particularly with bouncy objects as they often only have one frame of contact which results in no impulse being reported at all.

I dug a bit in the physics code and it seems that the contacts of a rigidbody are not updated after pre_solve in GodotBodyPair3D ran which seems suspicious.

Steps to reproduce

  1. set up a scene with a rigidbody with a collider and something it can collide with (I tested both rigidbodies and staticbodies for this)
  2. Turn on contact_monitor and set max_contacts_reported to a reasonable value
  3. Add a script to the rigidbody that implements _integrate_forces() and call state.get_contact_impulse(), for example print all impulses for all contacts
  4. Observe that during the first frame after a new contact is created a zero vector is returned. This is more obvious when a physics material with bounciness 1.0 is added to the rigidbody.

Minimal reproduction project

impulse_test.zip

darthLeviN commented 10 months ago

It's worse than it seems. I get a lot of screwed up zero impulses that mess up my integrate_forces calculations.

Calinou commented 10 months ago

@krokoschlange @darthLeviN Does this issue also apply to 2D?

krokoschlange commented 10 months ago

@krokoschlange @darthLeviN Does this issue also apply to 2D?

I haven't tested it myself, but according to this comment and #81654, yes it does. Looking at the code, that is not surprising, it's basically the same.

amityadav381 commented 3 months ago

@krokoschlange @darthLeviN Does this issue also apply to 2D?

Yes, I have seen it in 2D as well (today). But changing the: physics-tick-per-second from 60 to 240 max physics steps per second from 8 to 32 I was able to see some impulses values.

ottworks commented 2 months ago

I am also experiencing this, where I get alternating frames of zero impulse, mainly from convex collision meshes.