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

Sensor contact reporting issue #130

Closed
jankrassnigg opened this issue Apr 13, 2022 · 6 comments
Closed

Sensor contact reporting issue #130

jankrassnigg opened this issue Apr 13, 2022 · 6 comments

Comments

@jankrassnigg
Copy link
Contributor

I'm trying to get triggers working and I'm observing curios behavior. I use a custom ContactListener. On contact added, if one of the bodies is a sensor, I set my trigger to active and use the two body IDs to remember this contact. On contact removed, I use the two body IDs to check whether this was a sensor contact and deactivate my trigger again.

I now have a dynamic box, falling into a trigger, which correctly activates it, then the box stays there and thus goes to sleep.

With just this setup, everything works as expected. However, when I add a second body to the scene, which doesn't interact with the sensor at all, the moment it creates any contact, anywhere, with any other body, the sensor contact gets removed.

Stepping through the code, I see in ContactConstraintManager::ManifoldCache::ContactPointRemovedCallbacks that every frame, if there was a new contact, old contacts that didn't happen again this frame, get removed.

I assume that because my box came to rest within the sensor, and the sensor generally doesn't affect the dynamic body, this kind of contact is not persisted and thus gets erroneously cleaned up here.

This does not happen, if the body moving through the sensor is not yet sleeping, while the other contact happens.

@jankrassnigg
Copy link
Contributor Author

I'm seeing similar behavior with moving sensors. The documentation says sensors have to have motion type 'static' but can be moved around via SetPosition. However, contacts are only added and removed when the dynamic body is moving as well. A trigger that sweeps over a resting object won't get any contact report and existing contacts are not removed either (if nothing else in the scene happens).

In general, what's the recommended way to do moving trigger shapes? Is it better to just do overlap checks manually? For static triggers I can see that the physics engine can be more efficient, but for moving ones, would there be any benefit?

@jrouwe
Copy link
Owner

jrouwe commented Apr 13, 2022

Ah, I see what's going wrong here. Sensors are designed to only detect active dynamic bodies (they completely ignore any sleeping objects - sorry for not documenting this). The reason why you're not receiving the object removal callbacks is that in PhysicsSystem::Update there is an early out when there are no active bodies at all. So when you only have 1 body in the world and it goes to sleep, you don't get any callbacks, but as soon as another object becomes active the callback triggers.

I will fix the missing callback, and it would also be possible to support sensors detecting inactive bodies (I didn't need it), but it would come at a considerable cost (basically we'd need an extra parallel for over all sensors and check the broad/narrow phase for collisions with inactive bodies).

@jankrassnigg
Copy link
Contributor Author

I would argue that the extra cost is worth it. From a game engine perspective, sensors enable the very important use case to know when an object enter and leaves their area. The sleep state of a dynamic object is mostly an implementation detail of the physics engine and rarely of interest to the game, whereas the information "object has left the area" is often a critical piece of information for game mechanics. If an object goint to sleep can't be distinguished from an object leaving the area, that's a deal breaker.

So far I never had the use case for sensors that only give you active bodies, but if you have one and are worried about the additional performance penalty, maybe sensors could have a flag (or you just have two types of sensors), that enables detection of sleeping objects. Then you only pay that for sensors that really need it.

@jrouwe
Copy link
Owner

jrouwe commented Apr 15, 2022

I fixed the bug that the contact removal callbacks were triggered too late. I'll take a look at making those sensors detect inactive bodies. My current thinking is that if you activate a sensor (which is currently a no-op) that it will start reporting collisions with all bodies (sleeping/non-sleeping). An inactive sensor can only detect collisions with active bodies.

@jrouwe
Copy link
Owner

jrouwe commented Apr 16, 2022

Fixed in #133.

@jrouwe jrouwe closed this as completed Apr 16, 2022
@jankrassnigg
Copy link
Contributor Author

Awesome, thanks a lot! It looks like it's working exactly as needed now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants