Repository: godotengine/godot (language: cpp)

Issue:
Jolt Physics: state.get_contact_collider_position() Fails for Sleeping Bodies Despite get_contact_count() > 0
### 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](https://github.com/user-attachments/files/18168435/BugJoltContact.zip)





Discussion / hints:

Fix patch:
diff --git a/modules/jolt_physics/spaces/jolt_contact_listener_3d.cpp b/modules/jolt_physics/spaces/jolt_contact_listener_3d.cpp
index 21fb76464b27..85cf08d4c921 100644
--- a/modules/jolt_physics/spaces/jolt_contact_listener_3d.cpp
+++ b/modules/jolt_physics/spaces/jolt_contact_listener_3d.cpp
@@ -407,24 +407,28 @@ void JoltContactListener3D::_flush_contacts() {
 		const JPH::SubShapeIDPair &shape_pair = E.key;
 		Manifold &manifold = E.value;
 
-		const JPH::BodyID body_ids[2] = { shape_pair.GetBody1ID(), shape_pair.GetBody2ID() };
-		const JoltReadableBodies3D jolt_bodies = space->read_bodies(body_ids, 2);
+		const JoltReadableBody3D jolt_body1 = space->read_body(shape_pair.GetBody1ID());
+		const JoltReadableBody3D jolt_body2 = space->read_body(shape_pair.GetBody2ID());
 
-		JoltBody3D *body1 = jolt_bodies[0].as_body();
+		JoltBody3D *body1 = jolt_body1.as_body();
 		ERR_FAIL_NULL(body1);
 
-		JoltBody3D *body2 = jolt_bodies[1].as_body();
+		JoltBody3D *body2 = jolt_body2.as_body();
 		ERR_FAIL_NULL(body2);
 
 		const int shape_index1 = body1->find_shape_index(shape_pair.GetSubShapeID1());
 		const int shape_index2 = body2->find_shape_index(shape_pair.GetSubShapeID2());
 
-		for (const Contact &contact : manifold.contacts1) {
-			body1->add_contact(body2, manifold.depth, shape_index1, shape_index2, contact.normal, contact.point_self, contact.point_other, contact.velocity_self, contact.velocity_other, contact.impulse);
+		if (jolt_body1->IsActive()) {
+			for (const Contact &contact : manifold.contacts1) {
+				body1->add_contact(body2, manifold.depth, shape_index1, shape_index2, contact.normal, contact.point_self, contact.point_other, contact.velocity_self, contact.velocity_other, contact.impulse);
+			}
 		}
 
-		for (const Contact &contact : manifold.contacts2) {
-			body2->add_contact(body1, manifold.depth, shape_index2, shape_index1, contact.normal, contact.point_self, contact.point_other, contact.velocity_self, contact.velocity_other, contact.impulse);
+		if (jolt_body2->IsActive()) {
+			for (const Contact &contact : manifold.contacts2) {
+				body2->add_contact(body1, manifold.depth, shape_index2, shape_index1, contact.normal, contact.point_self, contact.point_other, contact.velocity_self, contact.velocity_other, contact.impulse);
+			}
 		}
 
 		manifold.contacts1.clear();


Test patch: