box2d_rust/distance/types.rs
1// Distance-group types from include/box2d/collision.h.
2// SPDX-FileCopyrightText: 2023 Erin Catto
3// SPDX-License-Identifier: MIT
4
5use crate::hull::MAX_POLYGON_VERTICES;
6use crate::math_functions::{Rot, Transform, Vec2};
7
8/// A distance proxy used by the GJK algorithm. It encapsulates any shape.
9/// You can provide between 1 and [`MAX_POLYGON_VERTICES`] points and a radius.
10/// (b2ShapeProxy)
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub struct ShapeProxy {
13 /// The point cloud
14 pub points: [Vec2; MAX_POLYGON_VERTICES],
15 /// The number of points. Must be greater than 0.
16 pub count: i32,
17 /// The external radius of the point cloud. May be zero.
18 pub radius: f32,
19}
20
21impl Default for ShapeProxy {
22 fn default() -> Self {
23 ShapeProxy {
24 points: [Vec2::default(); MAX_POLYGON_VERTICES],
25 count: 0,
26 radius: 0.0,
27 }
28 }
29}
30
31/// Result of computing the distance between two line segments.
32/// (b2SegmentDistanceResult)
33#[derive(Debug, Clone, Copy, PartialEq, Default)]
34pub struct SegmentDistanceResult {
35 /// The closest point on the first segment
36 pub closest1: Vec2,
37 /// The closest point on the second segment
38 pub closest2: Vec2,
39 /// The barycentric coordinate on the first segment
40 pub fraction1: f32,
41 /// The barycentric coordinate on the second segment
42 pub fraction2: f32,
43 /// The squared distance between the closest points
44 pub distance_squared: f32,
45}
46
47/// Used to warm start the GJK simplex. If you call this function multiple times
48/// with nearby transforms this might improve performance. Otherwise you can
49/// zero initialize this. (b2SimplexCache)
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
51pub struct SimplexCache {
52 /// The number of stored simplex points
53 pub count: u16,
54 /// The cached simplex indices on shape A
55 pub index_a: [u8; 3],
56 /// The cached simplex indices on shape B
57 pub index_b: [u8; 3],
58}
59
60/// Input for [`shape_distance`](crate::distance::shape_distance).
61/// (b2DistanceInput)
62#[derive(Debug, Clone, Copy, PartialEq)]
63pub struct DistanceInput {
64 /// The proxy for shape A
65 pub proxy_a: ShapeProxy,
66 /// The proxy for shape B
67 pub proxy_b: ShapeProxy,
68 /// Transform of shape B in shape A's frame, the relative pose B in A
69 /// (`inv_mul_transforms(world_a, world_b)`). The query is origin
70 /// independent and runs in frame A.
71 pub transform: Transform,
72 /// Should the proxy radius be considered?
73 pub use_radii: bool,
74}
75
76/// Output for [`shape_distance`](crate::distance::shape_distance).
77/// (b2DistanceOutput)
78#[derive(Debug, Clone, Copy, PartialEq, Default)]
79pub struct DistanceOutput {
80 /// Closest point on shape A, in shape A's frame
81 pub point_a: Vec2,
82 /// Closest point on shape B, in shape A's frame
83 pub point_b: Vec2,
84 /// A to B normal in shape A's frame. Invalid if distance is zero.
85 pub normal: Vec2,
86 /// The final distance, zero if overlapped
87 pub distance: f32,
88 /// Number of GJK iterations used
89 pub iterations: i32,
90 /// The number of simplexes stored in the simplex array
91 pub simplex_count: i32,
92}
93
94/// Simplex vertex for debugging the GJK algorithm. (b2SimplexVertex)
95#[derive(Debug, Clone, Copy, PartialEq, Default)]
96pub struct SimplexVertex {
97 /// support point in proxy A
98 pub w_a: Vec2,
99 /// support point in proxy B
100 pub w_b: Vec2,
101 /// w_b - w_a
102 pub w: Vec2,
103 /// barycentric coordinate for closest point
104 pub a: f32,
105 /// w_a index
106 pub index_a: i32,
107 /// w_b index
108 pub index_b: i32,
109}
110
111/// Simplex from the GJK algorithm. (b2Simplex)
112#[derive(Debug, Clone, Copy, PartialEq, Default)]
113pub struct Simplex {
114 /// vertices
115 pub v1: SimplexVertex,
116 pub v2: SimplexVertex,
117 pub v3: SimplexVertex,
118 /// number of valid vertices
119 pub count: i32,
120}
121
122impl Simplex {
123 /// The C code walks `b2SimplexVertex* vertices[] = {&v1, &v2, &v3}`; these
124 /// accessors are the borrow-checked equivalent.
125 pub(crate) fn vertex(&self, index: i32) -> &SimplexVertex {
126 match index {
127 0 => &self.v1,
128 1 => &self.v2,
129 _ => &self.v3,
130 }
131 }
132
133 pub(crate) fn vertex_mut(&mut self, index: i32) -> &mut SimplexVertex {
134 match index {
135 0 => &mut self.v1,
136 1 => &mut self.v2,
137 _ => &mut self.v3,
138 }
139 }
140}
141
142/// Input parameters for [`shape_cast`](crate::distance::shape_cast).
143/// (b2ShapeCastPairInput)
144#[derive(Debug, Clone, Copy, PartialEq)]
145pub struct ShapeCastPairInput {
146 /// The proxy for shape A
147 pub proxy_a: ShapeProxy,
148 /// The proxy for shape B
149 pub proxy_b: ShapeProxy,
150 /// Transform of shape B in shape A's frame, the relative pose B in A
151 pub transform: Transform,
152 /// The translation of shape B, in A's frame
153 pub translation_b: Vec2,
154 /// The fraction of the translation to consider, typically 1
155 pub max_fraction: f32,
156 /// Allows shapes with a radius to move slightly closer if already touching
157 pub can_encroach: bool,
158}
159
160/// This describes the motion of a body/shape for TOI computation. Shapes are
161/// defined with respect to the body origin, which may not coincide with the
162/// center of mass. However, to support dynamics we must interpolate the center
163/// of mass position. (b2Sweep)
164#[derive(Debug, Clone, Copy, PartialEq)]
165pub struct Sweep {
166 /// Local center of mass position
167 pub local_center: Vec2,
168 /// Starting center of mass world position
169 pub c1: Vec2,
170 /// Ending center of mass world position
171 pub c2: Vec2,
172 /// Starting world rotation
173 pub q1: Rot,
174 /// Ending world rotation
175 pub q2: Rot,
176}
177
178/// Time of impact input. (b2TOIInput)
179#[derive(Debug, Clone, Copy, PartialEq)]
180pub struct ToiInput {
181 /// The proxy for shape A
182 pub proxy_a: ShapeProxy,
183 /// The proxy for shape B
184 pub proxy_b: ShapeProxy,
185 /// The movement of shape A
186 pub sweep_a: Sweep,
187 /// The movement of shape B
188 pub sweep_b: Sweep,
189 /// Defines the sweep interval [0, max_fraction]
190 pub max_fraction: f32,
191}
192
193/// Describes the TOI output. (b2TOIState)
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
195pub enum ToiState {
196 #[default]
197 Unknown,
198 Failed,
199 Overlapped,
200 Hit,
201 Separated,
202}
203
204/// Time of impact output. (b2TOIOutput)
205#[derive(Debug, Clone, Copy, PartialEq, Default)]
206pub struct ToiOutput {
207 /// The type of result
208 pub state: ToiState,
209 /// The hit point
210 pub point: Vec2,
211 /// The hit normal
212 pub normal: Vec2,
213 /// The sweep time of the collision
214 pub fraction: f32,
215}