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}