1use crate::b2_math::*;
2use crate::b2_common::B2_MAX_MANIFOLD_POINTS;
3use crate::b2_shape::*;
4use crate::private::collision as private;
5use crate::shapes::b2_circle_shape::*;
6use crate::shapes::b2_edge_shape::*;
7use crate::shapes::b2_polygon_shape::*;
8
9pub const B2_NULL_FEATURE: u8 = std::u8::MAX;
14
15pub enum B2contactFeatureType {
16 EVertex = 0,
17 EFace = 1,
18}
19
20#[derive(Clone, Default, Copy, Debug, PartialEq)]
23pub struct B2contactFeature {
24 pub index_a: u8,
26 pub index_b: u8,
28 pub type_a: u8,
30 pub type_b: u8,
32}
33
34#[derive(Clone, Default, Copy, Debug, PartialEq)]
36pub struct B2contactId {
37 pub cf: B2contactFeature,
38}
39
40#[derive(Clone, Copy, Debug, Default)]
51pub struct B2manifoldPoint {
52 pub local_point: B2vec2,
54 pub normal_impulse: f32,
56 pub tangent_impulse: f32,
58 pub id: B2contactId,
60}
61
62#[derive(Clone, Copy, Debug)]
63pub enum B2manifoldType {
64 ECircles,
65 EFaceA,
66 EFaceB,
67}
68
69impl Default for B2manifoldType {
70 fn default() -> Self {
71 return B2manifoldType::ECircles;
72 }
73}
74
75impl Default for B2manifold {
76 fn default() -> Self {
77 return B2manifold {
78 points: [B2manifoldPoint::default();B2_MAX_MANIFOLD_POINTS],
79 local_normal: B2vec2::default(),
80 local_point: B2vec2::default(),
81 manifold_type: B2manifoldType::ECircles,
82 point_count: 0,
83 };
84 }
85}
86
87#[derive(Clone, Copy, Debug)]
104pub struct B2manifold {
105 pub points: [B2manifoldPoint; B2_MAX_MANIFOLD_POINTS],
107 pub local_normal: B2vec2,
109 pub local_point: B2vec2,
111 pub manifold_type: B2manifoldType,
112 pub point_count: usize,
114}
115
116#[derive(Default, Clone, Copy, Debug)]
118pub struct B2worldManifold {
119 pub normal: B2vec2,
121 pub points: [B2vec2; B2_MAX_MANIFOLD_POINTS],
123 pub separations: [f32; B2_MAX_MANIFOLD_POINTS],
125}
126
127impl B2worldManifold {
128 pub fn initialize(
133 &mut self,
134 manifold: &B2manifold,
135 xf_a: B2Transform,
136 radius_a: f32,
137 xf_b: B2Transform,
138 radius_b: f32,
139 ) {
140 private::b2_collision::b2_world_manifold_initialize(
141 self, manifold, xf_a, radius_a, xf_b, radius_b,
142 );
143 }
144}
145
146#[derive(Clone, Copy, Debug, PartialEq)]
148pub enum B2pointState {
149 B2NullState,
151 B2AddState,
153 B2PersistState,
155 B2RemoveState,
157}
158
159impl Default for B2pointState {
160 fn default() -> Self {
161 B2pointState::B2NullState
162 }
163}
164
165pub fn b2_get_point_states(
168 state1: &mut [B2pointState; B2_MAX_MANIFOLD_POINTS],
169 state2: &mut [B2pointState; B2_MAX_MANIFOLD_POINTS],
170 manifold1: &B2manifold,
171 manifold2: &B2manifold,
172) {
173 private::b2_collision::b2_get_point_states(state1, state2, manifold1, manifold2);
174}
175
176#[derive(Clone, Default, Copy, Debug)]
178pub struct B2clipVertex {
179 pub v: B2vec2,
180 pub id: B2contactId,
181}
182
183#[derive(Clone, Copy, Debug)]
185pub struct B2rayCastInput {
186 pub p1: B2vec2,
187 pub p2: B2vec2,
188 pub max_fraction: f32,
189}
190
191#[derive(Default, Clone, Copy, Debug)]
194pub struct B2rayCastOutput {
195 pub normal: B2vec2,
196 pub fraction: f32,
197}
198
199#[derive(Default, Clone, Copy, Debug)]
201pub struct B2AABB {
202 pub lower_bound: B2vec2,
204 pub upper_bound: B2vec2,
206}
207
208impl B2AABB {
209 pub fn is_valid(self) -> bool {
211 return b2_aabb_is_valid(self);
212 }
213
214 pub fn get_center(self) -> B2vec2 {
216 return 0.5 * (self.lower_bound + self.upper_bound);
217 }
218
219 pub fn get_extents(self) -> B2vec2 {
221 return 0.5 * (self.upper_bound - self.lower_bound);
222 }
223
224 pub fn get_perimeter(self) -> f32 {
226 let wx = self.upper_bound.x - self.lower_bound.x;
227 let wy = self.upper_bound.y - self.lower_bound.y;
228 return 2.0 * (wx + wy);
229 }
230
231 pub fn combine(&mut self, aabb: B2AABB) {
233 self.lower_bound = b2_min_vec2(self.lower_bound, aabb.lower_bound);
234 self.upper_bound = b2_max_vec2(self.upper_bound, aabb.upper_bound);
235 }
236
237 pub fn combine_two(&mut self, aabb1: B2AABB, aabb2: B2AABB) {
239 self.lower_bound = b2_min_vec2(aabb1.lower_bound, aabb2.lower_bound);
240 self.upper_bound = b2_max_vec2(aabb1.upper_bound, aabb2.upper_bound);
241 }
242
243 pub fn contains(self, aabb: &B2AABB) -> bool {
245 let mut result = true;
246 result = result && self.lower_bound.x <= aabb.lower_bound.x;
247 result = result && self.lower_bound.y <= aabb.lower_bound.y;
248 result = result && aabb.upper_bound.x <= self.upper_bound.x;
249 result = result && aabb.upper_bound.y <= self.upper_bound.y;
250 return result;
251 }
252
253 pub fn ray_cast(self, output: &mut B2rayCastOutput, input: &B2rayCastInput) -> bool {
254 return private::b2_collision::b2_aabb_ray_cast(self, output, input);
255 }
256}
257
258pub fn b2_collide_circles(
260 manifold: &mut B2manifold,
261 circle_a: &B2circleShape,
262 xf_a: &B2Transform,
263 circle_b: &B2circleShape,
264 xf_b: &B2Transform,
265) {
266 private::b2_collide_circle::b2_collide_circles(manifold, circle_a, xf_a, circle_b, xf_b);
267}
268
269pub fn b2_collide_polygon_and_circle(
271 manifold: &mut B2manifold,
272 polygon_a: &B2polygonShape,
273 xf_a: &B2Transform,
274 circle_b: &B2circleShape,
275 xf_b: &B2Transform,
276) {
277 private::b2_collide_circle::b2_collide_polygon_and_circle(
278 manifold, polygon_a, xf_a, circle_b, xf_b,
279 );
280}
281
282pub fn b2_collide_polygons(
284 manifold: &mut B2manifold,
285 polygon_a: &B2polygonShape,
286 xf_a: &B2Transform,
287 polygon_b: &B2polygonShape,
288 xf_b: &B2Transform,
289) {
290 private::b2_collide_polygon::b2_collide_polygons(
291 manifold, *polygon_a, *xf_a, *polygon_b, *xf_b,
292 );
293}
294
295pub fn b2_collide_edge_and_circle(
297 manifold: &mut B2manifold,
298 edge_a: &B2edgeShape,
299 xf_a: &B2Transform,
300 circle_b: &B2circleShape,
301 xf_b: &B2Transform,
302) {
303 private::b2_collide_edge::b2_collide_edge_and_circle(manifold, edge_a, xf_a, circle_b, xf_b);
304}
305
306pub fn b2_collide_edge_and_polygon(
308 manifold: &mut B2manifold,
309 edge_a: &B2edgeShape,
310 xf_a: &B2Transform,
311 polygon_b: &B2polygonShape,
312 xf_b: &B2Transform,
313) {
314 private::b2_collide_edge::b2_collide_edge_and_polygon(manifold, edge_a, xf_a, polygon_b, xf_b);
315}
316
317pub fn b2_clip_segment_to_line(
319 v_out: &mut [B2clipVertex; 2],
320 v_in: [B2clipVertex; 2],
321 normal: B2vec2,
322 offset: f32,
323 vertex_index_a: usize,
324) -> usize {
325 return private::b2_collision::b2_clip_segment_to_line(
326 v_out,
327 v_in,
328 normal,
329 offset,
330 vertex_index_a,
331 );
332}
333
334pub fn b2_test_overlap_shapes(
336 shape_a: ShapePtr,
337 index_a: usize,
338 shape_b: ShapePtr,
339 index_b: usize,
340 xf_a: B2Transform,
341 xf_b: B2Transform,
342) -> bool {
343 return private::b2_collision::b2_test_overlap(shape_a, index_a, shape_b, index_b, xf_a, xf_b);
344}
345
346pub fn b2_aabb_is_valid(self_: B2AABB) -> bool {
349 let d: B2vec2 = self_.upper_bound - self_.lower_bound;
350 let mut valid: bool = d.x >= 0.0 && d.y >= 0.0;
351 valid = valid && self_.lower_bound.is_valid() && self_.upper_bound.is_valid();
352 return valid;
353}
354
355pub fn b2_test_overlap(a: B2AABB, b: B2AABB) -> bool {
356 let d1 = b.lower_bound - a.upper_bound;
357 let d2 = a.lower_bound - b.upper_bound;
358
359 if d1.x > 0.0 || d1.y > 0.0 {
360 return false;
361 }
362
363 if d2.x > 0.0 || d2.y > 0.0 {
364 return false;
365 }
366
367 return true;
368}