Skip to main content

box2d_rust/
events.rs

1// Port of the event types from include/box2d/types.h (events group).
2//
3// The C aggregate views (b2SensorEvents, b2ContactEvents, b2BodyEvents,
4// b2JointEvents) are pointer+count pairs over world-owned arrays. The Rust
5// world API returns slices; b2BodyEvents/b2JointEvents collapse to a single
6// slice while SensorEvents/ContactEvents keep grouping structs because they
7// bundle several arrays.
8//
9// SPDX-FileCopyrightText: 2023 Erin Catto
10// SPDX-License-Identifier: MIT
11
12use crate::collision::Manifold;
13use crate::id::{BodyId, ContactId, JointId, ShapeId};
14use crate::math_functions::{Pos, Vec2, WorldTransform};
15
16/// A begin touch event is generated when a shape starts to overlap a sensor
17/// shape. (b2SensorBeginTouchEvent)
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct SensorBeginTouchEvent {
20    /// The id of the sensor shape
21    pub sensor_shape_id: ShapeId,
22    /// The id of the shape that began touching the sensor shape
23    pub visitor_shape_id: ShapeId,
24}
25
26/// An end touch event is generated when a shape stops overlapping a sensor
27/// shape. Always confirm the shape id is valid before use — either shape may
28/// have been destroyed. (b2SensorEndTouchEvent)
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub struct SensorEndTouchEvent {
31    /// The id of the sensor shape. @warning may have been destroyed
32    pub sensor_shape_id: ShapeId,
33    /// The id of the shape that stopped touching. @warning may have been destroyed
34    pub visitor_shape_id: ShapeId,
35}
36
37/// A begin touch event is generated when two shapes begin touching.
38/// (b2ContactBeginTouchEvent)
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub struct ContactBeginTouchEvent {
41    /// Id of the first shape
42    pub shape_id_a: ShapeId,
43    /// Id of the second shape
44    pub shape_id_b: ShapeId,
45    /// The transient contact id. May be destroyed automatically when the world
46    /// is modified or simulated.
47    pub contact_id: ContactId,
48}
49
50/// An end touch event is generated when two shapes stop touching.
51/// (b2ContactEndTouchEvent)
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53pub struct ContactEndTouchEvent {
54    /// Id of the first shape. @warning may have been destroyed
55    pub shape_id_a: ShapeId,
56    /// Id of the second shape. @warning may have been destroyed
57    pub shape_id_b: ShapeId,
58    /// Id of the contact. @warning may have been destroyed
59    pub contact_id: ContactId,
60}
61
62/// A hit touch event is generated when two shapes collide faster than the hit
63/// speed threshold. (b2ContactHitEvent)
64#[derive(Debug, Clone, Copy, PartialEq)]
65pub struct ContactHitEvent {
66    /// Id of the first shape
67    pub shape_id_a: ShapeId,
68    /// Id of the second shape
69    pub shape_id_b: ShapeId,
70    /// Id of the contact. @warning may have been destroyed
71    pub contact_id: ContactId,
72    /// Point where the shapes hit, a mid-point between the two surfaces.
73    pub point: Pos,
74    /// Normal vector pointing from shape A to shape B
75    pub normal: Vec2,
76    /// The speed the shapes are approaching. Always positive.
77    pub approach_speed: f32,
78}
79
80/// Body move event, triggered when a body moves due to simulation. Not
81/// reported for bodies moved by the user. (b2BodyMoveEvent)
82#[derive(Debug, Clone, Copy, PartialEq)]
83pub struct BodyMoveEvent {
84    pub user_data: u64,
85    pub transform: WorldTransform,
86    pub body_id: BodyId,
87    pub fell_asleep: bool,
88}
89
90/// Joint event, reported for awake joints whose force and/or torque exceed the
91/// threshold. (b2JointEvent)
92#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub struct JointEvent {
94    /// The joint id
95    pub joint_id: JointId,
96    /// The user data from the joint for convenience
97    pub user_data: u64,
98}
99
100/// Sensor events are buffered in the world and are available as begin/end
101/// events in the current time step. These are borrowed from world storage and
102/// invalidated by the next call to `world_step`. (b2SensorEvents)
103#[derive(Debug, Clone, Copy)]
104pub struct SensorEvents<'a> {
105    /// Events for shapes that began overlapping a sensor this step.
106    pub begin_events: &'a [SensorBeginTouchEvent],
107    /// Events for shapes that stopped overlapping a sensor. These are from the
108    /// previous buffer so the user doesn't need to flush events mid-step.
109    pub end_events: &'a [SensorEndTouchEvent],
110}
111
112/// Contact events are buffered in the world and are available as begin/end/hit
113/// events in the current time step. These are borrowed from world storage and
114/// invalidated by the next call to `world_step`. (b2ContactEvents)
115#[derive(Debug, Clone, Copy)]
116pub struct ContactEvents<'a> {
117    /// Events for shapes that began touching this step.
118    pub begin_events: &'a [ContactBeginTouchEvent],
119    /// Events for shapes that stopped touching. These are from the previous
120    /// buffer so the user doesn't need to flush events mid-step.
121    pub end_events: &'a [ContactEndTouchEvent],
122    /// Events for impacts above the hit-event threshold.
123    pub hit_events: &'a [ContactHitEvent],
124}
125
126/// The contact data for two shapes. By convention the manifold normal points
127/// from shape A to shape B. (b2ContactData)
128#[derive(Debug, Clone, Copy, PartialEq)]
129pub struct ContactData {
130    pub contact_id: ContactId,
131    pub shape_id_a: ShapeId,
132    pub shape_id_b: ShapeId,
133    pub manifold: Manifold,
134}