box2d_rust/types/shape.rs
1// Shape and chain creation types and defaults from types.h / types.c.
2// SPDX-FileCopyrightText: 2023 Erin Catto
3// SPDX-License-Identifier: MIT
4
5use super::{DEFAULT_CATEGORY_BITS, DEFAULT_MASK_BITS};
6use crate::core::SECRET_COOKIE;
7use crate::math_functions::Vec2;
8
9/// Collision filtering data for shapes. (b2Filter)
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct Filter {
12 /// The collision category bits. Normally you would just set one bit.
13 pub category_bits: u64,
14 /// The collision mask bits: the categories this shape accepts for collision.
15 pub mask_bits: u64,
16 /// Collision groups: never collide (negative) or always collide (positive).
17 /// A group index of zero has no effect. Non-zero group filtering always
18 /// wins against the mask bits.
19 pub group_index: i32,
20}
21
22/// Initialize a filter with the default values. (b2DefaultFilter)
23pub fn default_filter() -> Filter {
24 Filter {
25 category_bits: DEFAULT_CATEGORY_BITS,
26 mask_bits: DEFAULT_MASK_BITS,
27 group_index: 0,
28 }
29}
30
31impl Default for Filter {
32 fn default() -> Self {
33 default_filter()
34 }
35}
36
37/// The query filter is used to filter collisions between queries and shapes.
38/// (b2QueryFilter)
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub struct QueryFilter {
41 /// The collision category bits of this query.
42 pub category_bits: u64,
43 /// The shape categories this query accepts for collision.
44 pub mask_bits: u64,
45}
46
47/// Initialize a query filter with the default values. (b2DefaultQueryFilter)
48pub fn default_query_filter() -> QueryFilter {
49 QueryFilter {
50 category_bits: DEFAULT_CATEGORY_BITS,
51 mask_bits: DEFAULT_MASK_BITS,
52 }
53}
54
55impl Default for QueryFilter {
56 fn default() -> Self {
57 default_query_filter()
58 }
59}
60
61/// Surface materials allow chain shapes to have per segment surface properties.
62/// (b2SurfaceMaterial)
63#[derive(Debug, Clone, Copy, PartialEq)]
64pub struct SurfaceMaterial {
65 /// The Coulomb (dry) friction coefficient, usually in the range [0,1].
66 pub friction: f32,
67 /// The coefficient of restitution (bounce), usually in the range [0,1].
68 pub restitution: f32,
69 /// The rolling resistance, usually in the range [0,1].
70 pub rolling_resistance: f32,
71 /// The tangent speed for conveyor belts.
72 pub tangent_speed: f32,
73 /// User material identifier, passed to friction/restitution callbacks and
74 /// query results. Not used internally.
75 pub user_material_id: u64,
76 /// Custom debug draw color.
77 pub custom_color: u32,
78}
79
80/// Initialize a surface material with the default values.
81/// (b2DefaultSurfaceMaterial)
82pub fn default_surface_material() -> SurfaceMaterial {
83 SurfaceMaterial {
84 friction: 0.6,
85 restitution: 0.0,
86 rolling_resistance: 0.0,
87 tangent_speed: 0.0,
88 user_material_id: 0,
89 custom_color: 0,
90 }
91}
92
93impl Default for SurfaceMaterial {
94 fn default() -> Self {
95 default_surface_material()
96 }
97}
98
99/// Used to create a shape. Must be initialized using [`default_shape_def`].
100/// (b2ShapeDef)
101#[derive(Debug, Clone, Copy, PartialEq)]
102pub struct ShapeDef {
103 /// Application specific shape data.
104 pub user_data: u64,
105 /// The surface material for this shape.
106 pub material: SurfaceMaterial,
107 /// The density, usually in kg/m^2.
108 pub density: f32,
109 /// Collision filtering data.
110 pub filter: Filter,
111 /// Enable custom filtering. Only one of the two shapes needs to enable it.
112 pub enable_custom_filtering: bool,
113 /// A sensor shape generates overlap events but no collision response.
114 pub is_sensor: bool,
115 /// Enable sensor events for this shape. False by default, even for sensors.
116 pub enable_sensor_events: bool,
117 /// Enable contact events for this shape. False by default.
118 pub enable_contact_events: bool,
119 /// Enable hit events for this shape. False by default.
120 pub enable_hit_events: bool,
121 /// Enable pre-solve contact events for this shape.
122 pub enable_pre_solve_events: bool,
123 /// When shapes are created they scan the environment for collision next
124 /// step. Ignored for dynamic and kinematic shapes.
125 pub invoke_contact_creation: bool,
126 /// Should the body update the mass properties when this shape is created.
127 pub update_body_mass: bool,
128 /// Used internally to detect a valid definition. DO NOT SET.
129 pub internal_value: i32,
130}
131
132/// Initialize a shape definition with the default values. (b2DefaultShapeDef)
133pub fn default_shape_def() -> ShapeDef {
134 ShapeDef {
135 user_data: 0,
136 // C zero-inits the material then sets friction = 0.6, which is exactly
137 // the default surface material.
138 material: default_surface_material(),
139 density: 1.0,
140 filter: default_filter(),
141 enable_custom_filtering: false,
142 is_sensor: false,
143 enable_sensor_events: false,
144 enable_contact_events: false,
145 enable_hit_events: false,
146 enable_pre_solve_events: false,
147 invoke_contact_creation: true,
148 update_body_mass: true,
149 internal_value: SECRET_COOKIE,
150 }
151}
152
153impl Default for ShapeDef {
154 fn default() -> Self {
155 default_shape_def()
156 }
157}
158
159/// Used to create a chain of line segments. Must be initialized using
160/// [`default_chain_def`]. (b2ChainDef)
161///
162/// The C struct uses `points`/`count` and `materials`/`materialCount` pointer +
163/// length pairs; the Rust port carries owned `Vec`s whose lengths encode the
164/// counts (the C notes these are cloned).
165#[derive(Debug, Clone, PartialEq, Default)]
166pub struct ChainDef {
167 /// Application specific shape data.
168 pub user_data: u64,
169 /// An array of at least 4 points.
170 pub points: Vec<Vec2>,
171 /// Surface materials. Must have length 1 (one material for all segments) or
172 /// `points.len()` (a unique material per segment).
173 pub materials: Vec<SurfaceMaterial>,
174 /// Contact filtering data.
175 pub filter: Filter,
176 /// Indicates a closed chain formed by connecting the first and last points.
177 pub is_loop: bool,
178 /// Enable sensors to detect this chain. False by default.
179 pub enable_sensor_events: bool,
180 /// Used internally to detect a valid definition. DO NOT SET.
181 pub internal_value: i32,
182}
183
184/// Initialize a chain definition with the default values. (b2DefaultChainDef)
185pub fn default_chain_def() -> ChainDef {
186 ChainDef {
187 user_data: 0,
188 points: Vec::new(),
189 materials: vec![default_surface_material()],
190 filter: default_filter(),
191 is_loop: false,
192 enable_sensor_events: false,
193 internal_value: SECRET_COOKIE,
194 }
195}