godotengine / godot

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

PhysicsDirectBodyState2D: Reported values of `get_contact_impulse` not as expected #89921

Open stephanbogner opened 7 months ago

stephanbogner commented 7 months ago

Tested versions

Tested in:

System information

Godot v4.2.1.stable - macOS 14.1.2 - Vulkan (Forward+) - integrated Apple M2 Pro - Apple M2 Pro (10 Threads)

Issue description

Context:

I try to make breakable objects and wanted to use get_contact_impulse for this case do detect "hits".

Problem:

How strong the impulses are seem almost random ... but is hard to test in a reproducible way

My physics lab setup 😂:

Screenshot 2024-03-26 at 20 37 37

Outcome:

Note

I am not 100% sure if these are bugs or I am misunderstanding the concept of what get_contact_impulse is reporting.

Steps to reproduce

I recommend making a similar physics setup and playing around. Make sure you turn on contact_monitoring and set a value for max_contacts_reported.

I used the following code to track values:

extends RigidBody2D

var highest_speed := 0.0
var highest_impulse := 0.0

func _physics_process(delta):
    var speed = linear_velocity.length()
    if speed > highest_speed:
        highest_speed = speed
        $Velocity.text = str(snapped(highest_speed, 0.1))

func _integrate_forces(state):
    var total_impulse := 0.0
    for i in range(state.get_contact_count()):
        var collided_obj = state.get_contact_collider_object(i)
        var impulse = state.get_contact_impulse(i).length()
        total_impulse += impulse

    if total_impulse > highest_impulse:
        highest_impulse = total_impulse
        $Impulse.text = str(snapped(highest_impulse, 0.1))

Minimal reproduction project (MRP)

bug-contact-impulse.zip

stephanbogner commented 7 months ago

A different setup (bug-contact-impulse.zip):

Screenshot 2024-03-26 at 21 39 54 Screenshot 2024-03-26 at 21 39 40
rburing commented 7 months ago

Thanks for the MRP!

I haven't looked into this myself but others have made PRs for it. Can you test the PR https://github.com/godotengine/godot/pull/81654 and comment on whether it fixes the issue?

stephanbogner commented 6 months ago

@rburing Thanks for the reply.

I built from source (the other approaches mentioned on the page didn't work) and now generally it's much more in line with what I'd expect as an outcome ... but since I don't know enough about actual physics it's hard to say whether it's correct now or not though, but below are the results from my tests.

If you have a more clever idea for how to test properly I'd be happy to make more tests.

Screenshot 2024-04-21 at 22 42 49 Screenshot 2024-04-21 at 22 40 36