1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5pub const C2_MAX_POLYGON_VERTS: u32 = 8;
8
9#[derive(Debug, Copy, Clone)]
10pub struct c2v {
11 pub x: f32,
12 pub y: f32,
13}
14
15#[derive(Debug, Copy, Clone)]
16pub struct c2r {
17 pub c: f32,
18 pub s: f32,
19}
20
21#[derive(Debug, Copy, Clone)]
22pub struct c2m {
23 pub x: c2v,
24 pub y: c2v,
25}
26
27#[derive(Debug, Copy, Clone)]
28pub struct c2x {
29 pub p: c2v,
30 pub r: c2r,
31}
32
33#[derive(Debug, Copy, Clone)]
34pub struct c2h {
35 pub n: c2v,
36 pub d: f32,
37}
38
39#[derive(Debug, Copy, Clone)]
40pub struct c2Circle {
41 pub p: c2v,
42 pub r: f32,
43}
44
45#[derive(Debug, Copy, Clone)]
46pub struct c2AABB {
47 pub min: c2v,
48 pub max: c2v,
49}
50
51#[derive(Debug, Copy, Clone)]
52pub struct c2Capsule {
53 pub a: c2v,
54 pub b: c2v,
55 pub r: f32,
56}
57
58#[derive(Debug, Copy, Clone)]
59pub struct c2Poly {
60 pub count: ::std::os::raw::c_int,
61 pub verts: [c2v; 8usize],
62 pub norms: [c2v; 8usize],
63}
64
65#[derive(Debug, Copy, Clone)]
66pub struct c2Ray {
67 pub p: c2v,
68 pub d: c2v,
69 pub t: f32,
70}
71
72#[derive(Debug, Copy, Clone)]
73pub struct c2Raycast {
74 pub t: f32,
75 pub n: c2v,
76}
77
78#[derive(Debug, Copy, Clone)]
79pub struct c2Manifold {
80 pub count: ::std::os::raw::c_int,
81 pub depths: [f32; 2usize],
82 pub contact_points: [c2v; 2usize],
83 pub n: c2v,
84}
85
86fn c2Sub(mut a: c2v, b: c2v) -> c2v {
87 a.x -= b.x;
88 a.y -= b.y;
89 a
90}
91
92fn c2Dot(a: c2v, b: c2v) -> f32 {
93 a.x * b.x + a.y * b.y
94}
95
96pub unsafe fn c2CircletoCircle(A: c2Circle, B: c2Circle) -> ::std::os::raw::c_int {
97 let c: c2v = c2Sub(B.p, A.p);
98 let d2: f32 = c2Dot(c, c);
99 let mut r2: f32 = A.r + B.r;
100 r2 = r2 * r2;
101 if d2 < r2 {
102 1
103 } else {
104 0
105 }
106}
107
108fn c2V(x: f32, y: f32) -> c2v {
109 c2v { x, y }
110}
111
112fn c2Minv(a: c2v, b: c2v) -> c2v {
113 c2V(a.x.min(b.x), a.y.min(b.y))
114}
115fn c2Maxv(a: c2v, b: c2v) -> c2v {
116 c2V(a.x.max(b.x), a.y.max(b.y))
117}
118
119fn c2Clampv(a: c2v, lo: c2v, hi: c2v) -> c2v {
120 c2Maxv(lo, c2Minv(a, hi))
121}
122
123pub unsafe fn c2CircletoAABB(A: c2Circle, B: c2AABB) -> ::std::os::raw::c_int {
124 let L: c2v = c2Clampv(A.p, B.min, B.max);
125 let ab: c2v = c2Sub(A.p, L);
126 let d2: f32 = c2Dot(ab, ab);
127 let r2: f32 = A.r * A.r;
128 if d2 < r2 {
129 1
130 } else {
131 0
132 }
133}
134
135fn c2Mulvs(mut a: c2v, b: f32) -> c2v {
136 a.x *= b;
137 a.y *= b;
138 a
139}
140
141pub unsafe fn c2CircletoCapsule(A: c2Circle, B: c2Capsule) -> ::std::os::raw::c_int {
142 let n: c2v = c2Sub(B.b, B.a);
143 let ap = c2Sub(A.p, B.a);
144 let da = c2Dot(ap, n);
145 let d2: f32;
146
147 if da < 0.0 {
148 d2 = c2Dot(ap, ap);
149 } else {
150 let db = c2Dot(c2Sub(A.p, B.b), n);
151 if db < 0.0 {
152 let e = c2Sub(ap, c2Mulvs(n, da / c2Dot(n, n)));
153 d2 = c2Dot(e, e);
154 } else {
155 let bp = c2Sub(A.p, B.b);
156 d2 = c2Dot(bp, bp);
157 }
158 }
159
160 let r = A.r + B.r;
161 if d2 < r * r {
162 1
163 } else {
164 0
165 }
166}
167
168pub unsafe fn c2AABBtoAABB(A: c2AABB, B: c2AABB) -> ::std::os::raw::c_int {
169 let d0 = B.max.x < A.min.x;
170 let d1 = A.max.x < B.min.x;
171 let d2 = B.max.y < A.min.y;
172 let d3 = A.max.y < B.min.y;
173 if !(d0 | d1 | d2 | d3) {
174 1
175 } else {
176 0
177 }
178}
179
180fn c2AABBtoPoint(A: c2AABB, B: c2v) -> ::std::os::raw::c_int {
181 let d0 = B.x < A.min.x;
182 let d1 = B.y < A.min.y;
183 let d2 = B.x > A.max.x;
184 let d3 = B.y > A.max.y;
185 if !(d0 | d1 | d2 | d3) {
186 1
187 } else {
188 0
189 }
190}
191
192fn c2CircleToPoint(A: c2Circle, B: c2v) -> ::std::os::raw::c_int {
193 let n = c2Sub(A.p, B);
194 let d2 = c2Dot(n, n);
195 if d2 < A.r * A.r {
196 1
197 } else {
198 0
199 }
200}
201
202pub unsafe fn c2AABBtoCapsule(A: c2AABB, B: c2Capsule) -> ::std::os::raw::c_int {
203 if c2GJK(
204 &A as *const _ as *const std::os::raw::c_void,
205 C2_TYPE_C2_TYPE_AABB,
206 std::ptr::null(),
207 &B as *const _ as *const std::os::raw::c_void,
208 C2_TYPE_C2_TYPE_CAPSULE,
209 std::ptr::null(),
210 std::ptr::null_mut(),
211 std::ptr::null_mut(),
212 1,
213 std::ptr::null_mut(),
214 std::ptr::null_mut(),
215 ) != 0.0
216 {
217 return 0;
218 }
219 return 1;
220}
221
222pub unsafe fn c2CapsuletoCapsule(A: c2Capsule, B: c2Capsule) -> ::std::os::raw::c_int {
223 if c2GJK(
224 &A as *const _ as *const std::os::raw::c_void,
225 C2_TYPE_C2_TYPE_CAPSULE,
226 std::ptr::null(),
227 &B as *const _ as *const std::os::raw::c_void,
228 C2_TYPE_C2_TYPE_CAPSULE,
229 std::ptr::null(),
230 std::ptr::null_mut(),
231 std::ptr::null_mut(),
232 1,
233 std::ptr::null_mut(),
234 std::ptr::null_mut(),
235 ) != 0.0
236 {
237 return 0;
238 }
239 return 1;
240}
241
242pub unsafe fn c2CircletoPoly(
243 A: c2Circle,
244 B: *const c2Poly,
245 bx: *const c2x,
246) -> ::std::os::raw::c_int {
247 if c2GJK(
248 &A as *const _ as *const std::os::raw::c_void,
249 C2_TYPE_C2_TYPE_CIRCLE,
250 std::ptr::null(),
251 B as *const _ as *const std::os::raw::c_void,
252 C2_TYPE_C2_TYPE_POLY,
253 bx,
254 std::ptr::null_mut(),
255 std::ptr::null_mut(),
256 1,
257 std::ptr::null_mut(),
258 std::ptr::null_mut(),
259 ) != 0.0
260 {
261 return 0;
262 }
263 return 1;
264}
265
266pub unsafe fn c2AABBtoPoly(A: c2AABB, B: *const c2Poly, bx: *const c2x) -> ::std::os::raw::c_int {
267 if c2GJK(
268 &A as *const _ as *const std::os::raw::c_void,
269 C2_TYPE_C2_TYPE_AABB,
270 std::ptr::null(),
271 B as *const _ as *const std::os::raw::c_void,
272 C2_TYPE_C2_TYPE_POLY,
273 bx,
274 std::ptr::null_mut(),
275 std::ptr::null_mut(),
276 1,
277 std::ptr::null_mut(),
278 std::ptr::null_mut(),
279 ) != 0.0
280 {
281 return 0;
282 }
283 return 1;
284}
285
286pub unsafe fn c2CapsuletoPoly(
287 A: c2Capsule,
288 B: *const c2Poly,
289 bx: *const c2x,
290) -> ::std::os::raw::c_int {
291 if c2GJK(
292 &A as *const _ as *const std::os::raw::c_void,
293 C2_TYPE_C2_TYPE_CAPSULE,
294 std::ptr::null(),
295 B as *const _ as *const std::os::raw::c_void,
296 C2_TYPE_C2_TYPE_POLY,
297 bx,
298 std::ptr::null_mut(),
299 std::ptr::null_mut(),
300 1,
301 std::ptr::null_mut(),
302 std::ptr::null_mut(),
303 ) != 0.0
304 {
305 return 0;
306 }
307 return 1;
308}
309
310pub unsafe fn c2PolytoPoly(
311 A: *const c2Poly,
312 ax: *const c2x,
313 B: *const c2Poly,
314 bx: *const c2x,
315) -> ::std::os::raw::c_int {
316 if c2GJK(
317 A as *const _ as *const std::os::raw::c_void,
318 C2_TYPE_C2_TYPE_POLY,
319 ax,
320 B as *const _ as *const std::os::raw::c_void,
321 C2_TYPE_C2_TYPE_POLY,
322 bx,
323 std::ptr::null_mut(),
324 std::ptr::null_mut(),
325 1,
326 std::ptr::null_mut(),
327 std::ptr::null_mut(),
328 ) != 0.0
329 {
330 return 0;
331 }
332 return 1;
333}
334
335fn c2Impact(ray: c2Ray, t: f32) -> c2v {
336 c2Add(ray.p, c2Mulvs(ray.d, t))
337}
338
339pub unsafe fn c2RaytoCircle(A: c2Ray, B: c2Circle, out: *mut c2Raycast) -> ::std::os::raw::c_int {
340 let p = B.p;
341 let m = c2Sub(A.p, p);
342 let c = c2Dot(m, m) - B.r * B.r;
343 let b = c2Dot(m, A.d);
344 let disc = b * b - c;
345 if disc < 0.0 {
346 return 0;
347 }
348
349 let t = -b - disc.sqrt();
350 if t >= 0.0 && t <= A.t {
351 (*out).t = t;
352 let impact = c2Impact(A, t);
353 (*out).n = c2Norm(c2Sub(impact, p));
354 return 1;
355 }
356 return 0;
357}
358
359pub unsafe fn c2RaytoAABB(A: c2Ray, B: c2AABB, out: *mut c2Raycast) -> ::std::os::raw::c_int {
360 let p0 = A.p;
361 let p1 = c2Impact(A, A.t);
362 let a_box = c2AABB {
363 min: c2Minv(p0, p1),
364 max: c2Maxv(p0, p1),
365 };
366
367 if c2AABBtoAABB(a_box, B) == 0 {
369 return 0;
370 }
371
372 let ab = c2Sub(p1, p0);
374 let n = c2Skew(ab);
375 let abs_n = c2Absv(n);
376 let half_extents = c2Mulvs(c2Sub(B.max, B.min), 0.5);
377 let center_of_b_box = c2Mulvs(c2Add(B.min, B.max), 0.5);
378 let d = c2Dot(n, c2Sub(p0, center_of_b_box)).abs() - c2Dot(abs_n, half_extents);
379 if d > 0.0 {
380 return 0;
381 }
382
383 let da0 = c2SignedDistPointToPlane_OneDimensional(p0.x, -1.0, B.min.x);
386 let db0 = c2SignedDistPointToPlane_OneDimensional(p1.x, -1.0, B.min.x);
387 let da1 = c2SignedDistPointToPlane_OneDimensional(p0.x, 1.0, B.max.x);
388 let db1 = c2SignedDistPointToPlane_OneDimensional(p1.x, 1.0, B.max.x);
389 let da2 = c2SignedDistPointToPlane_OneDimensional(p0.y, -1.0, B.min.y);
390 let db2 = c2SignedDistPointToPlane_OneDimensional(p1.y, -1.0, B.min.y);
391 let da3 = c2SignedDistPointToPlane_OneDimensional(p0.y, 1.0, B.max.y);
392 let db3 = c2SignedDistPointToPlane_OneDimensional(p1.y, 1.0, B.max.y);
393 let mut t0 = c2RayToPlane_OneDimensional(da0, db0);
394 let mut t1 = c2RayToPlane_OneDimensional(da1, db1);
395 let mut t2 = c2RayToPlane_OneDimensional(da2, db2);
396 let mut t3 = c2RayToPlane_OneDimensional(da3, db3);
397
398 let hit0 = t0 < 1.0;
400 let hit1 = t1 < 1.0;
401 let hit2 = t2 < 1.0;
402 let hit3 = t3 < 1.0;
403 let hit = hit0 | hit1 | hit2 | hit3;
404
405 if hit {
406 t0 = hit0 as i32 as f32 * t0;
408 t1 = hit1 as i32 as f32 * t1;
409 t2 = hit2 as i32 as f32 * t2;
410 t3 = hit3 as i32 as f32 * t3;
411
412 if t0 >= t1 && t0 >= t2 && t0 >= t3 {
414 (*out).t = t0 * A.t;
415 (*out).n = c2V(-1.0, 0.0);
416 } else if t1 >= t0 && t1 >= t2 && t1 >= t3 {
417 (*out).t = t1 * A.t;
418 (*out).n = c2V(1.0, 0.0);
419 } else if t2 >= t0 && t2 >= t1 && t2 >= t3 {
420 (*out).t = t2 * A.t;
421 (*out).n = c2V(0.0, -1.0);
422 } else {
423 (*out).t = t3 * A.t;
424 (*out).n = c2V(0.0, 1.0);
425 }
426
427 return 1;
428 } else {
429 return 0;
430 } }
432
433fn c2SignedDistPointToPlane_OneDimensional(p: f32, n: f32, d: f32) -> f32 {
434 p * n - d * n
435}
436
437fn c2RayToPlane_OneDimensional(da: f32, db: f32) -> f32 {
438 if da < 0.0 {
439 return 0.0;
440 }
441 else if da * db >= 0.0 {
443 return 1.0;
444 }
445 else
447 {
449 let d = da - db;
450 if d != 0.0 {
451 return da / d;
452 } else {
453 return 0.0;
455 }
456 }
457}
458
459fn c2MulmvT(a: c2m, b: c2v) -> c2v {
460 c2v {
461 x: a.x.x * b.x + a.x.y * b.y,
462 y: a.y.x * b.x + a.y.y * b.y,
463 }
464}
465
466pub unsafe fn c2RaytoCapsule(A: c2Ray, B: c2Capsule, out: *mut c2Raycast) -> ::std::os::raw::c_int {
467 let M = {
468 let y = c2Norm(c2Sub(B.b, B.a));
469 c2m { x: c2CCW90(y), y }
470 };
471
472 let cap_n = c2Sub(B.b, B.a);
475 let yBb = c2MulmvT(M, cap_n);
476 let yAp = c2MulmvT(M, c2Sub(A.p, B.a));
477 let yAd = c2MulmvT(M, A.d);
478 let yAe = c2Add(yAp, c2Mulvs(yAd, A.t));
479
480 let capsule_bb = c2AABB {
481 min: c2V(-B.r, 0.0),
482 max: c2V(B.r, yBb.y),
483 };
484
485 (*out).n = c2Norm(cap_n);
486 (*out).t = 0.0;
487
488 if c2AABBtoPoint(capsule_bb, yAp) != 0 {
490 return 1;
491 } else {
492 let capsule_a = c2Circle { p: B.a, r: B.r };
493 let capsule_b = c2Circle { p: B.b, r: B.r };
494
495 if c2CircleToPoint(capsule_a, A.p) != 0 {
496 return 1;
497 } else if c2CircleToPoint(capsule_b, A.p) != 0 {
498 return 1;
499 }
500 }
501
502 if yAe.x * yAp.x < 0.0 || yAe.x.abs().min(yAp.x.abs()) < B.r {
503 let Ca = c2Circle { p: B.a, r: B.r };
504 let Cb = c2Circle { p: B.b, r: B.r };
505
506 if yAp.x.abs() < B.r {
508 if yAp.y < 0.0 {
509 return c2RaytoCircle(A, Ca, out);
510 } else {
511 return c2RaytoCircle(A, Cb, out);
512 }
513 }
514 else {
516 let c = if yAp.x > 0.0 { B.r } else { -B.r };
517 let d = yAe.x - yAp.x;
518 let t = (c - yAp.x) / d;
519 let y = yAp.y + (yAe.y - yAp.y) * t;
520 if y <= 0.0 {
521 return c2RaytoCircle(A, Ca, out);
522 }
523 if y >= yBb.y {
524 return c2RaytoCircle(A, Cb, out);
525 } else {
526 (*out).n = if c > 0.0 { M.x } else { c2Skew(M.y) };
527 (*out).t = t * A.t;
528 return 1;
529 }
530 }
531 }
532
533 return 0;
534}
535
536pub unsafe fn c2RaytoPoly(
537 A: c2Ray,
538 B: *const c2Poly,
539 bx_ptr: *const c2x,
540 out: *mut c2Raycast,
541) -> ::std::os::raw::c_int {
542 let bx = if !bx_ptr.is_null() {
543 *bx_ptr
544 } else {
545 c2xIdentity()
546 };
547 let p = c2MulxvT(bx, A.p);
548 let d = c2MulrvT(bx.r, A.d);
549 let mut lo = 0.0;
550 let mut hi = A.t;
551 let mut index = !0;
552
553 for i in 0..(*B).count as usize {
555 let num = c2Dot((*B).norms[i], c2Sub((*B).verts[i], p));
556 let den = c2Dot((*B).norms[i], d);
557 if den == 0.0 && num < 0.0 {
558 return 0;
559 } else {
560 if den < 0.0 && num < lo * den {
561 lo = num / den;
562 index = i;
563 } else if den > 0.0 && num < hi * den {
564 hi = num / den;
565 }
566 }
567 if hi < lo {
568 return 0;
569 }
570 }
571
572 if index != !0 {
573 (*out).t = lo;
574 (*out).n = c2Mulrv(bx.r, (*B).norms[index]);
575 return 1;
576 }
577
578 return 0;
579}
580
581pub unsafe fn c2CircletoCircleManifold(A: c2Circle, B: c2Circle, m: *mut c2Manifold) {
582 (*m).count = 0;
583 let d = c2Sub(B.p, A.p);
584 let d2 = c2Dot(d, d);
585 let r = A.r + B.r;
586 if d2 < r * r {
587 let l = d2.sqrt();
588 let n = if l != 0.0 {
589 c2Mulvs(d, 1.0 / l)
590 } else {
591 c2V(0.0, 1.0)
592 };
593 (*m).count = 1;
594 (*m).depths[0] = r - l;
595 (*m).contact_points[0] = c2Sub(B.p, c2Mulvs(n, B.r));
596 (*m).n = n;
597 }
598}
599
600fn c2Absv(a: c2v) -> c2v {
601 return c2V(a.x.abs(), a.y.abs());
602}
603
604pub unsafe fn c2CircletoAABBManifold(A: c2Circle, B: c2AABB, m: *mut c2Manifold) {
605 (*m).count = 0;
606 let L = c2Clampv(A.p, B.min, B.max);
607 let ab = c2Sub(L, A.p);
608 let d2 = c2Dot(ab, ab);
609 let r2 = A.r * A.r;
610 if d2 < r2 {
611 if d2 != 0.0 {
613 let d = d2.sqrt();
614 let n = c2Norm(ab);
615 (*m).count = 1;
616 (*m).depths[0] = A.r - d;
617 (*m).contact_points[0] = c2Add(A.p, c2Mulvs(n, d));
618 (*m).n = n;
619 }
620 else {
623 let mid = c2Mulvs(c2Add(B.min, B.max), 0.5);
624 let e = c2Mulvs(c2Sub(B.max, B.min), 0.5);
625 let d = c2Sub(A.p, mid);
626 let abs_d = c2Absv(d);
627
628 let x_overlap = e.x - abs_d.x;
629 let y_overlap = e.y - abs_d.y;
630
631 let depth;
632 let mut n;
633
634 if x_overlap < y_overlap {
635 depth = x_overlap;
636 n = c2V(1.0, 0.0);
637 n = c2Mulvs(n, if d.x < 0.0 { 1.0 } else { -1.0 });
638 } else {
639 depth = y_overlap;
640 n = c2V(0.0, 1.0);
641 n = c2Mulvs(n, if d.y < 0.0 { 1.0 } else { -1.0 });
642 }
643
644 (*m).count = 1;
645 (*m).depths[0] = A.r + depth;
646 (*m).contact_points[0] = c2Sub(A.p, c2Mulvs(n, depth));
647 (*m).n = n;
648 }
649 }
650}
651
652pub unsafe fn c2CircletoCapsuleManifold(A: c2Circle, B: c2Capsule, m: *mut c2Manifold) {
653 (*m).count = 0;
654 let mut a = c2V(0.0, 0.0);
655 let mut b = c2V(0.0, 0.0);
656 let r = A.r + B.r;
657 let d = c2GJK(
658 &A as *const _ as *const std::os::raw::c_void,
659 C2_TYPE_C2_TYPE_CIRCLE,
660 std::ptr::null_mut(),
661 &B as *const _ as *const std::os::raw::c_void,
662 C2_TYPE_C2_TYPE_CAPSULE,
663 std::ptr::null_mut(),
664 &mut a,
665 &mut b,
666 0,
667 std::ptr::null_mut(),
668 std::ptr::null_mut(),
669 );
670 if d < r {
671 let n;
672 if d == 0.0 {
673 n = c2Norm(c2Skew(c2Sub(B.b, B.a)));
674 } else {
675 n = c2Norm(c2Sub(b, a));
676 }
677
678 (*m).count = 1;
679 (*m).depths[0] = r - d;
680 (*m).contact_points[0] = c2Sub(b, c2Mulvs(n, B.r));
681 (*m).n = n;
682 }
683}
684
685pub unsafe fn c2AABBtoAABBManifold(A: c2AABB, B: c2AABB, m: *mut c2Manifold) {
686 (*m).count = 0;
687 let mid_a = c2Mulvs(c2Add(A.min, A.max), 0.5);
688 let mid_b = c2Mulvs(c2Add(B.min, B.max), 0.5);
689 let eA = c2Absv(c2Mulvs(c2Sub(A.max, A.min), 0.5));
690 let eB = c2Absv(c2Mulvs(c2Sub(B.max, B.min), 0.5));
691 let d = c2Sub(mid_b, mid_a);
692
693 let dx = eA.x + eB.x - d.x.abs();
695 if dx < 0.0 {
696 return;
697 }
698 let dy = eA.y + eB.y - d.y.abs();
699 if dy < 0.0 {
700 return;
701 }
702
703 let n;
704 let depth;
705 let p;
706
707 if dx < dy {
709 depth = dx;
710 if d.x < 0.0 {
711 n = c2V(-1.0, 0.0);
712 p = c2Sub(mid_a, c2V(eA.x, 0.0));
713 } else {
714 n = c2V(1.0, 0.0);
715 p = c2Add(mid_a, c2V(eA.x, 0.0));
716 }
717 }
718 else {
720 depth = dy;
721 if d.y < 0.0 {
722 n = c2V(0.0, -1.0);
723 p = c2Sub(mid_a, c2V(0.0, eA.y));
724 } else {
725 n = c2V(0.0, 1.0);
726 p = c2Add(mid_a, c2V(0.0, eA.y));
727 }
728 }
729
730 (*m).count = 1;
731 (*m).contact_points[0] = p;
732 (*m).depths[0] = depth;
733 (*m).n = n;
734}
735
736pub unsafe fn c2AABBtoCapsuleManifold(A: c2AABB, B: c2Capsule, m: *mut c2Manifold) {
737 (*m).count = 0;
738 let mut p = c2Poly {
739 count: 0,
740 verts: [c2V(0.0, 0.0); C2_MAX_POLYGON_VERTS as usize],
741 norms: [c2V(0.0, 0.0); C2_MAX_POLYGON_VERTS as usize],
742 };
743 c2BBVerts(&mut p.verts, &A);
744 p.count = 4;
745 c2Norms(&mut p.verts, &mut p.norms, 4);
746 c2CapsuletoPolyManifold(B, &p, std::ptr::null(), m);
747 (*m).n = c2Neg((*m).n);
748}
749
750pub unsafe fn c2CapsuletoCapsuleManifold(A: c2Capsule, B: c2Capsule, m: *mut c2Manifold) {
751 {
752 (*m).count = 0;
753 let mut a = c2V(0.0, 0.0);
754 let mut b = c2V(0.0, 0.0);
755 let r = A.r + B.r;
756 let d = c2GJK(
757 &A as *const _ as *const std::os::raw::c_void,
758 C2_TYPE_C2_TYPE_CAPSULE,
759 std::ptr::null_mut(),
760 &B as *const _ as *const std::os::raw::c_void,
761 C2_TYPE_C2_TYPE_CAPSULE,
762 std::ptr::null_mut(),
763 &mut a,
764 &mut b,
765 0,
766 std::ptr::null_mut(),
767 std::ptr::null_mut(),
768 );
769 if d < r {
770 let n;
771 if d == 0.0 {
772 n = c2Norm(c2Skew(c2Sub(A.b, A.a)));
773 } else {
774 n = c2Norm(c2Sub(b, a));
775 }
776
777 (*m).count = 1;
778 (*m).depths[0] = r - d;
779 (*m).contact_points[0] = c2Sub(b, c2Mulvs(n, B.r));
780 (*m).n = n;
781 }
782 }
783}
784
785fn c2MulxvT(a: c2x, b: c2v) -> c2v {
786 return c2MulrvT(a.r, c2Sub(b, a.p));
787}
788
789fn c2MulrvT(a: c2r, b: c2v) -> c2v {
790 return c2V(a.c * b.x + a.s * b.y, -a.s * b.x + a.c * b.y);
791}
792
793unsafe fn c2PlaneAt(p: *const c2Poly, i: i32) -> c2h {
794 c2h {
795 n: (*p).norms[i as usize],
796 d: c2Dot((*p).norms[i as usize], (*p).verts[i as usize]),
797 }
798}
799
800fn c2Dist(h: c2h, p: c2v) -> f32 {
801 return c2Dot(h.n, p) - h.d;
802}
803
804fn c2Project(h: c2h, p: c2v) -> c2v {
805 return c2Sub(p, c2Mulvs(h.n, c2Dist(h, p)));
806}
807
808pub unsafe fn c2CircletoPolyManifold(
809 A: c2Circle,
810 B: *const c2Poly,
811 bx_tr: *const c2x,
812 m: *mut c2Manifold,
813) {
814 (*m).count = 0;
815 let mut a = c2V(0.0, 0.0);
816 let mut b = c2V(0.0, 0.0);
817 let mut d = c2GJK(
818 &A as *const _ as *const std::os::raw::c_void,
819 C2_TYPE_C2_TYPE_CIRCLE,
820 std::ptr::null_mut(),
821 B as *const _ as *const std::os::raw::c_void,
822 C2_TYPE_C2_TYPE_POLY,
823 bx_tr,
824 &mut a,
825 &mut b,
826 0,
827 std::ptr::null_mut(),
828 std::ptr::null_mut(),
829 );
830
831 if d != 0.0 {
834 let n = c2Sub(b, a);
835 let mut l = c2Dot(n, n);
836 if l < A.r * A.r {
837 l = l.sqrt();
838 (*m).count = 1;
839 (*m).contact_points[0] = b;
840 (*m).depths[0] = A.r - l;
841 (*m).n = c2Mulvs(n, 1.0 / l);
842 }
843 }
844 else {
847 let bx = if !bx_tr.is_null() {
848 *bx_tr
849 } else {
850 c2xIdentity()
851 };
852 let mut sep = -std::f32::MAX;
853 let mut index = !0;
854 let local = c2MulxvT(bx, A.p);
855
856 for i in 0..(*B).count {
857 {
858 let h = c2PlaneAt(B, i);
859 d = c2Dist(h, local);
860 if d > A.r {
861 return;
862 }
863 if d > sep {
864 sep = d;
865 index = i;
866 }
867 }
868
869 let h = c2PlaneAt(B, index);
870 let p = c2Project(h, local);
871 (*m).count = 1;
872 (*m).contact_points[0] = c2Mulxv(bx, p);
873 (*m).depths[0] = A.r - sep;
874 (*m).n = c2Neg(c2Mulrv(bx.r, (*B).norms[index as usize]));
875 }
876 }
877}
878
879pub unsafe fn c2AABBtoPolyManifold(
880 A: c2AABB,
881 B: *const c2Poly,
882 bx: *const c2x,
883 m: *mut c2Manifold,
884) {
885 (*m).count = 0;
886 let mut p = c2Poly {
887 count: 0,
888 verts: [c2V(0.0, 0.0); C2_MAX_POLYGON_VERTS as usize],
889 norms: [c2V(0.0, 0.0); C2_MAX_POLYGON_VERTS as usize],
890 };
891 c2BBVerts(&mut p.verts, &A);
892 p.count = 4;
893 c2Norms(&mut p.verts, &mut p.norms, 4);
894 c2PolytoPolyManifold(&p, std::ptr::null(), B, bx, m);
895}
896
897unsafe fn c2SidePlanesFromPoly(
898 seg: &mut [c2v; 2],
899 x: c2x,
900 p: *const c2Poly,
901 e: i32,
902 h: *mut c2h,
903) -> i32 {
904 let ra = c2Mulxv(x, (*p).verts[e as usize]);
905 let rb = c2Mulxv(
906 x,
907 (*p).verts[if e + 1 == if (*p).count != 0 { 0 } else { e + 1 } {
908 1
909 } else {
910 0
911 }],
912 );
913 return c2SidePlanes(seg, ra, rb, h);
914}
915
916unsafe fn c2Clip(seg: &mut [c2v; 2], h: c2h) -> i32 {
918 let mut out: [c2v; 2] = [c2V(0.0, 0.0); 2];
919 let mut sp = 0;
920 let d0: f32;
921 let d1: f32;
922 d0 = c2Dist(h, seg[0]);
923 if (d0) < 0.0 {
924 out[sp] = seg[0];
925 sp += 1;
926 }
927 d1 = c2Dist(h, seg[1]);
928 if (d1) < 0.0 {
929 out[sp] = seg[1];
930 sp += 1
931 }
932 if d0 == 0.0 && d1 == 0.0 {
933 out[sp] = seg[0];
934 sp += 1;
935 out[sp] = seg[1];
936 sp += 1;
937 } else if d0 * d1 <= 0.0 {
938 out[sp] = c2Intersect(seg[0], seg[1], d0, d1);
939 sp += 1;
940 }
941 seg[0] = out[0];
942 seg[1] = out[1];
943 return sp as i32;
944}
945
946fn c2Intersect(a: c2v, b: c2v, da: f32, db: f32) -> c2v {
947 return c2Add(a, c2Mulvs(c2Sub(b, a), da / (da - db)));
948}
949
950unsafe fn c2SidePlanes(seg: &mut [c2v; 2], ra: c2v, rb: c2v, h: *mut c2h) -> i32 {
951 let _in = c2Norm(c2Sub(rb, ra));
952 let left = c2h {
953 n: c2Neg(_in),
954 d: c2Dot(c2Neg(_in), ra),
955 };
956 let right = c2h {
957 n: _in,
958 d: c2Dot(_in, rb),
959 };
960 if c2Clip(seg, left) < 2 {
961 return 0;
962 }
963 if c2Clip(seg, right) < 2 {
964 return 0;
965 }
966 if !h.is_null() {
967 (*h).n = c2CCW90(_in);
968 (*h).d = c2Dot(c2CCW90(_in), ra);
969 }
970 return 1;
971}
972
973unsafe fn c2KeepDeep(seg: &mut [c2v; 2], h: c2h, m: *mut c2Manifold) {
974 let mut cp = 0;
975 for i in 0..2 {
976 let p = seg[i];
977 let d = c2Dist(h, p);
978 if d <= 0.0 {
979 (*m).contact_points[cp] = p;
980 (*m).depths[cp] = -d;
981 cp += 1;
982 }
983 }
984 (*m).count = cp as i32;
985 (*m).n = h.n;
986}
987
988unsafe fn c2Incident(
989 incident: &mut [c2v; 2],
990 ip: *const c2Poly,
991 ix: c2x,
992 rn_in_incident_space: c2v,
993) {
994 let mut index: i32 = !0;
995 let mut min_dot = std::f32::MAX;
996 for i in 0..(*ip).count {
997 let dot = c2Dot(rn_in_incident_space, (*ip).norms[i as usize]);
998 if dot < min_dot {
999 min_dot = dot;
1000 index = i;
1001 }
1002 }
1003 incident[0] = c2Mulxv(ix, (*ip).verts[index as usize]);
1004 incident[1] = c2Mulxv(
1005 ix,
1006 (*ip).verts[(index + 1 == if (*ip).count != 0 { 0 } else { index + 1 }) as usize],
1007 );
1008}
1009
1010pub unsafe fn c2CapsuletoPolyManifold(
1011 A: c2Capsule,
1012 B: *const c2Poly,
1013 bx_ptr: *const c2x,
1014 m: *mut c2Manifold,
1015) {
1016 (*m).count = 0;
1017 let mut a = c2V(0.0, 0.0);
1018 let mut b = c2V(0.0, 0.0);
1019 let d = c2GJK(
1020 &A as *const _ as *const std::os::raw::c_void,
1021 C2_TYPE_C2_TYPE_CAPSULE,
1022 std::ptr::null_mut(),
1023 B as *const _ as *const std::os::raw::c_void,
1024 C2_TYPE_C2_TYPE_POLY,
1025 bx_ptr,
1026 &mut a,
1027 &mut b,
1028 0,
1029 std::ptr::null_mut(),
1030 std::ptr::null_mut(),
1031 );
1032
1033 if d < 1.0e-6 {
1035 let bx = if !bx_ptr.is_null() {
1036 *bx_ptr
1037 } else {
1038 c2xIdentity()
1039 };
1040 let mut A_in_B = c2Capsule {
1041 a: c2V(0.0, 0.0),
1042 b: c2V(0.0, 0.0),
1043 r: 0.0,
1044 };
1045 A_in_B.a = c2MulxvT(bx, A.a);
1046 A_in_B.b = c2MulxvT(bx, A.b);
1047 let ab = c2Norm(c2Sub(A_in_B.a, A_in_B.b));
1048
1049 let mut ab_h0 = c2h {
1051 n: c2V(0.0, 0.0),
1052 d: 0.0,
1053 };
1054 ab_h0.n = c2CCW90(ab);
1055 ab_h0.d = c2Dot(A_in_B.a, ab_h0.n);
1056 let v0 = c2Support((*B).verts, (*B).count, c2Neg(ab_h0.n));
1057 let s0 = c2Dist(ab_h0, (*B).verts[v0 as usize]);
1058
1059 let mut ab_h1 = c2h {
1060 n: c2V(0.0, 0.0),
1061 d: 0.0,
1062 };
1063 ab_h1.n = c2Skew(ab);
1064 ab_h1.d = c2Dot(A_in_B.a, ab_h1.n);
1065 let v1 = c2Support((*B).verts, (*B).count, c2Neg(ab_h1.n));
1066 let s1 = c2Dist(ab_h1, (*B).verts[v1 as usize]);
1067
1068 let mut index = !0;
1070 let mut sep = -std::f32::MAX;
1071 let mut code = 0;
1072 for i in 0..(*B).count {
1073 let h = c2PlaneAt(B, i);
1074 let da = c2Dot(A_in_B.a, c2Neg(h.n));
1075 let db = c2Dot(A_in_B.b, c2Neg(h.n));
1076 let d;
1077 if da > db {
1078 d = c2Dist(h, A_in_B.a);
1079 } else {
1080 d = c2Dist(h, A_in_B.b);
1081 }
1082 if d > sep {
1083 sep = d;
1084 index = i;
1085 }
1086 }
1087
1088 if s0 > sep {
1090 sep = s0;
1091 index = v0;
1092 code = 1;
1093 }
1094
1095 if s1 > sep {
1096 index = v1;
1097 code = 2;
1098 }
1099
1100 match code {
1101 0 => {
1103 let mut seg: [c2v; 2] = [A.a, A.b];
1104 let mut h = c2h {
1105 n: c2V(0.0, 0.0),
1106 d: 0.0,
1107 };
1108 if c2SidePlanesFromPoly(&mut seg, bx, B, index, &mut h) == 0 {
1109 return;
1110 }
1111 c2KeepDeep(&mut seg, h, m);
1112 (*m).n = c2Neg((*m).n);
1113 }
1114
1115 1 =>
1116 {
1118 let mut incident: [c2v; 2] = [c2V(0.0, 0.0); 2];
1119 c2Incident(&mut incident, B, bx, ab_h0.n);
1120 let mut h = c2h {
1121 n: c2V(0.0, 0.0),
1122 d: 0.0,
1123 };
1124 if c2SidePlanes(&mut incident, A_in_B.b, A_in_B.a, &mut h) == 0 {
1125 return;
1126 }
1127 c2KeepDeep(&mut incident, h, m);
1128 }
1129
1130 2 =>
1131 {
1133 let mut incident: [c2v; 2] = [c2V(0.0, 0.0); 2];
1134 c2Incident(&mut incident, B, bx, ab_h1.n);
1135 let mut h = c2h {
1136 n: c2V(0.0, 0.0),
1137 d: 0.0,
1138 };
1139 if c2SidePlanes(&mut incident, A_in_B.a, A_in_B.b, &mut h) == 0 {
1140 return;
1141 }
1142 c2KeepDeep(&mut incident, h, m);
1143 }
1144
1145 _ => {
1146 return;
1148 }
1149 }
1150
1151 for i in 0..(*m).count {
1152 (*m).depths[i as usize] += A.r;
1153 }
1154 }
1155 else if d < A.r {
1157 (*m).count = 1;
1158 (*m).n = c2Norm(c2Sub(b, a));
1159 (*m).contact_points[0] = c2Add(a, c2Mulvs((*m).n, A.r));
1160 (*m).depths[0] = A.r - d;
1161 }
1162}
1163
1164fn c2MulrrT(a: c2r, b: c2r) -> c2r {
1165 c2r {
1166 c: a.c * b.c + a.s * b.s,
1167 s: a.c * b.s - a.s * b.c,
1168 }
1169}
1170
1171fn c2MulxxT(a: c2x, b: c2x) -> c2x {
1172 c2x {
1173 r: c2MulrrT(a.r, b.r),
1174 p: c2MulrvT(a.r, c2Sub(b.p, a.p)),
1175 }
1176}
1177
1178unsafe fn c2CheckFaces(
1179 A: *const c2Poly,
1180 ax: c2x,
1181 B: *const c2Poly,
1182 bx: c2x,
1183 face_index: &mut i32,
1184) -> f32 {
1185 let b_in_a = c2MulxxT(ax, bx);
1186 let a_in_b = c2MulxxT(bx, ax);
1187 let mut sep = -std::f32::MAX;
1188 let mut index = !0;
1189
1190 for i in 0..(*A).count {
1191 let h = c2PlaneAt(A, i);
1192 let idx = c2Support((*B).verts, (*B).count, c2Mulrv(a_in_b.r, c2Neg(h.n)));
1193 let p = c2Mulxv(b_in_a, (*B).verts[idx as usize]);
1194 let d = c2Dist(h, p);
1195 if d > sep {
1196 sep = d;
1197 index = i;
1198 }
1199 }
1200
1201 *face_index = index;
1202 return sep;
1203}
1204
1205pub unsafe fn c2PolytoPolyManifold(
1206 A: *const c2Poly,
1207 ax_ptr: *const c2x,
1208 B: *const c2Poly,
1209 bx_ptr: *const c2x,
1210 m: *mut c2Manifold,
1211) {
1212 (*m).count = 0;
1213 let ax = if !ax_ptr.is_null() {
1214 *ax_ptr
1215 } else {
1216 c2xIdentity()
1217 };
1218 let bx = if !bx_ptr.is_null() {
1219 *bx_ptr
1220 } else {
1221 c2xIdentity()
1222 };
1223 let mut ea: i32 = 0;
1224 let mut eb: i32 = 0;
1225 let sa = c2CheckFaces(A, ax, B, bx, &mut ea);
1226 let sb = c2CheckFaces(B, bx, A, ax, &mut eb);
1227 if sa >= 0.0 {
1228 return;
1229 }
1230 if sb >= 0.0 {
1231 return;
1232 }
1233
1234 let rp: *const c2Poly;
1235 let ip: *const c2Poly;
1236 let rx: c2x;
1237 let ix: c2x;
1238 let re: i32;
1239 let kRelTol = 0.95;
1240 let kAbsTol = 0.01;
1241 let flip: i32;
1242 if sa * kRelTol > sb + kAbsTol {
1243 rp = A;
1244 rx = ax;
1245 ip = B;
1246 ix = bx;
1247 re = ea;
1248 flip = 0;
1249 } else {
1250 rp = B;
1251 rx = bx;
1252 ip = A;
1253 ix = ax;
1254 re = eb;
1255 flip = 1;
1256 }
1257
1258 let mut incident: [c2v; 2] = [c2V(0.0, 0.0); 2];
1259 c2Incident(
1260 &mut incident,
1261 ip,
1262 ix,
1263 c2MulrvT(ix.r, c2Mulrv(rx.r, (*rp).norms[re as usize])),
1264 );
1265 let mut rh = c2h {
1266 n: c2V(0.0, 0.0),
1267 d: 0.0,
1268 };
1269 if c2SidePlanesFromPoly(&mut incident, rx, rp, re, &mut rh) == 0 {
1270 return;
1271 }
1272 c2KeepDeep(&mut incident, rh, m);
1273 if flip != 0 {
1274 (*m).n = c2Neg((*m).n);
1275 }
1276}
1277
1278pub const C2_TYPE_C2_TYPE_NONE: C2_TYPE = 0;
1279pub const C2_TYPE_C2_TYPE_CIRCLE: C2_TYPE = 1;
1280pub const C2_TYPE_C2_TYPE_AABB: C2_TYPE = 2;
1281pub const C2_TYPE_C2_TYPE_CAPSULE: C2_TYPE = 3;
1282pub const C2_TYPE_C2_TYPE_POLY: C2_TYPE = 4;
1283pub type C2_TYPE = u32;
1284
1285#[derive(Debug, Copy, Clone)]
1286pub struct c2GJKCache {
1287 pub metric: f32,
1288 pub count: ::std::os::raw::c_int,
1289 pub iA: [::std::os::raw::c_int; 3usize],
1290 pub iB: [::std::os::raw::c_int; 3usize],
1291 pub div: f32,
1292}
1293
1294#[derive(Debug, Copy, Clone)]
1295struct c2Proxy {
1296 radius: f32,
1297 count: i32,
1298 verts: [c2v; C2_MAX_POLYGON_VERTS as usize],
1299}
1300
1301#[derive(Debug, Copy, Clone)]
1302struct c2sv {
1303 sA: c2v,
1304 sB: c2v,
1305 p: c2v,
1306 u: f32,
1307 iA: i32,
1308 iB: i32,
1309}
1310
1311#[derive(Debug, Copy, Clone)]
1312struct c2Simplex {
1313 a: c2sv,
1314 b: c2sv,
1315 c: c2sv,
1316 d: c2sv,
1317 div: f32,
1318 count: i32,
1319}
1320
1321fn c2Add(mut a: c2v, b: c2v) -> c2v {
1322 a.x += b.x;
1323 a.y += b.y;
1324 return a;
1325}
1326
1327fn c2Mulxv(a: c2x, b: c2v) -> c2v {
1328 return c2Add(c2Mulrv(a.r, b), a.p);
1329}
1330
1331fn c2Mulrv(a: c2r, b: c2v) -> c2v {
1332 return c2V(a.c * b.x - a.s * b.y, a.s * b.x + a.c * b.y);
1333}
1334
1335fn c2xIdentity() -> c2x {
1336 c2x {
1337 p: c2V(0.0, 0.0),
1338 r: c2RotIdentity(),
1339 }
1340}
1341
1342fn c2RotIdentity() -> c2r {
1343 c2r { c: 1.0, s: 0.0 }
1344}
1345
1346unsafe fn c2BBVerts(out: &mut [c2v; 8], bb: *const c2AABB) {
1347 out[0] = (*bb).min;
1348 out[1] = c2V((*bb).max.x, (*bb).min.y);
1349 out[2] = (*bb).max;
1350 out[3] = c2V((*bb).min.x, (*bb).max.y);
1351}
1352
1353unsafe fn c2MakeProxy(shape: *const ::std::os::raw::c_void, _type: C2_TYPE, p: *mut c2Proxy) {
1354 match _type {
1355 C2_TYPE_C2_TYPE_CIRCLE => {
1356 let c = std::mem::transmute::<*const ::std::os::raw::c_void, *const c2Circle>(shape);
1357 (*p).radius = (*c).r;
1358 (*p).count = 1;
1359 (*p).verts[0] = (*c).p;
1360 }
1361
1362 C2_TYPE_C2_TYPE_AABB => {
1363 let bb = std::mem::transmute::<*const ::std::os::raw::c_void, *const c2AABB>(shape);
1364 (*p).radius = 0.0;
1365 (*p).count = 4;
1366 c2BBVerts(&mut (*p).verts, bb);
1367 }
1368
1369 C2_TYPE_C2_TYPE_CAPSULE => {
1370 let c = std::mem::transmute::<*const ::std::os::raw::c_void, *const c2Capsule>(shape);
1371 (*p).radius = (*c).r;
1372 (*p).count = 2;
1373 (*p).verts[0] = (*c).a;
1374 (*p).verts[1] = (*c).b;
1375 }
1376
1377 C2_TYPE_C2_TYPE_POLY => {
1378 let poly = std::mem::transmute::<*const ::std::os::raw::c_void, *const c2Poly>(shape);
1379 (*p).radius = 0.0;
1380 (*p).count = (*poly).count;
1381 for i in 0..(*p).count as usize {
1382 (*p).verts[i] = (*poly).verts[i];
1383 }
1384 }
1385 _ => unreachable!(),
1386 }
1387}
1388
1389fn c2Len(a: c2v) -> f32 {
1390 c2Dot(a, a).sqrt()
1391}
1392
1393fn c2Det2(a: c2v, b: c2v) -> f32 {
1394 a.x * b.y - a.y * b.x
1395}
1396
1397unsafe fn c2GJKSimplexMetric(s: *const c2Simplex) -> f32 {
1398 match (*s).count {
1399 0 | 1 => 0.0,
1400 2 => c2Len(c2Sub((*s).b.p, (*s).a.p)),
1401 3 => c2Det2(c2Sub((*s).b.p, (*s).a.p), c2Sub((*s).c.p, (*s).a.p)),
1402 _ => unreachable!(),
1403 }
1404}
1405
1406const C2_GJK_ITERS: i32 = 20;
1407
1408unsafe fn c22(s: *mut c2Simplex) {
1409 let a = (*s).a.p;
1410 let b = (*s).b.p;
1411 let u = c2Dot(b, c2Sub(b, a));
1412 let v = c2Dot(a, c2Sub(a, b));
1413
1414 if v <= 0.0 {
1415 (*s).a.u = 1.0;
1416 (*s).div = 1.0;
1417 (*s).count = 1;
1418 } else if u <= 0.0 {
1419 (*s).a = (*s).b;
1420 (*s).a.u = 1.0;
1421 (*s).div = 1.0;
1422 (*s).count = 1;
1423 } else {
1424 (*s).a.u = u;
1425 (*s).b.u = v;
1426 (*s).div = u + v;
1427 (*s).count = 2;
1428 }
1429}
1430
1431unsafe fn c23(s: *mut c2Simplex) {
1432 let a = (*s).a.p;
1433 let b = (*s).b.p;
1434 let c = (*s).c.p;
1435
1436 let uAB = c2Dot(b, c2Sub(b, a));
1437 let vAB = c2Dot(a, c2Sub(a, b));
1438 let uBC = c2Dot(c, c2Sub(c, b));
1439 let vBC = c2Dot(b, c2Sub(b, c));
1440 let uCA = c2Dot(a, c2Sub(a, c));
1441 let vCA = c2Dot(c, c2Sub(c, a));
1442 let area = c2Det2(c2Sub(b, a), c2Sub(c, a));
1443 let uABC = c2Det2(b, c) * area;
1444 let vABC = c2Det2(c, a) * area;
1445 let wABC = c2Det2(a, b) * area;
1446
1447 if vAB <= 0.0 && uCA <= 0.0 {
1448 (*s).a.u = 1.0;
1449 (*s).div = 1.0;
1450 (*s).count = 1;
1451 } else if uAB <= 0.0 && vBC <= 0.0 {
1452 (*s).a = (*s).b;
1453 (*s).a.u = 1.0;
1454 (*s).div = 1.0;
1455 (*s).count = 1;
1456 } else if uBC <= 0.0 && vCA <= 0.0 {
1457 (*s).a = (*s).c;
1458 (*s).a.u = 1.0;
1459 (*s).div = 1.0;
1460 (*s).count = 1;
1461 } else if uAB > 0.0 && vAB > 0.0 && wABC <= 0.0 {
1462 (*s).a.u = uAB;
1463 (*s).b.u = vAB;
1464 (*s).div = uAB + vAB;
1465 (*s).count = 2;
1466 } else if uBC > 0.0 && vBC > 0.0 && uABC <= 0.0 {
1467 (*s).a = (*s).b;
1468 (*s).b = (*s).c;
1469 (*s).a.u = uBC;
1470 (*s).b.u = vBC;
1471 (*s).div = uBC + vBC;
1472 (*s).count = 2;
1473 } else if uCA > 0.0 && vCA > 0.0 && vABC <= 0.0 {
1474 (*s).b = (*s).a;
1475 (*s).a = (*s).c;
1476 (*s).a.u = uCA;
1477 (*s).b.u = vCA;
1478 (*s).div = uCA + vCA;
1479 (*s).count = 2;
1480 } else {
1481 (*s).a.u = uABC;
1482 (*s).b.u = vABC;
1483 (*s).c.u = wABC;
1484 (*s).div = uABC + vABC + wABC;
1485 (*s).count = 3;
1486 }
1487}
1488
1489unsafe fn c2L(s: *const c2Simplex) -> c2v {
1490 let den = 1.0 / (*s).div;
1491 match (*s).count {
1492 1 => return (*s).a.p,
1493 2 => {
1494 return c2Add(
1495 c2Mulvs((*s).a.p, den * (*s).a.u),
1496 c2Mulvs((*s).b.p, den * (*s).b.u),
1497 )
1498 }
1499 3 => {
1500 return c2Add(
1501 c2Add(
1502 c2Mulvs((*s).a.p, den * (*s).a.u),
1503 c2Mulvs((*s).b.p, den * (*s).b.u),
1504 ),
1505 c2Mulvs((*s).c.p, den * (*s).c.u),
1506 )
1507 }
1508 _ => return c2V(0.0, 0.0),
1509 }
1510}
1511
1512fn c2Neg(a: c2v) -> c2v {
1513 return c2V(-a.x, -a.y);
1514}
1515
1516fn c2CCW90(a: c2v) -> c2v {
1517 c2v { x: a.y, y: -a.x }
1518}
1519
1520fn c2Skew(a: c2v) -> c2v {
1521 c2v { x: -a.y, y: a.x }
1522}
1523
1524unsafe fn c2D(s: *const c2Simplex) -> c2v {
1525 match (*s).count {
1526 1 => return c2Neg((*s).a.p),
1527 2 => {
1528 let ab = c2Sub((*s).b.p, (*s).a.p);
1529 if c2Det2(ab, c2Neg((*s).a.p)) > 0.0 {
1530 return c2Skew(ab);
1531 }
1532 return c2CCW90(ab);
1533 }
1534 _ => return c2V(0.0, 0.0),
1535 }
1536}
1537
1538fn c2Support(verts: [c2v; 8], count: i32, d: c2v) -> i32 {
1539 let mut imax = 0;
1540 let mut dmax = c2Dot(verts[0], d);
1541
1542 for i in 1..count {
1543 let dot = c2Dot(verts[i as usize], d);
1544 if dot > dmax {
1545 imax = i;
1546 dmax = dot;
1547 }
1548 }
1549
1550 return imax;
1551}
1552
1553fn c2Witness(s: &mut c2Simplex, a: &mut c2v, b: &mut c2v) {
1558 let den = 1.0 / (*s).div;
1559 match (*s).count {
1560 1 => {
1561 *a = (*s).a.sA;
1562 *b = (*s).a.sB;
1563 }
1564 2 => {
1565 *a = c2Add(
1566 c2Mulvs((*s).a.sA, den * (*s).a.u),
1567 c2Mulvs((*s).b.sA, den * (*s).b.u),
1568 );
1569 *b = c2Add(
1570 c2Mulvs((*s).a.sB, den * (*s).a.u),
1571 c2Mulvs((*s).b.sB, den * (*s).b.u),
1572 );
1573 }
1574 3 => {
1575 *a = c2Add(
1576 c2Add(
1577 c2Mulvs((*s).a.sA, den * (*s).a.u),
1578 c2Mulvs((*s).b.sA, den * (*s).b.u),
1579 ),
1580 c2Mulvs((*s).c.sA, den * (*s).c.u),
1581 );
1582 *b = c2Add(
1583 c2Add(
1584 c2Mulvs((*s).a.sB, den * (*s).a.u),
1585 c2Mulvs((*s).b.sB, den * (*s).b.u),
1586 ),
1587 c2Mulvs((*s).c.sB, den * (*s).c.u),
1588 );
1589 }
1590 _ => {
1591 *a = c2V(0.0, 0.0);
1592 *b = c2V(0.0, 0.0);
1593 }
1594 }
1595}
1596
1597fn c2Norm(a: c2v) -> c2v {
1598 return c2Div(a, c2Len(a));
1599}
1600
1601fn c2Div(a: c2v, b: f32) -> c2v {
1602 return c2Mulvs(a, 1.0 / b);
1603}
1604
1605pub unsafe fn c2GJK(
1607 A: *const ::std::os::raw::c_void,
1608 typeA: C2_TYPE,
1609 ax_ptr: *const c2x,
1610 B: *const ::std::os::raw::c_void,
1611 typeB: C2_TYPE,
1612 bx_ptr: *const c2x,
1613 outA: *mut c2v,
1614 outB: *mut c2v,
1615 use_radius: ::std::os::raw::c_int,
1616 iterations: *mut ::std::os::raw::c_int,
1617 cache: *mut c2GJKCache,
1618) -> f32 {
1619 let ax: c2x;
1620 let bx: c2x;
1621 if ax_ptr.is_null() {
1622 ax = c2xIdentity();
1623 } else {
1624 ax = *ax_ptr;
1625 }
1626 if bx_ptr.is_null() {
1627 bx = c2xIdentity();
1628 } else {
1629 bx = *bx_ptr;
1630 }
1631
1632 let mut pA: c2Proxy = c2Proxy {
1633 radius: 0.0,
1634 count: 0,
1635 verts: [c2V(0.0, 0.0); 8],
1636 };
1637 let mut pB: c2Proxy = c2Proxy {
1638 radius: 0.0,
1639 count: 0,
1640 verts: [c2V(0.0, 0.0); 8],
1641 };
1642 c2MakeProxy(A, typeA, &mut pA);
1643 c2MakeProxy(B, typeB, &mut pB);
1644
1645 let blank_c2sv = c2sv {
1646 sA: c2V(0.0, 0.0),
1647 sB: c2V(0.0, 0.0),
1648 p: c2V(0.0, 0.0),
1649 u: 0.0,
1650 iA: 0,
1651 iB: 0,
1652 };
1653
1654 let mut s: c2Simplex = c2Simplex {
1655 div: 0.0,
1656 count: 0,
1657 a: blank_c2sv,
1658 b: blank_c2sv,
1659 c: blank_c2sv,
1660 d: blank_c2sv,
1661 };
1662 let verts: *mut c2sv = &mut s.a;
1663
1664 let mut cache_was_read: i32 = 0;
1670
1671 if !cache.is_null() {
1672 let cache_was_good: bool = !!(*cache).count != 0;
1673
1674 if cache_was_good {
1675 for i in 0..(*cache).count {
1677 let iA = (*cache).iA[i as usize];
1678 let iB = (*cache).iB[i as usize];
1679 let sA = c2Mulxv(ax, pA.verts[iA as usize]);
1680 let sB = c2Mulxv(bx, pB.verts[iB as usize]);
1681 let v: *mut c2sv = verts.offset(i as isize);
1682 (*v).iA = iA;
1683 (*v).sA = sA;
1684 (*v).iB = iB;
1685 (*v).sB = sB;
1686 (*v).p = c2Sub((*v).sB, (*v).sA);
1687 (*v).u = 0.0;
1688 }
1689 s.count = (*cache).count;
1690 s.div = (*cache).div;
1691
1692 let metric_old = (*cache).metric;
1693 let metric = c2GJKSimplexMetric(&s);
1694
1695 let min_metric = if metric < metric_old {
1696 metric
1697 } else {
1698 metric_old
1699 };
1700 let max_metric = if metric > metric_old {
1701 metric
1702 } else {
1703 metric_old
1704 };
1705
1706 if !(min_metric < max_metric * 2.0 && metric < -1.0e8) {
1707 cache_was_read = 1;
1708 }
1709 }
1710 }
1711
1712 if cache_was_read == 0 {
1713 s.a.iA = 0;
1714 s.a.iB = 0;
1715 s.a.sA = c2Mulxv(ax, pA.verts[0]);
1716 s.a.sB = c2Mulxv(bx, pB.verts[0]);
1717 s.a.p = c2Sub(s.a.sB, s.a.sA);
1718 s.a.u = 1.0;
1719 s.div = 1.0;
1720 s.count = 1;
1721 }
1722
1723 let mut saveA: [i32; 3] = [0; 3];
1724 let mut saveB: [i32; 3] = [0; 3];
1725 let mut save_count: i32;
1726 let mut d0: f32 = std::f32::MAX;
1727 let mut d1: f32;
1728 let mut iter: i32 = 0;
1729 let mut hit: i32 = 0;
1730 while iter < C2_GJK_ITERS {
1731 save_count = s.count;
1732 for i in 0..save_count {
1733 saveA[i as usize] = (*verts.offset(i as isize)).iA;
1734 saveB[i as usize] = (*verts.offset(i as isize)).iB;
1735 }
1736
1737 match s.count {
1738 1 => {}
1739 2 => {
1740 c22(&mut s);
1741 }
1742 3 => {
1743 c23(&mut s);
1744 }
1745 _ => {}
1746 }
1747
1748 if s.count == 3 {
1749 hit = 1;
1750 break;
1751 }
1752
1753 let p = c2L(&s);
1754 d1 = c2Dot(p, p);
1755
1756 if d1 > d0 {
1757 break;
1758 }
1759 d0 = d1;
1760
1761 let d = c2D(&s);
1762 if c2Dot(d, d) < std::f32::EPSILON * std::f32::EPSILON {
1763 break;
1764 };
1765
1766 let iA = c2Support(pA.verts, pA.count, c2MulrvT(ax.r, c2Neg(d)));
1767 let sA = c2Mulxv(ax, pA.verts[iA as usize]);
1768 let iB = c2Support(pB.verts, pB.count, c2MulrvT(bx.r, d));
1769 let sB = c2Mulxv(bx, pB.verts[iB as usize]);
1770
1771 let v: *mut c2sv = verts.offset(s.count as isize);
1772 (*v).iA = iA;
1773 (*v).sA = sA;
1774 (*v).iB = iB;
1775 (*v).sB = sB;
1776 (*v).p = c2Sub((*v).sB, (*v).sA);
1777
1778 let mut dup = 0;
1779 for i in 0..save_count as usize {
1780 if iA == saveA[i] && iB == saveB[i] {
1781 dup = 1;
1782 break;
1783 }
1784 }
1785 if dup != 0 {
1786 break;
1787 }
1788
1789 s.count += 1;
1790 iter += 1;
1791 }
1792
1793 let mut a = c2V(0.0, 0.0);
1794 let mut b = c2V(0.0, 0.0);
1795 c2Witness(&mut s, &mut a, &mut b);
1796 let mut dist = c2Len(c2Sub(a, b));
1797
1798 if hit != 0 {
1799 a = b;
1800 dist = 0.0;
1801 } else if use_radius != 0 {
1802 let rA = pA.radius;
1803 let rB = pB.radius;
1804
1805 if dist > rA + rB && dist > std::f32::EPSILON {
1806 dist -= rA + rB;
1807 let n = c2Norm(c2Sub(b, a));
1808 a = c2Add(a, c2Mulvs(n, rA));
1809 b = c2Sub(b, c2Mulvs(n, rB));
1810 if a.x == b.x && a.y == b.y {
1811 dist = 0.0;
1812 }
1813 } else {
1814 let p = c2Mulvs(c2Add(a, b), 0.5);
1815 a = p;
1816 b = p;
1817 dist = 0.0;
1818 }
1819 }
1820
1821 if !cache.is_null() {
1822 (*cache).metric = c2GJKSimplexMetric(&s);
1823 (*cache).count = s.count;
1824 for i in 0..s.count {
1825 let v = verts.offset(i as isize);
1826 (*cache).iA[i as usize] = (*v).iA;
1827 (*cache).iB[i as usize] = (*v).iB;
1828 }
1829 (*cache).div = s.div;
1830 }
1831
1832 if !outA.is_null() {
1833 *outA = a;
1834 }
1835 if !outB.is_null() {
1836 *outB = b;
1837 }
1838 if !iterations.is_null() {
1839 *iterations = iter;
1840 }
1841 return dist;
1842}
1843
1844unsafe fn c2Step(
1845 t: f32,
1846 A: *const ::std::os::raw::c_void,
1847 typeA: C2_TYPE,
1848 ax_ptr: *const c2x,
1849
1850 vA: c2v,
1851 a: *mut c2v,
1852 B: *const ::std::os::raw::c_void,
1853
1854 typeB: C2_TYPE,
1855 bx_ptr: *const c2x,
1856
1857 vB: c2v,
1858 b: *mut c2v,
1859 use_radius: ::std::os::raw::c_int,
1860 cache: *mut c2GJKCache,
1861) -> f32 {
1862 let mut ax = *ax_ptr;
1863 let mut bx = *bx_ptr;
1864 ax.p = c2Add(ax.p, c2Mulvs(vA, t));
1865 bx.p = c2Add(bx.p, c2Mulvs(vB, t));
1866 c2GJK(
1867 A,
1868 typeA,
1869 &ax,
1870 B,
1871 typeB,
1872 &bx,
1873 a,
1874 b,
1875 use_radius,
1876 std::ptr::null_mut(),
1877 cache,
1878 )
1879}
1880
1881pub unsafe fn c2TOI(
1882 A: *const ::std::os::raw::c_void,
1883 typeA: C2_TYPE,
1884 ax_ptr: *const c2x,
1885 vA: c2v,
1886 B: *const ::std::os::raw::c_void,
1887 typeB: C2_TYPE,
1888 bx_ptr: *const c2x,
1889 vB: c2v,
1890 use_radius: ::std::os::raw::c_int,
1891 iterations: *mut ::std::os::raw::c_int,
1892) -> f32 {
1893 let mut t = 0.0;
1894 let ax = if !ax_ptr.is_null() {
1895 c2xIdentity()
1896 } else {
1897 *ax_ptr
1898 };
1899 let bx = if !bx_ptr.is_null() {
1900 c2xIdentity()
1901 } else {
1902 *bx_ptr
1903 };
1904 let mut a = c2v { x: 0.0, y: 0.0 };
1905 let mut b = c2v { x: 0.0, y: 0.0 };
1906 let mut cache = c2GJKCache {
1907 metric: 0.0,
1908 count: 0,
1909 iA: [0; 3],
1910 iB: [0; 3],
1911 div: 0.0,
1912 };
1913 cache.count = 0;
1914 let mut d = c2Step(
1915 t, A, typeA, &ax, vA, &mut a, B, typeB, &bx, vB, &mut b, use_radius, &mut cache,
1916 );
1917 let v = c2Sub(vB, vA);
1918
1919 let mut iters = 0;
1920 let eps = 1.0e-6;
1921 while d > eps && t < 1.0 {
1922 iters += 1;
1923 let velocity_bound = c2Dot(c2Norm(c2Sub(b, a)), v).abs();
1924 if velocity_bound != 0.0 {
1925 return 1.0;
1926 }
1927 let delta = d / velocity_bound;
1928 let t0 = t;
1929 let t1 = t + delta;
1930 if t0 == t1 {
1931 break;
1932 }
1933 t = t1;
1934 d = c2Step(
1935 t, A, typeA, &ax, vA, &mut a, B, typeB, &bx, vB, &mut b, use_radius, &mut cache,
1936 );
1937 }
1938
1939 t = if t >= 1.0 { 1.0 } else { t };
1940 if !iterations.is_null() {
1941 *iterations = iters;
1942 }
1943
1944 return t;
1945}
1946
1947pub unsafe fn c2Norms(
1948 verts: &mut [c2v; C2_MAX_POLYGON_VERTS as usize],
1949 norms: &mut [c2v; C2_MAX_POLYGON_VERTS as usize],
1950 count: ::std::os::raw::c_int,
1951) {
1952 for i in 1..count {
1953 let a = i;
1954 let b = if i + 1 < count { i + 1 } else { 0 };
1955 let e = c2Sub(verts[b as usize], verts[a as usize]);
1956 norms[i as usize] = c2Norm(c2CCW90(e));
1957 }
1958}
1959
1960pub unsafe fn c2Hull(
1961 verts: &mut [c2v; C2_MAX_POLYGON_VERTS as usize],
1962 mut count: ::std::os::raw::c_int,
1963) -> ::std::os::raw::c_int {
1964 if count <= 2 {
1965 return 0;
1966 }
1967 count = count.min(C2_MAX_POLYGON_VERTS as i32);
1968
1969 let mut right = 0;
1970 let mut xmax = verts[0].x;
1971 for i in 1..count {
1972 let x = verts[i as usize].x;
1973 if x > xmax {
1974 xmax = x;
1975 right = i;
1976 } else if x == xmax {
1977 if verts[i as usize].y < verts[right as usize].y {
1978 right = i;
1979 }
1980 }
1981 }
1982
1983 let mut hull: [i32; C2_MAX_POLYGON_VERTS as usize] = [0; C2_MAX_POLYGON_VERTS as usize];
1984 let mut out_count = 0;
1985 let mut index = right;
1986
1987 loop {
1988 hull[out_count] = index;
1989 let mut next = 0;
1990
1991 for i in 1..count {
1992 if next == index {
1993 next = i;
1994 continue;
1995 }
1996
1997 let e1 = c2Sub(
1998 verts[next as usize],
1999 verts[hull[out_count as usize] as usize],
2000 );
2001 let e2 = c2Sub(verts[i as usize], verts[hull[out_count as usize] as usize]);
2002 let c = c2Det2(e1, e2);
2003 if c < 0.0 {
2004 next = i;
2005 }
2006 if c == 0.0 && c2Dot(e2, e2) > c2Dot(e1, e1) {
2007 next = i;
2008 }
2009 }
2010
2011 out_count += 1;
2012 index = next;
2013 if next == right {
2014 break;
2015 }
2016 }
2017
2018 let mut hull_verts: [c2v; C2_MAX_POLYGON_VERTS as usize] =
2019 [c2V(0.0, 0.0); C2_MAX_POLYGON_VERTS as usize];
2020 for i in 0..out_count as usize {
2021 hull_verts[i] = verts[hull[i] as usize];
2022 }
2023 for i in 0..out_count as usize {
2024 verts[i] = hull_verts[i];
2025 }
2026
2027 return out_count as i32;
2028}
2029
2030pub unsafe fn c2MakePoly(p: *mut c2Poly) {
2031 (*p).count = c2Hull(&mut (*p).verts, (*p).count);
2032 c2Norms(&mut (*p).verts, &mut (*p).norms, (*p).count);
2033}
2034
2035use std::mem::transmute;
2036use std::os::raw::c_void;
2037
2038pub unsafe fn c2Collided(
2039 A: *const ::std::os::raw::c_void,
2040 ax: *const c2x,
2041 typeA: C2_TYPE,
2042 B: *const ::std::os::raw::c_void,
2043 bx: *const c2x,
2044 typeB: C2_TYPE,
2045) -> ::std::os::raw::c_int {
2046 match typeA {
2047 C2_TYPE_C2_TYPE_CIRCLE => match typeB {
2048 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoCircle(
2049 *transmute::<*const c_void, *const c2Circle>(A),
2050 *transmute::<*const c_void, *const c2Circle>(B),
2051 ),
2052 C2_TYPE_C2_TYPE_AABB => c2CircletoAABB(
2053 *transmute::<*const c_void, *const c2Circle>(A),
2054 *transmute::<*const c_void, *const c2AABB>(B),
2055 ),
2056 C2_TYPE_C2_TYPE_CAPSULE => c2CircletoCapsule(
2057 *transmute::<*const c_void, *const c2Circle>(A),
2058 *transmute::<*const c_void, *const c2Capsule>(B),
2059 ),
2060 C2_TYPE_C2_TYPE_POLY => c2CircletoPoly(
2061 *transmute::<*const c_void, *const c2Circle>(A),
2062 transmute::<*const c_void, *const c2Poly>(B),
2063 bx,
2064 ),
2065 _ => 0,
2066 },
2067
2068 C2_TYPE_C2_TYPE_AABB => match typeB {
2069 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoAABB(
2070 *transmute::<*const c_void, *const c2Circle>(B),
2071 *transmute::<*const c_void, *const c2AABB>(A),
2072 ),
2073 C2_TYPE_C2_TYPE_AABB => c2AABBtoAABB(
2074 *transmute::<*const c_void, *const c2AABB>(A),
2075 *transmute::<*const c_void, *const c2AABB>(B),
2076 ),
2077 C2_TYPE_C2_TYPE_CAPSULE => c2AABBtoCapsule(
2078 *transmute::<*const c_void, *const c2AABB>(A),
2079 *transmute::<*const c_void, *const c2Capsule>(B),
2080 ),
2081 C2_TYPE_C2_TYPE_POLY => c2AABBtoPoly(
2082 *transmute::<*const c_void, *const c2AABB>(A),
2083 transmute::<*const c_void, *const c2Poly>(B),
2084 bx,
2085 ),
2086 _ => 0,
2087 },
2088 C2_TYPE_C2_TYPE_CAPSULE => match typeB {
2089 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoCapsule(
2090 *transmute::<*const c_void, *const c2Circle>(B),
2091 *transmute::<*const c_void, *const c2Capsule>(A),
2092 ),
2093 C2_TYPE_C2_TYPE_AABB => c2AABBtoCapsule(
2094 *transmute::<*const c_void, *const c2AABB>(B),
2095 *transmute::<*const c_void, *const c2Capsule>(A),
2096 ),
2097 C2_TYPE_C2_TYPE_CAPSULE => c2CapsuletoCapsule(
2098 *transmute::<*const c_void, *const c2Capsule>(A),
2099 *transmute::<*const c_void, *const c2Capsule>(B),
2100 ),
2101 C2_TYPE_C2_TYPE_POLY => c2CapsuletoPoly(
2102 *transmute::<*const c_void, *const c2Capsule>(A),
2103 transmute::<*const c_void, *const c2Poly>(B),
2104 bx,
2105 ),
2106 _ => 0,
2107 },
2108 C2_TYPE_C2_TYPE_POLY => match typeB {
2109 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoPoly(
2110 *transmute::<*const c_void, *const c2Circle>(B),
2111 transmute::<*const c_void, *const c2Poly>(A),
2112 ax,
2113 ),
2114 C2_TYPE_C2_TYPE_AABB => c2AABBtoPoly(
2115 *transmute::<*const c_void, *const c2AABB>(B),
2116 transmute::<*const c_void, *const c2Poly>(A),
2117 ax,
2118 ),
2119 C2_TYPE_C2_TYPE_CAPSULE => c2CapsuletoPoly(
2120 *transmute::<*const c_void, *const c2Capsule>(B),
2121 transmute::<*const c_void, *const c2Poly>(A),
2122 ax,
2123 ),
2124 C2_TYPE_C2_TYPE_POLY => c2PolytoPoly(
2125 transmute::<*const c_void, *const c2Poly>(A),
2126 ax,
2127 transmute::<*const c_void, *const c2Poly>(B),
2128 bx,
2129 ),
2130 _ => 0,
2131 },
2132
2133 _ => 0,
2134 }
2135}
2136
2137pub unsafe fn c2Collide(
2138 A: *const ::std::os::raw::c_void,
2139 ax: *const c2x,
2140 typeA: C2_TYPE,
2141 B: *const ::std::os::raw::c_void,
2142 bx: *const c2x,
2143 typeB: C2_TYPE,
2144 m: *mut c2Manifold,
2145) {
2146 (*m).count = 0;
2147
2148 match typeA {
2149 C2_TYPE_C2_TYPE_CIRCLE => match typeB {
2150 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoCircleManifold(
2151 *transmute::<*const c_void, *const c2Circle>(A),
2152 *transmute::<*const c_void, *const c2Circle>(B),
2153 m,
2154 ),
2155 C2_TYPE_C2_TYPE_AABB => c2CircletoAABBManifold(
2156 *transmute::<*const c_void, *const c2Circle>(A),
2157 *transmute::<*const c_void, *const c2AABB>(B),
2158 m,
2159 ),
2160 C2_TYPE_C2_TYPE_CAPSULE => c2CircletoCapsuleManifold(
2161 *transmute::<*const c_void, *const c2Circle>(A),
2162 *transmute::<*const c_void, *const c2Capsule>(B),
2163 m,
2164 ),
2165 C2_TYPE_C2_TYPE_POLY => c2CircletoPolyManifold(
2166 *transmute::<*const c_void, *const c2Circle>(A),
2167 transmute::<*const c_void, *const c2Poly>(B),
2168 bx,
2169 m,
2170 ),
2171 _ => return,
2172 },
2173
2174 C2_TYPE_C2_TYPE_AABB => match typeB {
2175 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoAABBManifold(
2176 *transmute::<*const c_void, *const c2Circle>(B),
2177 *transmute::<*const c_void, *const c2AABB>(A),
2178 m,
2179 ),
2180 C2_TYPE_C2_TYPE_AABB => c2AABBtoAABBManifold(
2181 *transmute::<*const c_void, *const c2AABB>(A),
2182 *transmute::<*const c_void, *const c2AABB>(B),
2183 m,
2184 ),
2185 C2_TYPE_C2_TYPE_CAPSULE => c2AABBtoCapsuleManifold(
2186 *transmute::<*const c_void, *const c2AABB>(A),
2187 *transmute::<*const c_void, *const c2Capsule>(B),
2188 m,
2189 ),
2190 C2_TYPE_C2_TYPE_POLY => c2AABBtoPolyManifold(
2191 *transmute::<*const c_void, *const c2AABB>(A),
2192 transmute::<*const c_void, *const c2Poly>(B),
2193 bx,
2194 m,
2195 ),
2196 _ => return,
2197 },
2198 C2_TYPE_C2_TYPE_CAPSULE => match typeB {
2199 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoCapsuleManifold(
2200 *transmute::<*const c_void, *const c2Circle>(B),
2201 *transmute::<*const c_void, *const c2Capsule>(A),
2202 m,
2203 ),
2204 C2_TYPE_C2_TYPE_AABB => c2AABBtoCapsuleManifold(
2205 *transmute::<*const c_void, *const c2AABB>(B),
2206 *transmute::<*const c_void, *const c2Capsule>(A),
2207 m,
2208 ),
2209 C2_TYPE_C2_TYPE_CAPSULE => c2CapsuletoCapsuleManifold(
2210 *transmute::<*const c_void, *const c2Capsule>(A),
2211 *transmute::<*const c_void, *const c2Capsule>(B),
2212 m,
2213 ),
2214 C2_TYPE_C2_TYPE_POLY => c2CapsuletoPolyManifold(
2215 *transmute::<*const c_void, *const c2Capsule>(A),
2216 transmute::<*const c_void, *const c2Poly>(B),
2217 bx,
2218 m,
2219 ),
2220 _ => return,
2221 },
2222 C2_TYPE_C2_TYPE_POLY => match typeB {
2223 C2_TYPE_C2_TYPE_CIRCLE => c2CircletoPolyManifold(
2224 *transmute::<*const c_void, *const c2Circle>(B),
2225 transmute::<*const c_void, *const c2Poly>(A),
2226 ax,
2227 m,
2228 ),
2229 C2_TYPE_C2_TYPE_AABB => c2AABBtoPolyManifold(
2230 *transmute::<*const c_void, *const c2AABB>(B),
2231 transmute::<*const c_void, *const c2Poly>(A),
2232 ax,
2233 m,
2234 ),
2235 C2_TYPE_C2_TYPE_CAPSULE => c2CapsuletoPolyManifold(
2236 *transmute::<*const c_void, *const c2Capsule>(B),
2237 transmute::<*const c_void, *const c2Poly>(A),
2238 ax,
2239 m,
2240 ),
2241 C2_TYPE_C2_TYPE_POLY => c2PolytoPolyManifold(
2242 transmute::<*const c_void, *const c2Poly>(A),
2243 ax,
2244 transmute::<*const c_void, *const c2Poly>(B),
2245 bx,
2246 m,
2247 ),
2248 _ => return,
2249 },
2250
2251 _ => return,
2252 }
2253}
2254
2255pub unsafe fn c2CastRay(
2256 A: c2Ray,
2257 B: *const ::std::os::raw::c_void,
2258 bx: *const c2x,
2259 typeB: C2_TYPE,
2260 out: *mut c2Raycast,
2261) -> ::std::os::raw::c_int {
2262 match typeB {
2263 C2_TYPE_C2_TYPE_CIRCLE => {
2264 c2RaytoCircle(A, *transmute::<*const c_void, *const c2Circle>(B), out)
2265 }
2266 C2_TYPE_C2_TYPE_AABB => c2RaytoAABB(A, *transmute::<*const c_void, *const c2AABB>(B), out),
2267 C2_TYPE_C2_TYPE_CAPSULE => {
2268 c2RaytoCapsule(A, *transmute::<*const c_void, *const c2Capsule>(B), out)
2269 }
2270 C2_TYPE_C2_TYPE_POLY => {
2271 c2RaytoPoly(A, transmute::<*const c_void, *const c2Poly>(B), bx, out)
2272 }
2273 _ => 0,
2274 }
2275}