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

Jolt Physics: state.get_contact_collider_position() Fails for Sleeping Bodies Despite get_contact_count() > 0 #100515

Closed
NatGazer opened this issue Dec 17, 2024 · 2 comments · Fixed by #100533

Comments

@NatGazer
Copy link

Tested versions

  • Reproducible in: 4.3.stable

System information

Windows 10 - Vulkan (Forward+) - NVIDIA RTX 3060

Issue description

Jolt was just integrated to Godot, so I believe this should be in Godot issues. If not let me know!

When using Jolt Physics in Godot 4, and trying to get collision contact points between bodies, calling state.get_contact_collider_position(index) for a RigidBody3D results in an "Index out of bounds" error if the body gets in sleep mode. This occurs even when get_contact_count() reports a value greater than 0. The error does not occur with default Godot Physics

The error:

_physics_process(): Index p_contact_idx = 0 is out of bounds (body->get_contact_count() = 0).
  <C++ Source>   src\objects\jolt_physics_direct_body_state_3d.cpp:217 @ _get_contact_collider_position()

This behavior affects contact point calculations for bodies that are stationary but still colliding with other objects

Steps to reproduce

  1. Set up a scene with two colliding RigidBody3D objects.
  2. Ensure Jolt Physics is installed and defined as current physics engine
  3. Enable contact_monitor and set max_contacts_reported to a non-zero value (e.g., 5).
  4. Let one of the bodies come to rest, causing it to enter sleep mode.
  5. Execute the code below inside the body that has come to a rest:
extends RigidBody3D

func _ready() -> void:
	contact_monitor = true
	max_contacts_reported = 5

func _physics_process(_delta: float) -> void:
	# Get body rid
	var rid := get_rid()
	# Get body physics state
	var state := PhysicsServer3D.body_get_direct_state(rid)
	
	for i in get_contact_count():
		print("Contact count: ", get_contact_count(),
			"  ", state.get_contact_collider_position(i))

Expected Behavior:
state.get_contact_collider_position(index) should return valid contact points if get_contact_count() > 0, even when the body is in sleep mode.

Observed Behavior:
An "Index out of bounds" error occurs, and get_contact_collider_position() fails.

Minimal reproduction project (MRP)

I had to remove macOS, Linux and android libraries from the Jolt folder to make the file small enough to upload. You can always reinstall jolt add-on to make sure.

BugJoltContact.zip

@mihe
Copy link
Contributor

mihe commented Dec 17, 2024

I've put up a pull request to fix this, in #100533.

Until then you can work around this by simply using state.get_contact_count() instead of just get_contact_count(). You will however end up having contacts reported during the first sleep frame (which is largely what #100533 fixes) so you might want to check for state.sleeping if that matters at all to you.

Jolt was just integrated to Godot, so I believe this should be in Godot issues. If not let me know!

It might be more appropriate to report issues with the extension to the Godot Jolt repository instead. That way we don't end up burdening the maintainers here with stuff that might perhaps only relate to the extension. I'll apply whatever fix is needed to Godot either way, and backport it to the extension.

@mihe
Copy link
Contributor

mihe commented Jan 3, 2025

#100533 has now been reverted in favor of #100983, which should make the Jolt Physics module behave as Godot Physics does in terms of contact reporting for sleeping bodies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment