From f59fe0847a1bdf0028326b71a3aab800ee339e78 Mon Sep 17 00:00:00 2001 From: Erin Catto Date: Sat, 9 Nov 2024 21:11:52 -0800 Subject: [PATCH] Update event documentation --- docs/overview.md | 1 + docs/simulation.md | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/docs/overview.md b/docs/overview.md index e2231f8ea..17ef4c66f 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -123,6 +123,7 @@ of the time step: - body movement events - contact begin and end events +- sensor begin and end events - contact hit events These events allow your application to react to changes in the simulation. diff --git a/docs/simulation.md b/docs/simulation.md index 4f88069fd..c826968cf 100644 --- a/docs/simulation.md +++ b/docs/simulation.md @@ -1009,21 +1009,34 @@ for (int i = 0; i < sensorEvents.beginCount; ++i) } ``` -And there are events when a shape stops overlapping with a sensor. +And there are events when a shape stops overlapping with a sensor. Be careful with end +touch events because they may be generated when shapes are destroyed. Test the shape +ids with `b2Shape_IsValid`. ```c for (int i = 0; i < sensorEvents.endCount; ++i) { b2SensorEndTouchEvent* endTouch = sensorEvents.endEvents + i; - void* myUserData = b2Shape_GetUserData(endTouch->visitorShapeId); - // process end event + if (b2Shape_IsValid(endTouch->visitorShapeId)) + { + void* myUserData = b2Shape_GetUserData(endTouch->visitorShapeId); + // process end event + } } ``` -You will not get end events if a shape is destroyed. Sensor events should -be processed after the world step and before other game logic. This should +Sensor events should be processed after the world step and before other game logic. This should help you avoid processing stale data. +There are several user operations that can cause sensors to stop touching. Such operations +include: +- destroying a body or shape +- changing the filter on a shape +- disabling a body +- setting the body transform +These may generate end-touch events and these events are included with simulation events available +after the next call to `b2World_Step`. + Sensor events are only enabled for a non-sensor shape if `b2ShapeDef::enableSensorEvents` is true. @@ -1065,11 +1078,17 @@ contain the two shape ids. for (int i = 0; i < contactEvents.endCount; ++i) { b2ContactEndTouchEvent* endEvent = contactEvents.endEvents + i; - ShapesStopTouching(endEvent->shapeIdA, endEvent->shapeIdB); + + // Use b2Shape_IsValid because a shape may have been destroyed + if (b2Shape_IsValid(endEvent->shapeIdA) && b2Shape_IsValid(endEvent->shapeIdB)) + { + ShapesStopTouching(endEvent->shapeIdA, endEvent->shapeIdB); + } } ``` -The end touch events are not generated when you destroy a shape or the body that owns it. +Similar to `b2SensorEndTouchEvent`, `b2ContactEndTouchEvent` may be generated due to a user operation, +such as destroying a body or shape. These events are included with simulation events after the next `b2World_Step`. Shapes only generate begin and end touch events if `b2ShapeDef::enableContactEvents` is true.