godot-jolt: Areas don't detect static bodies

Areas don’t detect static bodies. Areas work fine for character bodies, and rigid bodies, but not static bodies.

See the attached project, or simply create an area that overlaps with a static body and check get_overlapping_bodies or has_overlapping_bodies.

bug.zip

The attached project is C#, but I can probably throw together a GD script one if needed.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (12 by maintainers)

Commits related to this issue

Most upvoted comments

There’s a new flag BodyCreationSettings::mSensorDetectsStatic to make this possible in jrouwe/JoltPhysics#581.

Yep, after flipping the option in the project settings, areas detect static bodies just like in GD physics.

Thanks,

I know I would definitely prefer to opt-in to this behavior rather than have it enabled globally by default.

I must admit I’d be tempted to have it be opt-out just to make the migration path easier, because I do feel strongly about the drop-in aspect of this extension, but I also understand that a lot of people wouldn’t know or care to disable such a setting, even when suffering the negative side effects from it. Having it be opt-in (with a prominent warning) is probably the wiser choice.

I’m leaning towards adding an additional flag on a body next to the IsSensor flag that indicates if you want a sensor to collide with static objects.

How would this pair up with disabling mUseManifoldReduction on the sensors? I had to disable that for contacts to be added/removed in a predictable manner. Are there any negative interactions there that need to be considered?

Also, just to be clear, if one were to set up their collision layers/masks (object layers) in such a way that the static bodies were completely culled from any collision with the sensors, then this performance concern mostly goes away, right? Assuming that you only have a select few sensors that need to actually detect static bodies.

To quote Jolt’s documentation on sensors, which are the thing backing Area3D in Godot Jolt:

Sensors are normal rigid bodies that report contacts with other Dynamic or Kinematic bodies through the ContactListener interface.

So them not detecting static bodies is by design. Judging by the reply here it’s done for performance reasons.

I was under the impression that this was a limitation in Godot Physics as well, but when looking more closely it seems that was only an issue when the “Monitorable” property was disabled, as seen here. I’ll make sure to document this discrepancy.

As for a workaround, I suppose you could do what was suggested in that Jolt discussion and just do an intersect_shape yourself using the area’s shape(s), although you won’t be able to do that from C# right now, due to #270. Alternatively you could maybe create some sort of “ghost” kinematic body, using a dedicated collision layer, child that to your static object and use it as a sort of proxy body. I’m sure there are other interesting ways of going about it as well.

I’ll let you know when there’s some progress on this.

How would this pair up with disabling mUseManifoldReduction on the sensors?

This should work for static too (with the same performance cost).

Also, just to be clear, if one were to set up their collision layers/masks (object layers) in such a way that the static bodies were completely culled from any collision with the sensors, then this performance concern mostly goes away, right?

Yes, if people carefully set up their collision layers so that sensors don’t collide with static then there is no performance issue.

I know I would definitely prefer to opt-in to this behavior rather than have it enabled globally by default.

I’m easily seeing the perf gains had by switching to Jolt, and it’s worth a few minor workarounds needed for the change in behavior.

How would that compare in performance overall? Is using sensors with a contact listener mostly a convenience thing, and not so much an optimization, over just doing your own queries?

Sensors are quite simple in Jolt, it is really just a parallel for running over all sensors and checking what they collide with. It will utilize the contact cache, which reduces the amount of actual collision checks that need to be done (easily implemented yourself) and the parallel for is executed together with other physics work so that it leaves less gaps in scheduling compared to when you would do it yourself outside the physics update.

I’ve been thinking about this a bit more and now I’m leaning towards adding an additional flag on a body next to the IsSensor flag that indicates if you want a sensor to collide with static objects. It can be off by default and have a big warning that things will be expensive if you turn it on…

Bat man responding, 😄

I took a quick look and made this: https://github.com/jrouwe/JoltPhysics/tree/feature/sensors_vs_static

If you start the SensorTest you see that the ‘KinematicSensor’ will start detecting the floor. As you can see it’s quite a simple fix (I didn’t test it very well though so it might be buggy) but I’m very worried about the performance implications. Sensors in general tend to be quite large so I think this will end up wasting a lot of CPU cycles and it’s not easy to spot that you’re burning all these cycles because the code will probably ignore all collisions that its not interested in. As suggested in the other ticket, I would be more in favor of solving this by doing explicit collision checks to avoid polluting the contact cache with this information (could this be done in Godot Jolt’s Area3D implementation?).