]> rtime.felk.cvut.cz Git - hubacji1/rrts.git/blob - incl/cute_c2.h
Update license info in cute header file
[hubacji1/rrts.git] / incl / cute_c2.h
1 // Copyright (c) 2017 Randy Gaul http://www.randygaul.net
2 // SPDX-FileCopyrightText: 2017 Randy Gaul http://www.randygaul.net
3 // SPDX-FileCopyrightText: 2021 Randy Gaul http://www.randygaul.net
4 //
5 // SPDX-License-Identifier: Unlicense
6 // SPDX-License-Identifier: Zlib
7 /*
8         ------------------------------------------------------------------------------
9                 Licensing information can be found at the end of the file.
10         ------------------------------------------------------------------------------
11
12         cute_c2.h - v1.06
13
14         To create implementation (the function definitions)
15                 #define CUTE_C2_IMPLEMENTATION
16         in *one* C/CPP file (translation unit) that includes this file
17
18
19         SUMMARY
20
21                 cute_c2 is a single-file header that implements 2D collision detection routines
22                 that test for overlap, and optionally can find the collision manifold. The
23                 manifold contains all necessary information to prevent shapes from inter-
24                 penetrating, which is useful for character controllers, general physics
25                 simulation, and user-interface programming.
26
27                 This header implements a group of "immediate mode" functions that should be
28                 very easily adapted into pre-existing projects.
29
30
31         THE IMPORTANT PARTS
32
33                 Most of the math types in this header are for internal use. Users care about
34                 the shape types and the collision functions.
35
36                 SHAPE TYPES:
37                 * c2Circle
38                 * c2Capsule
39                 * c2AABB
40                 * c2Ray
41                 * c2Poly
42
43                 COLLISION FUNCTIONS (*** is a shape name from the above list):
44                 * c2***to***         - boolean YES/NO hittest
45                 * c2***to***Manifold - construct manifold to describe how shapes hit
46                 * c2GJK              - runs GJK algorithm to find closest point pair
47                                        between two shapes
48                 * c2TOI              - computes the time of impact between two shapes, useful for
49                                        sweeping shapes, or doing shape casts
50                 * c2MakePoly         - Runs convex hull algorithm and computes normals on input point-set
51                 * c2Collided         - generic version of c2***to*** funcs
52                 * c2Collide          - generic version of c2***to***Manifold funcs
53                 * c2CastRay          - generic version of c2Rayto*** funcs
54
55                 The rest of the header is more or less for internal use. Here is an example of
56                 making some shapes and testing for collision:
57
58                         c2Circle c;
59                         c.p = position;
60                         c.r = radius;
61
62                         c2Capsule cap;
63                         cap.a = first_endpoint;
64                         cap.b = second_endpoint;
65                         cap.r = radius;
66
67                         int hit = c2CircletoCapsule(c, cap);
68                         if (hit)
69                         {
70                                 handle collision here...
71                         }
72         
73                 For more code examples and tests please see:
74                 https://github.com/RandyGaul/cute_header/tree/master/examples_cute_gl_and_c2
75
76                 Here is a past discussion thread on this header:
77                 https://www.reddit.com/r/gamedev/comments/5tqyey/tinyc2_2d_collision_detection_library_in_c/
78
79                 Here is a very nice repo containing various tests and examples using SFML for rendering:
80                 https://github.com/sro5h/tinyc2-tests
81
82
83         DETAILS/ADVICE
84
85                 This header does not implement a broad-phase, and instead concerns itself with
86                 the narrow-phase. This means this header just checks to see if two individual
87                 shapes are touching, and can give information about how they are touching.
88
89                 Very common 2D broad-phases are tree and grid approaches. Quad trees are good
90                 for static geometry that does not move much if at all. Dynamic AABB trees are
91                 good for general purpose use, and can handle moving objects very well. Grids
92                 are great and are similar to quad trees.
93
94                 If implementing a grid it can be wise to have each collideable grid cell hold
95                 an integer. This integer refers to a 2D shape that can be passed into the
96                 various functions in this header. The shape can be transformed from "model"
97                 space to "world" space using c2x -- a transform struct. In this way a grid
98                 can be implemented that holds any kind of convex shape (that this header
99                 supports) while conserving memory with shape instancing.
100
101                 Please email at my address with any questions or comments at:
102                 author's last name followed by 1748 at gmail
103
104
105         FEATURES
106
107                 * Circles, capsules, AABBs, rays and convex polygons are supported
108                 * Fast boolean only result functions (hit yes/no)
109                 * Slghtly slower manifold generation for collision normals + depths +points
110                 * GJK implementation (finds closest points for disjoint pairs of shapes)
111                 * Shape casts/sweeps with c2TOI function (time of impact)
112                 * Robust 2D convex hull generator
113                 * Lots of correctly implemented and tested 2D math routines
114                 * Implemented in portable C, and is readily portable to other languages
115                 * Generic c2Collide, c2Collided and c2CastRay function (can pass in any shape type)
116                 * Extensive examples at: https://github.com/RandyGaul/cute_headers/tree/master/examples_cute_gl_and_c2
117
118
119         Revision History
120         
121                 1.0  (02/13/2017) initial release
122                 1.01 (02/13/2017) const crusade, minor optimizations, capsule degen
123                 1.02 (03/21/2017) compile fixes for c on more compilers
124                 1.03 (09/15/2017) various bugfixes and quality of life changes to manifolds
125                 1.04 (03/25/2018) fixed manifold bug in c2CircletoAABBManifold
126                 1.05 (11/01/2018) added c2TOI (time of impact) for shape cast/sweep test
127                 1.06 (08/23/2019) C2_*** types to C2_TYPE_***, and CUTE_C2_API
128
129
130         Contributors
131         
132                 Plastburk         1.01 - const pointers pull request
133                 mmozeiko          1.02 - 3 compile bugfixes
134                 felipefs          1.02 - 3 compile bugfixes
135                 seemk             1.02 - fix branching bug in c2Collide
136                 sro5h             1.02 - bug reports for multiple manifold funcs
137                 sro5h             1.03 - work involving quality of life fixes for manifolds
138                 Wizzard033        1.06 - C2_*** types to C2_TYPE_***, and CUTE_C2_API
139 */
140
141 #if !defined(CUTE_C2_H)
142
143 // this can be adjusted as necessary, but is highly recommended to be kept at 8.
144 // higher numbers will incur quite a bit of memory overhead, and convex shapes
145 // over 8 verts start to just look like spheres, which can be implicitly rep-
146 // resented as a point + radius. usually tools that generate polygons should be
147 // constructed so they do not output polygons with too many verts.
148 // Note: polygons in cute_c2 are all *convex*.
149 #define C2_MAX_POLYGON_VERTS 8
150
151 // 2d vector
152 typedef struct
153 {
154         float x;
155         float y;
156 } c2v;
157
158 // 2d rotation composed of cos/sin pair
159 typedef struct
160 {
161         float c;
162         float s;
163 } c2r;
164
165 // 2d rotation matrix
166 typedef struct
167 {
168         c2v x;
169         c2v y;
170 } c2m;
171
172 // 2d transformation "x"
173 // These are used especially for c2Poly when a c2Poly is passed to a function.
174 // Since polygons are prime for "instancing" a c2x transform can be used to
175 // transform a polygon from local space to world space. In functions that take
176 // a c2x pointer (like c2PolytoPoly), these pointers can be NULL, which represents
177 // an identity transformation and assumes the verts inside of c2Poly are already
178 // in world space.
179 typedef struct
180 {
181         c2v p;
182         c2r r;
183 } c2x;
184
185 // 2d halfspace (aka plane, aka line)
186 typedef struct
187 {
188         c2v n;   // normal, normalized
189         float d; // distance to origin from plane, or ax + by = d
190 } c2h;
191
192 typedef struct
193 {
194         c2v p;
195         float r;
196 } c2Circle;
197
198 typedef struct
199 {
200         c2v min;
201         c2v max;
202 } c2AABB;
203
204 // a capsule is defined as a line segment (from a to b) and radius r
205 typedef struct
206 {
207         c2v a;
208         c2v b;
209         float r;
210 } c2Capsule;
211
212 typedef struct
213 {
214         int count;
215         c2v verts[C2_MAX_POLYGON_VERTS];
216         c2v norms[C2_MAX_POLYGON_VERTS];
217 } c2Poly;
218
219 // IMPORTANT:
220 // Many algorithms in this file are sensitive to the magnitude of the
221 // ray direction (c2Ray::d). It is highly recommended to normalize the
222 // ray direction and use t to specify a distance. Please see this link
223 // for an in-depth explanation: https://github.com/RandyGaul/cute_headers/issues/30
224 typedef struct
225 {
226         c2v p;   // position
227         c2v d;   // direction (normalized)
228         float t; // distance along d from position p to find endpoint of ray
229 } c2Ray;
230
231 typedef struct
232 {
233         float t; // time of impact
234         c2v n;   // normal of surface at impact (unit length)
235 } c2Raycast;
236
237 // position of impact p = ray.p + ray.d * raycast.t
238 #define c2Impact(ray, t) c2Add(ray.p, c2Mulvs(ray.d, t))
239
240 // contains all information necessary to resolve a collision, or in other words
241 // this is the information needed to separate shapes that are colliding. Doing
242 // the resolution step is *not* included in cute_c2. cute_c2 does not include
243 // "feature information" that describes which topological features collided.
244 // However, modifying the exist ***Manifold funcs can be done to output any
245 // needed feature information. Feature info is sometimes needed for certain kinds
246 // of simulations that cache information over multiple game-ticks, of which are
247 // associated to the collision of specific features. An example implementation
248 // is in the qu3e 3D physics engine library: https://github.com/RandyGaul/qu3e
249 typedef struct
250 {
251         int count;
252         float depths[2];
253         c2v contact_points[2];
254
255         // always points from shape A to shape B (first and second shapes passed into
256         // any of the c2***to***Manifold functions)
257         c2v n;
258 } c2Manifold;
259
260 // This define allows exporting/importing of the header to a dynamic library.
261 // Here's an example.
262 // #define CUTE_C2_API extern "C" __declspec(dllexport)
263 #if !defined(CUTE_C2_API)
264 #       define CUTE_C2_API
265 #endif
266
267 // boolean collision detection
268 // these versions are faster than the manifold versions, but only give a YES/NO
269 // result
270 CUTE_C2_API int c2CircletoCircle(c2Circle A, c2Circle B);
271 CUTE_C2_API int c2CircletoAABB(c2Circle A, c2AABB B);
272 CUTE_C2_API int c2CircletoCapsule(c2Circle A, c2Capsule B);
273 CUTE_C2_API int c2AABBtoAABB(c2AABB A, c2AABB B);
274 CUTE_C2_API int c2AABBtoCapsule(c2AABB A, c2Capsule B);
275 CUTE_C2_API int c2CapsuletoCapsule(c2Capsule A, c2Capsule B);
276 CUTE_C2_API int c2CircletoPoly(c2Circle A, const c2Poly* B, const c2x* bx);
277 CUTE_C2_API int c2AABBtoPoly(c2AABB A, const c2Poly* B, const c2x* bx);
278 CUTE_C2_API int c2CapsuletoPoly(c2Capsule A, const c2Poly* B, const c2x* bx);
279 CUTE_C2_API int c2PolytoPoly(const c2Poly* A, const c2x* ax, const c2Poly* B, const c2x* bx);
280
281 // ray operations
282 // output is placed into the c2Raycast struct, which represents the hit location
283 // of the ray. the out param contains no meaningful information if these funcs
284 // return 0
285 CUTE_C2_API int c2RaytoCircle(c2Ray A, c2Circle B, c2Raycast* out);
286 CUTE_C2_API int c2RaytoAABB(c2Ray A, c2AABB B, c2Raycast* out);
287 CUTE_C2_API int c2RaytoCapsule(c2Ray A, c2Capsule B, c2Raycast* out);
288 CUTE_C2_API int c2RaytoPoly(c2Ray A, const c2Poly* B, const c2x* bx_ptr, c2Raycast* out);
289
290 // manifold generation
291 // these functions are slower than the boolean versions, but will compute one
292 // or two points that represent the plane of contact. This information is
293 // is usually needed to resolve and prevent shapes from colliding. If no coll
294 // ision occured the count member of the manifold struct is set to 0.
295 CUTE_C2_API void c2CircletoCircleManifold(c2Circle A, c2Circle B, c2Manifold* m);
296 CUTE_C2_API void c2CircletoAABBManifold(c2Circle A, c2AABB B, c2Manifold* m);
297 CUTE_C2_API void c2CircletoCapsuleManifold(c2Circle A, c2Capsule B, c2Manifold* m);
298 CUTE_C2_API void c2AABBtoAABBManifold(c2AABB A, c2AABB B, c2Manifold* m);
299 CUTE_C2_API void c2AABBtoCapsuleManifold(c2AABB A, c2Capsule B, c2Manifold* m);
300 CUTE_C2_API void c2CapsuletoCapsuleManifold(c2Capsule A, c2Capsule B, c2Manifold* m);
301 CUTE_C2_API void c2CircletoPolyManifold(c2Circle A, const c2Poly* B, const c2x* bx, c2Manifold* m);
302 CUTE_C2_API void c2AABBtoPolyManifold(c2AABB A, const c2Poly* B, const c2x* bx, c2Manifold* m);
303 CUTE_C2_API void c2CapsuletoPolyManifold(c2Capsule A, const c2Poly* B, const c2x* bx, c2Manifold* m);
304 CUTE_C2_API void c2PolytoPolyManifold(const c2Poly* A, const c2x* ax, const c2Poly* B, const c2x* bx, c2Manifold* m);
305
306 typedef enum
307 {
308         C2_TYPE_NONE,
309         C2_TYPE_CIRCLE,
310         C2_TYPE_AABB,
311         C2_TYPE_CAPSULE,
312         C2_TYPE_POLY
313 } C2_TYPE;
314
315 // This struct is only for advanced usage of the c2GJK function. See comments inside of the
316 // c2GJK function for more details.
317 typedef struct
318 {
319         float metric;
320         int count;
321         int iA[3];
322         int iB[3];
323         float div;
324 } c2GJKCache;
325
326 // Runs the GJK algorithm to find closest points, returns distance between closest points.
327 // outA and outB can be NULL, in this case only distance is returned. ax_ptr and bx_ptr
328 // can be NULL, and represent local to world transformations for shapes A and B respectively.
329 // use_radius will apply radii for capsules and circles (if set to false, spheres are
330 // treated as points and capsules are treated as line segments i.e. rays). The cache parameter
331 // should be NULL, as it is only for advanced usage (unless you know what you're doing, then
332 // go ahead and use it). iterations is an optional parameter.
333 CUTE_C2_API float c2GJK(const void* A, C2_TYPE typeA, const c2x* ax_ptr, const void* B, C2_TYPE typeB, const c2x* bx_ptr, c2v* outA, c2v* outB, int use_radius, int* iterations, c2GJKCache* cache);
334
335 // Computes the time of impact from shape A and shape B. The velocity of each shape is provided
336 // by vA and vB respectively. The shapes are *not* allowed to rotate over time. The velocity is
337 // assumed to represent the change in motion from time 0 to time 1, and so the return value will
338 // be a number from 0 to 1. To move each shape to the colliding configuration, multiply vA and vB
339 // each by the return value. ax_ptr and bx_ptr are optional parameters to transforms for each shape,
340 // and are typically used for polygon shapes to transform from model to world space. Set these to
341 // NULL to represent identity transforms. The out_normal for non-colliding configurations (or in
342 // other words, when the return value is 1) is just the direction pointing along the closest points
343 // from shape A to shape B. out_normal can be NULL. iterations is an optional parameter. use_radius
344 // will apply radii for capsules and circles (if set to false, spheres are treated as points and
345 // capsules are treated as line segments i.e. rays).
346 CUTE_C2_API float c2TOI(const void* A, C2_TYPE typeA, const c2x* ax_ptr, c2v vA, const void* B, C2_TYPE typeB, const c2x* bx_ptr, c2v vB, int use_radius, c2v* out_normal, c2v* out_contact_point, int* iterations);
347
348 // Computes 2D convex hull. Will not do anything if less than two verts supplied. If
349 // more than C2_MAX_POLYGON_VERTS are supplied extras are ignored.
350 CUTE_C2_API int c2Hull(c2v* verts, int count);
351 CUTE_C2_API void c2Norms(c2v* verts, c2v* norms, int count);
352
353 // runs c2Hull and c2Norms, assumes p->verts and p->count are both set to valid values
354 CUTE_C2_API void c2MakePoly(c2Poly* p);
355
356 // Generic collision detection routines, useful for games that want to use some poly-
357 // morphism to write more generic-styled code. Internally calls various above functions.
358 // For AABBs/Circles/Capsules ax and bx are ignored. For polys ax and bx can define
359 // model to world transformations, or be NULL for identity transforms.
360 CUTE_C2_API int c2Collided(const void* A, const c2x* ax, C2_TYPE typeA, const void* B, const c2x* bx, C2_TYPE typeB);
361 CUTE_C2_API void c2Collide(const void* A, const c2x* ax, C2_TYPE typeA, const void* B, const c2x* bx, C2_TYPE typeB, c2Manifold* m);
362 CUTE_C2_API int c2CastRay(c2Ray A, const void* B, const c2x* bx, C2_TYPE typeB, c2Raycast* out);
363
364 #ifdef _MSC_VER
365         #define C2_INLINE __forceinline
366 #else
367         #define C2_INLINE inline __attribute__((always_inline))
368 #endif
369
370 // adjust these primitives as seen fit
371 #include <string.h> // memcpy
372 #include <math.h>
373 #define c2Sin(radians) sinf(radians)
374 #define c2Cos(radians) cosf(radians)
375 #define c2Sqrt(a) sqrtf(a)
376 #define c2Min(a, b) ((a) < (b) ? (a) : (b))
377 #define c2Max(a, b) ((a) > (b) ? (a) : (b))
378 #define c2Abs(a) ((a) < 0 ? -(a) : (a))
379 #define c2Clamp(a, lo, hi) c2Max(lo, c2Min(a, hi))
380 C2_INLINE void c2SinCos(float radians, float* s, float* c) { *c = c2Cos(radians); *s = c2Sin(radians); }
381 #define c2Sign(a) (a < 0 ? -1.0f : 1.0f)
382
383 // The rest of the functions in the header-only portion are all for internal use
384 // and use the author's personal naming conventions. It is recommended to use one's
385 // own math library instead of the one embedded here in cute_c2, but for those
386 // curious or interested in trying it out here's the details:
387
388 // The Mul functions are used to perform multiplication. x stands for transform,
389 // v stands for vector, s stands for scalar, r stands for rotation, h stands for
390 // halfspace and T stands for transpose.For example c2MulxvT stands for "multiply
391 // a transform with a vector, and transpose the transform".
392
393 // vector ops
394 C2_INLINE c2v c2V(float x, float y) { c2v a; a.x = x; a.y = y; return a; }
395 C2_INLINE c2v c2Add(c2v a, c2v b) { a.x += b.x; a.y += b.y; return a; }
396 C2_INLINE c2v c2Sub(c2v a, c2v b) { a.x -= b.x; a.y -= b.y; return a; }
397 C2_INLINE float c2Dot(c2v a, c2v b) { return a.x * b.x + a.y * b.y; }
398 C2_INLINE c2v c2Mulvs(c2v a, float b) { a.x *= b; a.y *= b; return a; }
399 C2_INLINE c2v c2Mulvv(c2v a, c2v b) { a.x *= b.x; a.y *= b.y; return a; }
400 C2_INLINE c2v c2Div(c2v a, float b) { return c2Mulvs(a, 1.0f / b); }
401 C2_INLINE c2v c2Skew(c2v a) { c2v b; b.x = -a.y; b.y = a.x; return b; }
402 C2_INLINE c2v c2CCW90(c2v a) { c2v b; b.x = a.y; b.y = -a.x; return b; }
403 C2_INLINE float c2Det2(c2v a, c2v b) { return a.x * b.y - a.y * b.x; }
404 C2_INLINE c2v c2Minv(c2v a, c2v b) { return c2V(c2Min(a.x, b.x), c2Min(a.y, b.y)); }
405 C2_INLINE c2v c2Maxv(c2v a, c2v b) { return c2V(c2Max(a.x, b.x), c2Max(a.y, b.y)); }
406 C2_INLINE c2v c2Clampv(c2v a, c2v lo, c2v hi) { return c2Maxv(lo, c2Minv(a, hi)); }
407 C2_INLINE c2v c2Absv(c2v a) { return c2V(c2Abs(a.x), c2Abs(a.y)); }
408 C2_INLINE float c2Hmin(c2v a) { return c2Min(a.x, a.y); }
409 C2_INLINE float c2Hmax(c2v a) { return c2Max(a.x, a.y); }
410 C2_INLINE float c2Len(c2v a) { return c2Sqrt(c2Dot(a, a)); }
411 C2_INLINE c2v c2Norm(c2v a) { return c2Div(a, c2Len(a)); }
412 C2_INLINE c2v c2SafeNorm(c2v a) { float sq = c2Dot(a, a); return sq ? c2Div(a, c2Len(a)) : c2V(0, 0); }
413 C2_INLINE c2v c2Neg(c2v a) { return c2V(-a.x, -a.y); }
414 C2_INLINE c2v c2Lerp(c2v a, c2v b, float t) { return c2Add(a, c2Mulvs(c2Sub(b, a), t)); }
415 C2_INLINE int c2Parallel(c2v a, c2v b, float kTol)
416 {
417         float k = c2Len(a) / c2Len(b);
418         b = c2Mulvs(b, k);
419         if (c2Abs(a.x - b.x) < kTol && c2Abs(a.y - b.y) < kTol) return 1;
420         return 0;
421 }
422
423 // rotation ops
424 C2_INLINE c2r c2Rot(float radians) { c2r r; c2SinCos(radians, &r.s, &r.c); return r; }
425 C2_INLINE c2r c2RotIdentity() { c2r r; r.c = 1.0f; r.s = 0; return r; }
426 C2_INLINE c2v c2RotX(c2r r) { return c2V(r.c, r.s); }
427 C2_INLINE c2v c2RotY(c2r r) { return c2V(-r.s, r.c); }
428 C2_INLINE c2v c2Mulrv(c2r a, c2v b)  { return c2V(a.c * b.x - a.s * b.y,  a.s * b.x + a.c * b.y); }
429 C2_INLINE c2v c2MulrvT(c2r a, c2v b) { return c2V(a.c * b.x + a.s * b.y, -a.s * b.x + a.c * b.y); }
430 C2_INLINE c2r c2Mulrr(c2r a, c2r b)  { c2r c; c.c = a.c * b.c - a.s * b.s; c.s = a.s * b.c + a.c * b.s; return c; }
431 C2_INLINE c2r c2MulrrT(c2r a, c2r b) { c2r c; c.c = a.c * b.c + a.s * b.s; c.s = a.c * b.s - a.s * b.c; return c; }
432
433 C2_INLINE c2v c2Mulmv(c2m a, c2v b) { c2v c; c.x = a.x.x * b.x + a.y.x * b.y; c.y = a.x.y * b.x + a.y.y * b.y; return c; }
434 C2_INLINE c2v c2MulmvT(c2m a, c2v b) { c2v c; c.x = a.x.x * b.x + a.x.y * b.y; c.y = a.y.x * b.x + a.y.y * b.y; return c; }
435 C2_INLINE c2m c2Mulmm(c2m a, c2m b)  { c2m c; c.x = c2Mulmv(a, b.x);  c.y = c2Mulmv(a, b.y); return c; }
436 C2_INLINE c2m c2MulmmT(c2m a, c2m b) { c2m c; c.x = c2MulmvT(a, b.x); c.y = c2MulmvT(a, b.y); return c; }
437
438 // transform ops
439 C2_INLINE c2x c2xIdentity() { c2x x; x.p = c2V(0, 0); x.r = c2RotIdentity(); return x; }
440 C2_INLINE c2v c2Mulxv(c2x a, c2v b) { return c2Add(c2Mulrv(a.r, b), a.p); }
441 C2_INLINE c2v c2MulxvT(c2x a, c2v b) { return c2MulrvT(a.r, c2Sub(b, a.p)); }
442 C2_INLINE c2x c2Mulxx(c2x a, c2x b) { c2x c; c.r = c2Mulrr(a.r, b.r); c.p = c2Add(c2Mulrv(a.r, b.p), a.p); return c; }
443 C2_INLINE c2x c2MulxxT(c2x a, c2x b) { c2x c; c.r = c2MulrrT(a.r, b.r); c.p = c2MulrvT(a.r, c2Sub(b.p, a.p)); return c; }
444 C2_INLINE c2x c2Transform(c2v p, float radians) { c2x x; x.r = c2Rot(radians); x.p = p; return x; }
445
446 // halfspace ops
447 C2_INLINE c2v c2Origin(c2h h) { return c2Mulvs(h.n, h.d); }
448 C2_INLINE float c2Dist(c2h h, c2v p) { return c2Dot(h.n, p) - h.d; }
449 C2_INLINE c2v c2Project(c2h h, c2v p) { return c2Sub(p, c2Mulvs(h.n, c2Dist(h, p))); }
450 C2_INLINE c2h c2Mulxh(c2x a, c2h b) { c2h c; c.n = c2Mulrv(a.r, b.n); c.d = c2Dot(c2Mulxv(a, c2Origin(b)), c.n); return c; }
451 C2_INLINE c2h c2MulxhT(c2x a, c2h b) { c2h c; c.n = c2MulrvT(a.r, b.n); c.d = c2Dot(c2MulxvT(a, c2Origin(b)), c.n); return c; }
452 C2_INLINE c2v c2Intersect(c2v a, c2v b, float da, float db) { return c2Add(a, c2Mulvs(c2Sub(b, a), (da / (da - db)))); }
453
454 C2_INLINE void c2BBVerts(c2v* out, c2AABB* bb)
455 {
456         out[0] = bb->min;
457         out[1] = c2V(bb->max.x, bb->min.y);
458         out[2] = bb->max;
459         out[3] = c2V(bb->min.x, bb->max.y);
460 }
461
462 #define CUTE_C2_H
463 #endif
464
465 #ifdef CUTE_C2_IMPLEMENTATION
466 #ifndef CUTE_C2_IMPLEMENTATION_ONCE
467 #define CUTE_C2_IMPLEMENTATION_ONCE
468
469 int c2Collided(const void* A, const c2x* ax, C2_TYPE typeA, const void* B, const c2x* bx, C2_TYPE typeB)
470 {
471         switch (typeA)
472         {
473         case C2_TYPE_CIRCLE:
474                 switch (typeB)
475                 {
476                 case C2_TYPE_CIRCLE:  return c2CircletoCircle(*(c2Circle*)A, *(c2Circle*)B);
477                 case C2_TYPE_AABB:    return c2CircletoAABB(*(c2Circle*)A, *(c2AABB*)B);
478                 case C2_TYPE_CAPSULE: return c2CircletoCapsule(*(c2Circle*)A, *(c2Capsule*)B);
479                 case C2_TYPE_POLY:    return c2CircletoPoly(*(c2Circle*)A, (const c2Poly*)B, bx);
480                 default:         return 0;
481                 }
482                 break;
483
484         case C2_TYPE_AABB:
485                 switch (typeB)
486                 {
487                 case C2_TYPE_CIRCLE:  return c2CircletoAABB(*(c2Circle*)B, *(c2AABB*)A);
488                 case C2_TYPE_AABB:    return c2AABBtoAABB(*(c2AABB*)A, *(c2AABB*)B);
489                 case C2_TYPE_CAPSULE: return c2AABBtoCapsule(*(c2AABB*)A, *(c2Capsule*)B);
490                 case C2_TYPE_POLY:    return c2AABBtoPoly(*(c2AABB*)A, (const c2Poly*)B, bx);
491                 default:         return 0;
492                 }
493                 break;
494
495         case C2_TYPE_CAPSULE:
496                 switch (typeB)
497                 {
498                 case C2_TYPE_CIRCLE:  return c2CircletoCapsule(*(c2Circle*)B, *(c2Capsule*)A);
499                 case C2_TYPE_AABB:    return c2AABBtoCapsule(*(c2AABB*)B, *(c2Capsule*)A);
500                 case C2_TYPE_CAPSULE: return c2CapsuletoCapsule(*(c2Capsule*)A, *(c2Capsule*)B);
501                 case C2_TYPE_POLY:    return c2CapsuletoPoly(*(c2Capsule*)A, (const c2Poly*)B, bx);
502                 default:         return 0;
503                 }
504                 break;
505
506         case C2_TYPE_POLY:
507                 switch (typeB)
508                 {
509                 case C2_TYPE_CIRCLE:  return c2CircletoPoly(*(c2Circle*)B, (const c2Poly*)A, ax);
510                 case C2_TYPE_AABB:    return c2AABBtoPoly(*(c2AABB*)B, (const c2Poly*)A, ax);
511                 case C2_TYPE_CAPSULE: return c2CapsuletoPoly(*(c2Capsule*)B, (const c2Poly*)A, ax);
512                 case C2_TYPE_POLY:    return c2PolytoPoly((const c2Poly*)A, ax, (const c2Poly*)B, bx);
513                 default:         return 0;
514                 }
515                 break;
516
517         default:
518                 return 0;
519         }
520 }
521
522 void c2Collide(const void* A, const c2x* ax, C2_TYPE typeA, const void* B, const c2x* bx, C2_TYPE typeB, c2Manifold* m)
523 {
524         m->count = 0;
525
526         switch (typeA)
527         {
528         case C2_TYPE_CIRCLE:
529                 switch (typeB)
530                 {
531                 case C2_TYPE_CIRCLE:  c2CircletoCircleManifold(*(c2Circle*)A, *(c2Circle*)B, m); break;
532                 case C2_TYPE_AABB:    c2CircletoAABBManifold(*(c2Circle*)A, *(c2AABB*)B, m); break;
533                 case C2_TYPE_CAPSULE: c2CircletoCapsuleManifold(*(c2Circle*)A, *(c2Capsule*)B, m); break;
534                 case C2_TYPE_POLY:    c2CircletoPolyManifold(*(c2Circle*)A, (const c2Poly*)B, bx, m); break;
535                 }
536                 break;
537
538         case C2_TYPE_AABB:
539                 switch (typeB)
540                 {
541                 case C2_TYPE_CIRCLE:  c2CircletoAABBManifold(*(c2Circle*)B, *(c2AABB*)A, m); m->n = c2Neg(m->n); break;
542                 case C2_TYPE_AABB:    c2AABBtoAABBManifold(*(c2AABB*)A, *(c2AABB*)B, m); break;
543                 case C2_TYPE_CAPSULE: c2AABBtoCapsuleManifold(*(c2AABB*)A, *(c2Capsule*)B, m); break;
544                 case C2_TYPE_POLY:    c2AABBtoPolyManifold(*(c2AABB*)A, (const c2Poly*)B, bx, m); break;
545                 }
546                 break;
547
548         case C2_TYPE_CAPSULE:
549                 switch (typeB)
550                 {
551                 case C2_TYPE_CIRCLE:  c2CircletoCapsuleManifold(*(c2Circle*)B, *(c2Capsule*)A, m); m->n = c2Neg(m->n); break;
552                 case C2_TYPE_AABB:    c2AABBtoCapsuleManifold(*(c2AABB*)B, *(c2Capsule*)A, m); m->n = c2Neg(m->n); break;
553                 case C2_TYPE_CAPSULE: c2CapsuletoCapsuleManifold(*(c2Capsule*)A, *(c2Capsule*)B, m); break;
554                 case C2_TYPE_POLY:    c2CapsuletoPolyManifold(*(c2Capsule*)A, (const c2Poly*)B, bx, m); break;
555                 }
556                 break;
557
558         case C2_TYPE_POLY:
559                 switch (typeB)
560                 {
561                 case C2_TYPE_CIRCLE:  c2CircletoPolyManifold(*(c2Circle*)B, (const c2Poly*)A, ax, m); m->n = c2Neg(m->n); break;
562                 case C2_TYPE_AABB:    c2AABBtoPolyManifold(*(c2AABB*)B, (const c2Poly*)A, ax, m); m->n = c2Neg(m->n); break;
563                 case C2_TYPE_CAPSULE: c2CapsuletoPolyManifold(*(c2Capsule*)B, (const c2Poly*)A, ax, m); m->n = c2Neg(m->n); break;
564                 case C2_TYPE_POLY:    c2PolytoPolyManifold((const c2Poly*)A, ax, (const c2Poly*)B, bx, m); break;
565                 }
566                 break;
567         }
568 }
569
570 int c2CastRay(c2Ray A, const void* B, const c2x* bx, C2_TYPE typeB, c2Raycast* out)
571 {
572         switch (typeB)
573         {
574         case C2_TYPE_CIRCLE:  return c2RaytoCircle(A, *(c2Circle*)B, out);
575         case C2_TYPE_AABB:    return c2RaytoAABB(A, *(c2AABB*)B, out);
576         case C2_TYPE_CAPSULE: return c2RaytoCapsule(A, *(c2Capsule*)B, out);
577         case C2_TYPE_POLY:    return c2RaytoPoly(A, (const c2Poly*)B, bx, out);
578         }
579
580         return 0;
581 }
582
583 #define C2_GJK_ITERS 20
584
585 typedef struct
586 {
587         float radius;
588         int count;
589         c2v verts[C2_MAX_POLYGON_VERTS];
590 } c2Proxy;
591
592 typedef struct
593 {
594         c2v sA;
595         c2v sB;
596         c2v p;
597         float u;
598         int iA;
599         int iB;
600 } c2sv;
601
602 typedef struct
603 {
604         c2sv a, b, c, d;
605         float div;
606         int count;
607 } c2Simplex;
608
609 static C2_INLINE void c2MakeProxy(const void* shape, C2_TYPE type, c2Proxy* p)
610 {
611         switch (type)
612         {
613         case C2_TYPE_CIRCLE:
614         {
615                 c2Circle* c = (c2Circle*)shape;
616                 p->radius = c->r;
617                 p->count = 1;
618                 p->verts[0] = c->p;
619         }       break;
620
621         case C2_TYPE_AABB:
622         {
623                 c2AABB* bb = (c2AABB*)shape;
624                 p->radius = 0;
625                 p->count = 4;
626                 c2BBVerts(p->verts, bb);
627         }       break;
628
629         case C2_TYPE_CAPSULE:
630         {
631                 c2Capsule* c = (c2Capsule*)shape;
632                 p->radius = c->r;
633                 p->count = 2;
634                 p->verts[0] = c->a;
635                 p->verts[1] = c->b;
636         }       break;
637
638         case C2_TYPE_POLY:
639         {
640                 c2Poly* poly = (c2Poly*)shape;
641                 p->radius = 0;
642                 p->count = poly->count;
643                 for (int i = 0; i < p->count; ++i) p->verts[i] = poly->verts[i];
644         }       break;
645         }
646 }
647
648 static C2_INLINE int c2Support(const c2v* verts, int count, c2v d)
649 {
650         int imax = 0;
651         float dmax = c2Dot(verts[0], d);
652
653         for (int i = 1; i < count; ++i)
654         {
655                 float dot = c2Dot(verts[i], d);
656                 if (dot > dmax)
657                 {
658                         imax = i;
659                         dmax = dot;
660                 }
661         }
662
663         return imax;
664 }
665
666 #define C2_BARY(n, x) c2Mulvs(s->n.x, (den * s->n.u))
667 #define C2_BARY2(x) c2Add(C2_BARY(a, x), C2_BARY(b, x))
668 #define C2_BARY3(x) c2Add(c2Add(C2_BARY(a, x), C2_BARY(b, x)), C2_BARY(c, x))
669
670 static C2_INLINE c2v c2L(c2Simplex* s)
671 {
672         float den = 1.0f / s->div;
673         switch (s->count)
674         {
675         case 1: return s->a.p;
676         case 2: return C2_BARY2(p);
677         case 3: return C2_BARY3(p);
678         default: return c2V(0, 0);
679         }
680 }
681
682 static C2_INLINE void c2Witness(c2Simplex* s, c2v* a, c2v* b)
683 {
684         float den = 1.0f / s->div;
685         switch (s->count)
686         {
687         case 1: *a = s->a.sA; *b = s->a.sB; break;
688         case 2: *a = C2_BARY2(sA); *b = C2_BARY2(sB); break;
689         case 3: *a = C2_BARY3(sA); *b = C2_BARY3(sB); break;
690         default: *a = c2V(0, 0); *b = c2V(0, 0);
691         }
692 }
693
694 static C2_INLINE c2v c2D(c2Simplex* s)
695 {
696         switch (s->count)
697         {
698         case 1: return c2Neg(s->a.p);
699         case 2:
700         {
701                 c2v ab = c2Sub(s->b.p, s->a.p);
702                 if (c2Det2(ab, c2Neg(s->a.p)) > 0) return c2Skew(ab);
703                 return c2CCW90(ab);
704         }
705         case 3:
706         default: return c2V(0, 0);
707         }
708 }
709
710 static C2_INLINE void c22(c2Simplex* s)
711 {
712         c2v a = s->a.p;
713         c2v b = s->b.p;
714         float u = c2Dot(b, c2Norm(c2Sub(b, a)));
715         float v = c2Dot(a, c2Norm(c2Sub(a, b)));
716
717         if (v <= 0)
718         {
719                 s->a.u = 1.0f;
720                 s->div = 1.0f;
721                 s->count = 1;
722         }
723
724         else if (u <= 0)
725         {
726                 s->a = s->b;
727                 s->a.u = 1.0f;
728                 s->div = 1.0f;
729                 s->count = 1;
730         }
731
732         else
733         {
734                 s->a.u = u;
735                 s->b.u = v;
736                 s->div = u + v;
737                 s->count = 2;
738         }
739 }
740
741 static C2_INLINE void c23(c2Simplex* s)
742 {
743         c2v a = s->a.p;
744         c2v b = s->b.p;
745         c2v c = s->c.p;
746
747         float uAB = c2Dot(b, c2Norm(c2Sub(b, a)));
748         float vAB = c2Dot(a, c2Norm(c2Sub(a, b)));
749         float uBC = c2Dot(c, c2Norm(c2Sub(c, b)));
750         float vBC = c2Dot(b, c2Norm(c2Sub(b, c)));
751         float uCA = c2Dot(a, c2Norm(c2Sub(a, c)));
752         float vCA = c2Dot(c, c2Norm(c2Sub(c, a)));
753         float area = c2Det2(c2Norm(c2Sub(b, a)), c2Norm(c2Sub(c, a)));
754         float uABC = c2Det2(b, c) * area;
755         float vABC = c2Det2(c, a) * area;
756         float wABC = c2Det2(a, b) * area;
757
758         if (vAB <= 0 && uCA <= 0)
759         {
760                 s->a.u = 1.0f;
761                 s->div = 1.0f;
762                 s->count = 1;
763         }
764
765         else if (uAB <= 0 && vBC <= 0)
766         {
767                 s->a = s->b;
768                 s->a.u = 1.0f;
769                 s->div = 1.0f;
770                 s->count = 1;
771         }
772
773         else if (uBC <= 0 && vCA <= 0)
774         {
775                 s->a = s->c;
776                 s->a.u = 1.0f;
777                 s->div = 1.0f;
778                 s->count = 1;
779         }
780
781         else if (uAB > 0 && vAB > 0 && wABC <= 0)
782         {
783                 s->a.u = uAB;
784                 s->b.u = vAB;
785                 s->div = uAB + vAB;
786                 s->count = 2;
787         }
788
789         else if (uBC > 0 && vBC > 0 && uABC <= 0)
790         {
791                 s->a = s->b;
792                 s->b = s->c;
793                 s->a.u = uBC;
794                 s->b.u = vBC;
795                 s->div = uBC + vBC;
796                 s->count = 2;
797         }
798
799         else if (uCA > 0 && vCA > 0 && vABC <= 0)
800         {
801                 s->b = s->a;
802                 s->a = s->c;
803                 s->a.u = uCA;
804                 s->b.u = vCA;
805                 s->div = uCA + vCA;
806                 s->count = 2;
807         }
808
809         else
810         {
811                 s->a.u = uABC;
812                 s->b.u = vABC;
813                 s->c.u = wABC;
814                 s->div = uABC + vABC + wABC;
815                 s->count = 3;
816         }
817 }
818
819 #include <float.h>
820
821 static C2_INLINE float c2GJKSimplexMetric(c2Simplex* s)
822 {
823         switch (s->count)
824         {
825         default: // fall through
826         case 1:  return 0;
827         case 2:  return c2Len(c2Sub(s->b.p, s->a.p));
828         case 3:  return c2Det2(c2Sub(s->b.p, s->a.p), c2Sub(s->c.p, s->a.p));
829         }
830 }
831
832 // Please see http://box2d.org/downloads/ under GDC 2010 for Erin's demo code
833 // and PDF slides for documentation on the GJK algorithm. This function is mostly
834 // from Erin's version from his online resources.
835 float c2GJK(const void* A, C2_TYPE typeA, const c2x* ax_ptr, const void* B, C2_TYPE typeB, const c2x* bx_ptr, c2v* outA, c2v* outB, int use_radius, int* iterations, c2GJKCache* cache)
836 {
837         c2x ax;
838         c2x bx;
839         if (!ax_ptr) ax = c2xIdentity();
840         else ax = *ax_ptr;
841         if (!bx_ptr) bx = c2xIdentity();
842         else bx = *bx_ptr;
843
844         c2Proxy pA;
845         c2Proxy pB;
846         c2MakeProxy(A, typeA, &pA);
847         c2MakeProxy(B, typeB, &pB);
848
849         c2Simplex s;
850         c2sv* verts = &s.a;
851
852         // Metric and caching system as designed by E. Catto in Box2D for his conservative advancment/bilateral
853         // advancement algorithim implementations. The purpose is to reuse old simplex indices (any simplex that
854         // have not degenerated into a line or point) as a starting point. This skips the first few iterations of
855         // GJK going from point, to line, to triangle, lowering convergence rates dramatically for temporally
856         // coherent cases (such as in time of impact searches).
857         int cache_was_read = 0;
858         if (cache)
859         {
860                 int cache_was_good = !!cache->count;
861
862                 if (cache_was_good)
863                 {
864                         for (int i = 0; i < cache->count; ++i)
865                         {
866                                 int iA = cache->iA[i];
867                                 int iB = cache->iB[i];
868                                 c2v sA = c2Mulxv(ax, pA.verts[iA]);
869                                 c2v sB = c2Mulxv(bx, pB.verts[iB]);
870                                 c2sv* v = verts + i;
871                                 v->iA = iA;
872                                 v->sA = sA;
873                                 v->iB = iB;
874                                 v->sB = sB;
875                                 v->p = c2Sub(v->sB, v->sA);
876                                 v->u = 0;
877                         }
878                         s.count = cache->count;
879                         s.div = cache->div;
880
881                         float metric_old = cache->metric;
882                         float metric = c2GJKSimplexMetric(&s);
883
884                         float min_metric = metric < metric_old ? metric : metric_old;
885                         float max_metric = metric > metric_old ? metric : metric_old;
886
887                         if (!(min_metric < max_metric * 2.0f && metric < -1.0e8f)) cache_was_read = 1;
888                 }
889         }
890
891         if (!cache_was_read)
892         {
893                 s.a.iA = 0;
894                 s.a.iB = 0;
895                 s.a.sA = c2Mulxv(ax, pA.verts[0]);
896                 s.a.sB = c2Mulxv(bx, pB.verts[0]);
897                 s.a.p = c2Sub(s.a.sB, s.a.sA);
898                 s.a.u = 1.0f;
899                 s.div = 1.0f;
900                 s.count = 1;
901         }
902
903         int saveA[3], saveB[3];
904         int save_count = 0;
905         float d0 = FLT_MAX;
906         float d1 = FLT_MAX;
907         int iter = 0;
908         int hit = 0;
909         while (iter < C2_GJK_ITERS)
910         {
911                 save_count = s.count;
912                 for (int i = 0; i < save_count; ++i)
913                 {
914                         saveA[i] = verts[i].iA;
915                         saveB[i] = verts[i].iB;
916                 }
917                 
918                 switch (s.count)
919                 {
920                 case 1: break;
921                 case 2: c22(&s); break;
922                 case 3: c23(&s); break;
923                 }
924
925                 if (s.count == 3)
926                 {
927                         hit = 1;
928                         break;
929                 }
930
931                 c2v p = c2L(&s);
932                 d1 = c2Dot(p, p);
933
934                 if (d1 > d0) break;
935                 d0 = d1;
936
937                 c2v d = c2D(&s);
938                 if (c2Dot(d, d) < FLT_EPSILON * FLT_EPSILON) break;
939
940                 int iA = c2Support(pA.verts, pA.count, c2MulrvT(ax.r, c2Neg(d)));
941                 c2v sA = c2Mulxv(ax, pA.verts[iA]);
942                 int iB = c2Support(pB.verts, pB.count, c2MulrvT(bx.r, d));
943                 c2v sB = c2Mulxv(bx, pB.verts[iB]);
944
945                 c2sv* v = verts + s.count;
946                 v->iA = iA;
947                 v->sA = sA;
948                 v->iB = iB;
949                 v->sB = sB;
950                 v->p = c2Sub(v->sB, v->sA);
951
952                 int dup = 0;
953                 for (int i = 0; i < save_count; ++i)
954                 {
955                         if (iA == saveA[i] && iB == saveB[i])
956                         {
957                                 dup = 1;
958                                 break;
959                         }
960                 }
961                 if (dup) break;
962
963                 ++s.count;
964                 ++iter;
965         }
966
967         c2v a, b;
968         c2Witness(&s, &a, &b);
969         float dist = c2Len(c2Sub(a, b));
970
971         if (hit)
972         {
973                 a = b;
974                 dist = 0;
975         }
976
977         else if (use_radius)
978         {
979                 float rA = pA.radius;
980                 float rB = pB.radius;
981
982                 if (dist > rA + rB && dist > FLT_EPSILON)
983                 {
984                         dist -= rA + rB;
985                         c2v n = c2Norm(c2Sub(b, a));
986                         a = c2Add(a, c2Mulvs(n, rA));
987                         b = c2Sub(b, c2Mulvs(n, rB));
988                         if (a.x == b.x && a.y == b.y) dist = 0;
989                 }
990
991                 else
992                 {
993                         c2v p = c2Mulvs(c2Add(a, b), 0.5f);
994                         a = p;
995                         b = p;
996                         dist = 0;
997                 }
998         }
999
1000         if (cache)
1001         {
1002                 cache->metric = c2GJKSimplexMetric(&s);
1003                 cache->count = s.count;
1004                 for (int i = 0; i < s.count; ++i)
1005                 {
1006                         c2sv* v = verts + i;
1007                         cache->iA[i] = v->iA;
1008                         cache->iB[i] = v->iB;
1009                 }
1010                 cache->div = s.div;
1011         }
1012
1013         if (outA) *outA = a;
1014         if (outB) *outB = b;
1015         if (iterations) *iterations = iter;
1016         return dist;
1017 }
1018
1019 static C2_INLINE float c2Step(float t, const void* A, C2_TYPE typeA, const c2x* ax_ptr, c2v vA, c2v* a, const void* B, C2_TYPE typeB, const c2x* bx_ptr, c2v vB, c2v* b, int use_radius, c2GJKCache* cache)
1020 {
1021         c2x ax = *ax_ptr;
1022         c2x bx = *bx_ptr;
1023         ax.p = c2Add(ax.p, c2Mulvs(vA, t));
1024         bx.p = c2Add(bx.p, c2Mulvs(vB, t));
1025         float d = c2GJK(A, typeA, &ax, B, typeB, &bx, a, b, use_radius, NULL, cache);
1026         return d;
1027 }
1028
1029 float c2TOI(const void* A, C2_TYPE typeA, const c2x* ax_ptr, c2v vA, const void* B, C2_TYPE typeB, const c2x* bx_ptr, c2v vB, int use_radius, c2v* out_normal, c2v* out_contact_point, int* iterations)
1030 {
1031         float t = 0;
1032         c2x ax;
1033         c2x bx;
1034         if (!ax_ptr) ax = c2xIdentity();
1035         else ax = *ax_ptr;
1036         if (!bx_ptr) bx = c2xIdentity();
1037         else bx = *bx_ptr;
1038         c2v a, b, n;
1039         c2GJKCache cache;
1040         cache.count = 0;
1041         float d = c2Step(t, A, typeA, &ax, vA, &a, B, typeB, &bx, vB, &b, use_radius, &cache);
1042         c2v v = c2Sub(vB, vA);
1043         n = c2SafeNorm(c2Sub(b, a));
1044
1045         int iter = 0;
1046         float eps = 1.0e-5f;
1047         while (d > eps && t < 1)
1048         {
1049                 ++iter;
1050                 float velocity_bound = c2Abs(c2Dot(c2Norm(c2Sub(b, a)), v));
1051                 if (!velocity_bound) return 1;
1052                 float delta = d / velocity_bound;
1053                 t += delta * 0.95f;
1054                 c2v a0, b0;
1055                 d = c2Step(t, A, typeA, &ax, vA, &a0, B, typeB, &bx, vB, &b0, use_radius, &cache);
1056                 if (d * d >= eps)
1057                 {
1058                         a = a0;
1059                         b = b0;
1060                         n = c2Sub(b, a);
1061                 }
1062         }
1063
1064         n = c2SafeNorm(n);
1065         t = t >= 1 ? 1 : t;
1066         c2v p = c2Mulvs(c2Add(a, b), 0.5f);
1067
1068         if (out_normal) *out_normal = n;
1069         if (out_contact_point) *out_contact_point = p;
1070         if (iterations) *iterations = iter;
1071         return t;
1072 }
1073
1074 int c2Hull(c2v* verts, int count)
1075 {
1076         if (count <= 2) return 0;
1077         count = c2Min(C2_MAX_POLYGON_VERTS, count);
1078
1079         int right = 0;
1080         float xmax = verts[0].x;
1081         for (int i = 1; i < count; ++i)
1082         {
1083                 float x = verts[i].x;
1084                 if (x > xmax)
1085                 {
1086                         xmax = x;
1087                         right = i;
1088                 }
1089
1090                 else if (x == xmax)
1091                 if (verts[i].y < verts[right].y) right = i;
1092         }
1093
1094         int hull[C2_MAX_POLYGON_VERTS];
1095         int out_count = 0;
1096         int index = right;
1097
1098         while (1)
1099         {
1100                 hull[out_count] = index;
1101                 int next = 0;
1102
1103                 for (int i = 1; i < count; ++i)
1104                 {
1105                         if (next == index)
1106                         {
1107                                 next = i;
1108                                 continue;
1109                         }
1110
1111                         c2v e1 = c2Sub(verts[next], verts[hull[out_count]]);
1112                         c2v e2 = c2Sub(verts[i], verts[hull[out_count]]);
1113                         float c = c2Det2(e1, e2);
1114                         if(c < 0) next = i;
1115                         if (c == 0 && c2Dot(e2, e2) > c2Dot(e1, e1)) next = i;
1116                 }
1117
1118                 ++out_count;
1119                 index = next;
1120                 if (next == right) break;
1121         }
1122
1123         c2v hull_verts[C2_MAX_POLYGON_VERTS];
1124         for (int i = 0; i < out_count; ++i) hull_verts[i] = verts[hull[i]];
1125         memcpy(verts, hull_verts, sizeof(c2v) * out_count);
1126         return out_count;
1127 }
1128
1129 void c2Norms(c2v* verts, c2v* norms, int count)
1130 {
1131         for (int  i = 0; i < count; ++i)
1132         {
1133                 int a = i;
1134                 int b = i + 1 < count ? i + 1 : 0;
1135                 c2v e = c2Sub(verts[b], verts[a]);
1136                 norms[i] = c2Norm(c2CCW90(e));
1137         }
1138 }
1139
1140 void c2MakePoly(c2Poly* p)
1141 {
1142         p->count = c2Hull(p->verts, p->count);
1143         c2Norms(p->verts, p->norms, p->count);
1144 }
1145
1146 int c2CircletoCircle(c2Circle A, c2Circle B)
1147 {
1148         c2v c = c2Sub(B.p, A.p);
1149         float d2 = c2Dot(c, c);
1150         float r2 = A.r + B.r;
1151         r2 = r2 * r2;
1152         return d2 < r2;
1153 }
1154
1155 int c2CircletoAABB(c2Circle A, c2AABB B)
1156 {
1157         c2v L = c2Clampv(A.p, B.min, B.max);
1158         c2v ab = c2Sub(A.p, L);
1159         float d2 = c2Dot(ab, ab);
1160         float r2 = A.r * A.r;
1161         return d2 < r2;
1162 }
1163
1164 int c2AABBtoAABB(c2AABB A, c2AABB B)
1165 {
1166         int d0 = B.max.x < A.min.x;
1167         int d1 = A.max.x < B.min.x;
1168         int d2 = B.max.y < A.min.y;
1169         int d3 = A.max.y < B.min.y;
1170         return !(d0 | d1 | d2 | d3);
1171 }
1172
1173 // see: http://www.randygaul.net/2014/07/23/distance-point-to-line-segment/
1174 int c2CircletoCapsule(c2Circle A, c2Capsule B)
1175 {
1176         c2v n = c2Sub(B.b, B.a);
1177         c2v ap = c2Sub(A.p, B.a);
1178         float da = c2Dot(ap, n);
1179         float d2;
1180
1181         if (da < 0) d2 = c2Dot(ap, ap);
1182         else
1183         {
1184                 float db = c2Dot(c2Sub(A.p, B.b), n);
1185                 if (db < 0)
1186                 {
1187                         c2v e = c2Sub(ap, c2Mulvs(n, (da / c2Dot(n, n))));
1188                         d2 = c2Dot(e, e);
1189                 }
1190                 else
1191                 {
1192                         c2v bp = c2Sub(A.p, B.b);
1193                         d2 = c2Dot(bp, bp);
1194                 }
1195         }
1196
1197         float r = A.r + B.r;
1198         return d2 < r * r;
1199 }
1200
1201 int c2AABBtoCapsule(c2AABB A, c2Capsule B)
1202 {
1203         if (c2GJK(&A, C2_TYPE_AABB, 0, &B, C2_TYPE_CAPSULE, 0, 0, 0, 1, 0, 0)) return 0;
1204         return 1;
1205 }
1206
1207 int c2CapsuletoCapsule(c2Capsule A, c2Capsule B)
1208 {
1209         if (c2GJK(&A, C2_TYPE_CAPSULE, 0, &B, C2_TYPE_CAPSULE, 0, 0, 0, 1, 0, 0)) return 0;
1210         return 1;
1211 }
1212
1213 int c2CircletoPoly(c2Circle A, const c2Poly* B, const c2x* bx)
1214 {
1215         if (c2GJK(&A, C2_TYPE_CIRCLE, 0, B, C2_TYPE_POLY, bx, 0, 0, 1, 0, 0)) return 0;
1216         return 1;
1217 }
1218
1219 int c2AABBtoPoly(c2AABB A, const c2Poly* B, const c2x* bx)
1220 {
1221         if (c2GJK(&A, C2_TYPE_AABB, 0, B, C2_TYPE_POLY, bx, 0, 0, 1, 0, 0)) return 0;
1222         return 1;
1223 }
1224
1225 int c2CapsuletoPoly(c2Capsule A, const c2Poly* B, const c2x* bx)
1226 {
1227         if (c2GJK(&A, C2_TYPE_CAPSULE, 0, B, C2_TYPE_POLY, bx, 0, 0, 1, 0, 0)) return 0;
1228         return 1;
1229 }
1230
1231 int c2PolytoPoly(const c2Poly* A, const c2x* ax, const c2Poly* B, const c2x* bx)
1232 {
1233         if (c2GJK(A, C2_TYPE_POLY, ax, B, C2_TYPE_POLY, bx, 0, 0, 1, 0, 0)) return 0;
1234         return 1;
1235 }
1236
1237 int c2RaytoCircle(c2Ray A, c2Circle B, c2Raycast* out)
1238 {
1239         c2v p = B.p;
1240         c2v m = c2Sub(A.p, p);
1241         float c = c2Dot(m, m) - B.r * B.r;
1242         float b = c2Dot(m, A.d);
1243         float disc = b * b - c;
1244         if (disc < 0) return 0;
1245
1246         float t = -b - c2Sqrt(disc);
1247         if (t >= 0 && t <= A.t)
1248         {
1249                 out->t = t;
1250                 c2v impact = c2Impact(A, t);
1251                 out->n = c2Norm(c2Sub(impact, p));
1252                 return 1;
1253         }
1254         return 0;
1255 }
1256
1257 static inline float c2SignedDistPointToPlane_OneDimensional(float p, float n, float d)
1258 {
1259         return p * n - d * n;
1260 }
1261
1262 static inline float c2RayToPlane_OneDimensional(float da, float db)
1263 {
1264         if (da < 0) return 0; // Ray started behind plane.
1265         else if (da * db >= 0) return 1.0f; // Ray starts and ends on the same of the plane.
1266         else // Ray starts and ends on opposite sides of the plane (or directly on the plane).
1267         {
1268                 float d = da - db;
1269                 if (d != 0) return da / d;
1270                 else return 0; // Special case for super tiny ray, or AABB.
1271         }
1272 }
1273
1274 int c2RaytoAABB(c2Ray A, c2AABB B, c2Raycast* out)
1275 {
1276         c2v p0 = A.p;
1277         c2v p1 = c2Impact(A, A.t);
1278         c2AABB a_box;
1279         a_box.min = c2Minv(p0, p1);
1280         a_box.max = c2Maxv(p0, p1);
1281
1282         // Test B's axes.
1283         if (!c2AABBtoAABB(a_box, B)) return 0;
1284
1285         // Test the ray's axes (along the segment's normal).
1286         c2v ab = c2Sub(p1, p0);
1287         c2v n = c2Skew(ab);
1288         c2v abs_n = c2Absv(n);
1289         c2v half_extents = c2Mulvs(c2Sub(B.max, B.min), 0.5f);
1290         c2v center_of_b_box = c2Mulvs(c2Add(B.min, B.max), 0.5f);
1291         float d = c2Abs(c2Dot(n, c2Sub(p0, center_of_b_box))) - c2Dot(abs_n, half_extents);
1292         if (d > 0) return 0;
1293
1294         // Calculate intermediate values up-front.
1295         // This should play well with superscalar architecture.
1296         float da0 = c2SignedDistPointToPlane_OneDimensional(p0.x, -1.0f, B.min.x);
1297         float db0 = c2SignedDistPointToPlane_OneDimensional(p1.x, -1.0f, B.min.x);
1298         float da1 = c2SignedDistPointToPlane_OneDimensional(p0.x,  1.0f, B.max.x);
1299         float db1 = c2SignedDistPointToPlane_OneDimensional(p1.x,  1.0f, B.max.x);
1300         float da2 = c2SignedDistPointToPlane_OneDimensional(p0.y, -1.0f, B.min.y);
1301         float db2 = c2SignedDistPointToPlane_OneDimensional(p1.y, -1.0f, B.min.y);
1302         float da3 = c2SignedDistPointToPlane_OneDimensional(p0.y,  1.0f, B.max.y);
1303         float db3 = c2SignedDistPointToPlane_OneDimensional(p1.y,  1.0f, B.max.y);
1304         float t0 = c2RayToPlane_OneDimensional(da0, db0);
1305         float t1 = c2RayToPlane_OneDimensional(da1, db1);
1306         float t2 = c2RayToPlane_OneDimensional(da2, db2);
1307         float t3 = c2RayToPlane_OneDimensional(da3, db3);
1308
1309         // Calculate hit predicate, no branching.
1310         int hit0 = t0 < 1.0f;
1311         int hit1 = t1 < 1.0f;
1312         int hit2 = t2 < 1.0f;
1313         int hit3 = t3 < 1.0f;
1314         int hit = hit0 | hit1 | hit2 | hit3;
1315
1316         if (hit)
1317         {
1318                 // Remap t's within 0-1 range, where >= 1 is treated as 0.
1319                 t0 = (float)hit0 * t0;
1320                 t1 = (float)hit1 * t1;
1321                 t2 = (float)hit2 * t2;
1322                 t3 = (float)hit3 * t3;
1323
1324                 // Sort output by finding largest t to deduce the normal.
1325                 if (t0 >= t1 && t0 >= t2 && t0 >= t3)
1326                 {
1327                         out->t = t0 * A.t;
1328                         out->n = c2V(-1, 0);
1329                 }
1330                 
1331                 else if (t1 >= t0 && t1 >= t2 && t1 >= t3)
1332                 {
1333                         out->t = t1 * A.t;
1334                         out->n = c2V(1, 0);
1335                 }
1336                 
1337                 else if (t2 >= t0 && t2 >= t1 && t2 >= t3)
1338                 {
1339                         out->t = t2 * A.t;
1340                         out->n = c2V(0, -1);
1341                 }
1342                 
1343                 else
1344                 {
1345                         out->t = t3 * A.t;
1346                         out->n = c2V(0, 1);
1347                 }
1348
1349                 return 1;
1350         } else return 0; // This can still numerically happen.
1351 }
1352
1353 int c2RaytoCapsule(c2Ray A, c2Capsule B, c2Raycast* out)
1354 {
1355         c2m M;
1356         M.y = c2Norm(c2Sub(B.b, B.a));
1357         M.x = c2CCW90(M.y);
1358
1359         // rotate capsule to origin, along Y axis
1360         // rotate the ray same way
1361         c2v yBb = c2MulmvT(M, c2Sub(B.b, B.a));
1362         c2v yAp = c2MulmvT(M, c2Sub(A.p, B.a));
1363         c2v yAd = c2MulmvT(M, A.d);
1364         c2v yAe = c2Add(yAp, c2Mulvs(yAd, A.t));
1365
1366         if (yAe.x * yAp.x < 0 || c2Min(c2Abs(yAe.x), c2Abs(yAp.x)) < B.r)
1367         {
1368                 float c = yAp.x > 0 ? B.r : -B.r;
1369                 float d = (yAe.x - yAp.x);
1370                 float t = (c - yAp.x) / d;
1371                 float y = yAp.y + (yAe.y - yAp.y) * t;
1372
1373                 // hit bottom half-circle
1374                 if (y < 0)
1375                 {
1376                         c2Circle C;
1377                         C.p = B.a;
1378                         C.r = B.r;
1379                         return c2RaytoCircle(A, C, out);
1380                 }
1381
1382                 // hit top-half circle
1383                 else if (y > yBb.y)
1384                 {
1385                         c2Circle C;
1386                         C.p = B.b;
1387                         C.r = B.r;
1388                         return c2RaytoCircle(A, C, out);
1389                 }
1390
1391                 // hit the middle of capsule
1392                 else
1393                 {
1394                         out->n = c > 0 ? M.x : c2Skew(M.y);
1395                         out->t = t * A.t;
1396                         return 1;
1397                 }
1398         }
1399
1400         return 0;
1401 }
1402
1403 int c2RaytoPoly(c2Ray A, const c2Poly* B, const c2x* bx_ptr, c2Raycast* out)
1404 {
1405         c2x bx = bx_ptr ? *bx_ptr : c2xIdentity();
1406         c2v p = c2MulxvT(bx, A.p);
1407         c2v d = c2MulrvT(bx.r, A.d);
1408         float lo = 0;
1409         float hi = A.t;
1410         int index = ~0;
1411
1412         // test ray to each plane, tracking lo/hi times of intersection
1413         for (int i = 0; i < B->count; ++i)
1414         {
1415                 float num = c2Dot(B->norms[i], c2Sub(B->verts[i], p));
1416                 float den = c2Dot(B->norms[i], d);
1417                 if (den == 0 && num < 0) return 0;
1418                 else
1419                 {
1420                         if (den < 0 && num < lo * den)
1421                         {
1422                                 lo = num / den;
1423                                 index = i;
1424                         }
1425                         else if (den > 0 && num < hi * den) hi = num / den;
1426                 }
1427                 if (hi < lo) return 0;
1428         }
1429
1430         if (index != ~0)
1431         {
1432                 out->t = lo;
1433                 out->n = c2Mulrv(bx.r, B->norms[index]);
1434                 return 1;
1435         }
1436
1437         return 0;
1438 }
1439
1440 void c2CircletoCircleManifold(c2Circle A, c2Circle B, c2Manifold* m)
1441 {
1442         m->count = 0;
1443         c2v d = c2Sub(B.p, A.p);
1444         float d2 = c2Dot(d, d);
1445         float r = A.r + B.r;
1446         if (d2 < r * r)
1447         {
1448                 float l = c2Sqrt(d2);
1449                 c2v n = l != 0 ? c2Mulvs(d, 1.0f / l) : c2V(0, 1.0f);
1450                 m->count = 1;
1451                 m->depths[0] = r - l;
1452                 m->contact_points[0] = c2Sub(B.p, c2Mulvs(n, B.r));
1453                 m->n = n;
1454         }
1455 }
1456
1457 void c2CircletoAABBManifold(c2Circle A, c2AABB B, c2Manifold* m)
1458 {
1459         m->count = 0;
1460         c2v L = c2Clampv(A.p, B.min, B.max);
1461         c2v ab = c2Sub(L, A.p);
1462         float d2 = c2Dot(ab, ab);
1463         float r2 = A.r * A.r;
1464         if (d2 < r2)
1465         {
1466                 // shallow (center of circle not inside of AABB)
1467                 if (d2 != 0)
1468                 {
1469                         float d = c2Sqrt(d2);
1470                         c2v n = c2Norm(ab);
1471                         m->count = 1;
1472                         m->depths[0] = A.r - d;
1473                         m->contact_points[0] = c2Add(A.p, c2Mulvs(n, d));
1474                         m->n = n;
1475                 }
1476
1477                 // deep (center of circle inside of AABB)
1478                 // clamp circle's center to edge of AABB, then form the manifold
1479                 else
1480                 {
1481                         c2v mid = c2Mulvs(c2Add(B.min, B.max), 0.5f);
1482                         c2v e = c2Mulvs(c2Sub(B.max, B.min), 0.5f);
1483                         c2v d = c2Sub(A.p, mid);
1484                         c2v abs_d = c2Absv(d);
1485
1486                         float x_overlap = e.x - abs_d.x;
1487                         float y_overlap = e.y - abs_d.y;
1488
1489                         float depth;
1490                         c2v n;
1491
1492                         if (x_overlap < y_overlap)
1493                         {
1494                                 depth = x_overlap;
1495                                 n = c2V(1.0f, 0);
1496                                 n = c2Mulvs(n, d.x < 0 ? 1.0f : -1.0f);
1497                         }
1498
1499                         else
1500                         {
1501                                 depth = y_overlap;
1502                                 n = c2V(0, 1.0f);
1503                                 n = c2Mulvs(n, d.y < 0 ? 1.0f : -1.0f);
1504                         }
1505
1506                         m->count = 1;
1507                         m->depths[0] = A.r + depth;
1508                         m->contact_points[0] = c2Sub(A.p, c2Mulvs(n, depth));
1509                         m->n = n;
1510                 }
1511         }
1512 }
1513
1514 void c2CircletoCapsuleManifold(c2Circle A, c2Capsule B, c2Manifold* m)
1515 {
1516         m->count = 0;
1517         c2v a, b;
1518         float r = A.r + B.r;
1519         float d = c2GJK(&A, C2_TYPE_CIRCLE, 0, &B, C2_TYPE_CAPSULE, 0, &a, &b, 0, 0, 0);
1520         if (d < r)
1521         {
1522                 c2v n;
1523                 if (d == 0) n = c2Norm(c2Skew(c2Sub(B.b, B.a)));
1524                 else n = c2Norm(c2Sub(b, a));
1525
1526                 m->count = 1;
1527                 m->depths[0] = r - d;
1528                 m->contact_points[0] = c2Sub(b, c2Mulvs(n, B.r));
1529                 m->n = n;
1530         }
1531 }
1532
1533 void c2AABBtoAABBManifold(c2AABB A, c2AABB B, c2Manifold* m)
1534 {
1535         m->count = 0;
1536         c2v mid_a = c2Mulvs(c2Add(A.min, A.max), 0.5f);
1537         c2v mid_b = c2Mulvs(c2Add(B.min, B.max), 0.5f);
1538         c2v eA = c2Absv(c2Mulvs(c2Sub(A.max, A.min), 0.5f));
1539         c2v eB = c2Absv(c2Mulvs(c2Sub(B.max, B.min), 0.5f));
1540         c2v d = c2Sub(mid_b, mid_a);
1541
1542         // calc overlap on x and y axes
1543         float dx = eA.x + eB.x - c2Abs(d.x);
1544         if (dx < 0) return;
1545         float dy = eA.y + eB.y - c2Abs(d.y);
1546         if (dy < 0) return;
1547
1548         c2v n;
1549         float depth;
1550         c2v p;
1551
1552         // x axis overlap is smaller
1553         if (dx < dy)
1554         {
1555                 depth = dx;
1556                 if (d.x < 0)
1557                 {
1558                         n = c2V(-1.0f, 0);
1559                         p = c2Sub(mid_a, c2V(eA.x, 0));
1560                 }
1561                 else
1562                 {
1563                         n = c2V(1.0f, 0);
1564                         p = c2Add(mid_a, c2V(eA.x, 0));
1565                 }
1566         }
1567
1568         // y axis overlap is smaller
1569         else
1570         {
1571                 depth = dy;
1572                 if (d.y < 0)
1573                 {
1574                         n = c2V(0, -1.0f);
1575                         p = c2Sub(mid_a, c2V(0, eA.y));
1576                 }
1577                 else
1578                 {
1579                         n = c2V(0, 1.0f);
1580                         p = c2Add(mid_a, c2V(0, eA.y));
1581                 }
1582         }
1583
1584         m->count = 1;
1585         m->contact_points[0] = p;
1586         m->depths[0] = depth;
1587         m->n = n;
1588 }
1589
1590 void c2AABBtoCapsuleManifold(c2AABB A, c2Capsule B, c2Manifold* m)
1591 {
1592         m->count = 0;
1593         c2Poly p;
1594         c2BBVerts(p.verts, &A);
1595         p.count = 4;
1596         c2Norms(p.verts, p.norms, 4);
1597         c2CapsuletoPolyManifold(B, &p, 0, m);
1598         m->n = c2Neg(m->n);
1599 }
1600
1601 void c2CapsuletoCapsuleManifold(c2Capsule A, c2Capsule B, c2Manifold* m)
1602 {
1603         m->count = 0;
1604         c2v a, b;
1605         float r = A.r + B.r;
1606         float d = c2GJK(&A, C2_TYPE_CAPSULE, 0, &B, C2_TYPE_CAPSULE, 0, &a, &b, 0, 0, 0);
1607         if (d < r)
1608         {
1609                 c2v n;
1610                 if (d == 0) n = c2Norm(c2Skew(c2Sub(A.b, A.a)));
1611                 else n = c2Norm(c2Sub(b, a));
1612
1613                 m->count = 1;
1614                 m->depths[0] = r - d;
1615                 m->contact_points[0] = c2Sub(b, c2Mulvs(n, B.r));
1616                 m->n = n;
1617         }
1618 }
1619
1620 static C2_INLINE c2h c2PlaneAt(const c2Poly* p, const int i)
1621 {
1622         c2h h;
1623         h.n = p->norms[i];
1624         h.d = c2Dot(p->norms[i], p->verts[i]);
1625         return h;
1626 }
1627
1628 void c2CircletoPolyManifold(c2Circle A, const c2Poly* B, const c2x* bx_tr, c2Manifold* m)
1629 {
1630         m->count = 0;
1631         c2v a, b;
1632         float d = c2GJK(&A, C2_TYPE_CIRCLE, 0, B, C2_TYPE_POLY, bx_tr, &a, &b, 0, 0, 0);
1633
1634         // shallow, the circle center did not hit the polygon
1635         // just use a and b from GJK to define the collision
1636         if (d != 0)
1637         {
1638                 c2v n = c2Sub(b, a);
1639                 float l = c2Dot(n, n);
1640                 if (l < A.r * A.r)
1641                 {
1642                         l = c2Sqrt(l);
1643                         m->count = 1;
1644                         m->contact_points[0] = b;
1645                         m->depths[0] = A.r - l;
1646                         m->n = c2Mulvs(n, 1.0f / l);
1647                 }
1648         }
1649
1650         // Circle center is inside the polygon
1651         // find the face closest to circle center to form manifold
1652         else
1653         {
1654                 c2x bx = bx_tr ? *bx_tr : c2xIdentity();
1655                 float sep = -FLT_MAX;
1656                 int index = ~0;
1657                 c2v local = c2MulxvT(bx, A.p);
1658
1659                 for (int i = 0; i < B->count; ++i)
1660                 {
1661                         c2h h = c2PlaneAt(B, i);
1662                         d = c2Dist(h, local);
1663                         if (d > A.r) return;
1664                         if (d > sep)
1665                         {
1666                                 sep = d;
1667                                 index = i;
1668                         }
1669                 }
1670
1671                 c2h h = c2PlaneAt(B, index);
1672                 c2v p = c2Project(h, local);
1673                 m->count = 1;
1674                 m->contact_points[0] = c2Mulxv(bx, p);
1675                 m->depths[0] = A.r - sep;
1676                 m->n = c2Neg(c2Mulrv(bx.r, B->norms[index]));
1677         }
1678 }
1679
1680 // Forms a c2Poly and uses c2PolytoPolyManifold
1681 void c2AABBtoPolyManifold(c2AABB A, const c2Poly* B, const c2x* bx, c2Manifold* m)
1682 {
1683         m->count = 0;
1684         c2Poly p;
1685         c2BBVerts(p.verts, &A);
1686         p.count = 4;
1687         c2Norms(p.verts, p.norms, 4);
1688         c2PolytoPolyManifold(&p, 0, B, bx, m);
1689 }
1690
1691 // clip a segment to a plane
1692 static int c2Clip(c2v* seg, c2h h)
1693 {
1694         c2v out[2];
1695         int sp = 0;
1696         float d0, d1;
1697         if ((d0 = c2Dist(h, seg[0])) < 0) out[sp++] = seg[0];
1698         if ((d1 = c2Dist(h, seg[1])) < 0) out[sp++] = seg[1];
1699         if (d0 == 0 && d1 == 0) {
1700                 out[sp++] = seg[0];
1701                 out[sp++] = seg[1];
1702         } else if (d0 * d1 <= 0) out[sp++] = c2Intersect(seg[0], seg[1], d0, d1);
1703         seg[0] = out[0]; seg[1] = out[1];
1704         return sp;
1705 }
1706
1707 #ifdef _MSC_VER
1708         #pragma warning(push)
1709         #pragma warning(disable:4204) // nonstandard extension used: non-constant aggregate initializer
1710 #endif
1711
1712 // clip a segment to the "side planes" of another segment.
1713 // side planes are planes orthogonal to a segment and attached to the
1714 // endpoints of the segment
1715 static int c2SidePlanes(c2v* seg, c2x x, const c2Poly* p, int e, c2h* h)
1716 {
1717         c2v ra = c2Mulxv(x, p->verts[e]);
1718         c2v rb = c2Mulxv(x, p->verts[e + 1 == p->count ? 0 : e + 1]);
1719         c2v in = c2Norm(c2Sub(rb, ra));
1720         c2h left = { c2Neg(in), c2Dot(c2Neg(in), ra) };
1721         c2h right = { in, c2Dot(in, rb) };
1722         if (c2Clip(seg, left) < 2) return 0;
1723         if (c2Clip(seg, right) < 2) return 0;
1724         if (h) {
1725                 h->n = c2CCW90(in);
1726                 h->d = c2Dot(c2CCW90(in), ra);
1727         }
1728         return 1;
1729 }
1730
1731 static void c2KeepDeep(c2v* seg, c2h h, c2Manifold* m)
1732 {
1733         int cp = 0;
1734         for (int i = 0; i < 2; ++i)
1735         {
1736                 c2v p = seg[i];
1737                 float d = c2Dist(h, p);
1738                 if (d <= 0)
1739                 {
1740                         m->contact_points[cp] = p;
1741                         m->depths[cp] = -d;
1742                         ++cp;
1743                 }
1744         }
1745         m->count = cp;
1746         m->n = h.n;
1747 }
1748
1749 static C2_INLINE c2v c2CapsuleSupport(c2Capsule A, c2v dir)
1750 {
1751         float da = c2Dot(A.a, dir);
1752         float db = c2Dot(A.b, dir);
1753         if (da > db) return c2Add(A.a, c2Mulvs(dir, A.r));
1754         else return c2Add(A.b, c2Mulvs(dir, A.r));
1755 }
1756
1757 static void c2AntinormalFace(c2Capsule cap, const c2Poly* p, c2x x, int* face_out, c2v* n_out)
1758 {
1759         float sep = -FLT_MAX;
1760         int index = ~0;
1761         c2v n = c2V(0, 0);
1762         for (int i = 0; i < p->count; ++i)
1763         {
1764                 c2h h = c2Mulxh(x, c2PlaneAt(p, i));
1765                 c2v n0 = c2Neg(h.n);
1766                 c2v s = c2CapsuleSupport(cap, n0);
1767                 float d = c2Dist(h, s);
1768                 if (d > sep)
1769                 {
1770                         sep = d;
1771                         index = i;
1772                         n = n0;
1773                 }
1774         }
1775         *face_out = index;
1776         *n_out = n;
1777 }
1778
1779 void c2CapsuletoPolyManifold(c2Capsule A, const c2Poly* B, const c2x* bx_ptr, c2Manifold* m)
1780 {
1781         m->count = 0;
1782         c2v a, b;
1783         float d = c2GJK(&A, C2_TYPE_CAPSULE, 0, B, C2_TYPE_POLY, bx_ptr, &a, &b, 0, 0, 0);
1784
1785         // deep, treat as segment to poly collision
1786         if (d == 0)
1787         {
1788                 c2x bx = bx_ptr ? *bx_ptr : c2xIdentity();
1789                 c2v n;
1790                 int index;
1791                 c2AntinormalFace(A, B, bx, &index, &n);
1792                 c2v seg[2] = { A.a, A.b };
1793                 c2h h;
1794                 if (!c2SidePlanes(seg, bx, B, index, &h)) return;
1795                 c2KeepDeep(seg, h, m);
1796                 for (int i = 0; i < m->count; ++i)
1797                 {
1798                         m->depths[i] += c2Sign(m->depths) * A.r;
1799                         m->contact_points[i] = c2Add(m->contact_points[i], c2Mulvs(n, A.r));
1800                 }
1801                 m->n = c2Neg(m->n);
1802         }
1803
1804         // shallow, use GJK results a and b to define manifold
1805         else if (d < A.r)
1806         {
1807                 c2x bx = bx_ptr ? *bx_ptr : c2xIdentity();
1808                 c2v ab = c2Sub(b, a);
1809                 int face_case = 0;
1810
1811                 for (int i = 0; i < B->count; ++i)
1812                 {
1813                         c2v n = c2Mulrv(bx.r, B->norms[i]);
1814                         if (c2Parallel(c2Neg(ab), n, 5.0e-3f))
1815                         {
1816                                 face_case = 1;
1817                                 break;
1818                         }
1819                 }
1820
1821                 // 1 contact
1822                 if (!face_case)
1823                 {
1824                         one_contact:
1825                         m->count = 1;
1826                         m->n = c2Norm(ab);
1827                         m->contact_points[0] = c2Add(a, c2Mulvs(m->n, A.r));
1828                         m->depths[0] = A.r - d;
1829                 }
1830
1831                 // 2 contacts if laying on a polygon face nicely
1832                 else
1833                 {
1834                         c2v n;
1835                         int index;
1836                         c2AntinormalFace(A, B, bx, &index, &n);
1837                         c2v seg[2] = { c2Add(A.a, c2Mulvs(n, A.r)), c2Add(A.b, c2Mulvs(n, A.r)) };
1838                         c2h h;
1839                         if (!c2SidePlanes(seg, bx, B, index, &h)) goto one_contact;
1840                         c2KeepDeep(seg, h, m);
1841                         m->n = c2Neg(m->n);
1842                 }
1843         }
1844 }
1845
1846 #ifdef _MSC_VER
1847         #pragma warning(pop)
1848 #endif
1849
1850 static float c2CheckFaces(const c2Poly* A, c2x ax, const c2Poly* B, c2x bx, int* face_index)
1851 {
1852         c2x b_in_a = c2MulxxT(ax, bx);
1853         c2x a_in_b = c2MulxxT(bx, ax);
1854         float sep = -FLT_MAX;
1855         int index = ~0;
1856
1857         for (int i = 0; i < A->count; ++i)
1858         {
1859                 c2h h = c2PlaneAt(A, i);
1860                 int idx = c2Support(B->verts, B->count, c2Mulrv(a_in_b.r, c2Neg(h.n)));
1861                 c2v p = c2Mulxv(b_in_a, B->verts[idx]);
1862                 float d = c2Dist(h, p);
1863                 if (d > sep)
1864                 {
1865                         sep = d;
1866                         index = i;
1867                 }
1868         }
1869
1870         *face_index = index;
1871         return sep;
1872 }
1873
1874 static C2_INLINE void c2Incident(c2v* incident, const c2Poly* ip, c2x ix, const c2Poly* rp, c2x rx, int re)
1875 {
1876         c2v n = c2MulrvT(ix.r, c2Mulrv(rx.r, rp->norms[re]));
1877         int index = ~0;
1878         float min_dot = FLT_MAX;
1879         for (int i = 0; i < ip->count; ++i)
1880         {
1881                 float dot = c2Dot(n, ip->norms[i]);
1882                 if (dot < min_dot)
1883                 {
1884                         min_dot = dot;
1885                         index = i;
1886                 }
1887         }
1888         incident[0] = c2Mulxv(ix, ip->verts[index]);
1889         incident[1] = c2Mulxv(ix, ip->verts[index + 1 == ip->count ? 0 : index + 1]);
1890 }
1891
1892 // Please see Dirk Gregorius's 2013 GDC lecture on the Separating Axis Theorem
1893 // for a full-algorithm overview. The short description is:
1894         // Test A against faces of B, test B against faces of A
1895         // Define the reference and incident shapes (denoted by r and i respectively)
1896         // Define the reference face as the axis of minimum penetration
1897         // Find the incident face, which is most anti-normal face
1898         // Clip incident face to reference face side planes
1899         // Keep all points behind the reference face
1900 void c2PolytoPolyManifold(const c2Poly* A, const c2x* ax_ptr, const c2Poly* B, const c2x* bx_ptr, c2Manifold* m)
1901 {
1902         m->count = 0;
1903         c2x ax = ax_ptr ? *ax_ptr : c2xIdentity();
1904         c2x bx = bx_ptr ? *bx_ptr : c2xIdentity();
1905         int ea, eb;
1906         float sa, sb;
1907         if ((sa = c2CheckFaces(A, ax, B, bx, &ea)) >= 0) return;
1908         if ((sb = c2CheckFaces(B, bx, A, ax, &eb)) >= 0) return;
1909
1910         const c2Poly* rp,* ip;
1911         c2x rx, ix;
1912         int re;
1913         float kRelTol = 0.95f, kAbsTol = 0.01f;
1914         int flip;
1915         if (sa * kRelTol > sb + kAbsTol)
1916         {
1917                 rp = A; rx = ax;
1918                 ip = B; ix = bx;
1919                 re = ea;
1920                 flip = 0;
1921         }
1922         else
1923         {
1924                 rp = B; rx = bx;
1925                 ip = A; ix = ax;
1926                 re = eb;
1927                 flip = 1;
1928         }
1929
1930         c2v incident[2];
1931         c2Incident(incident, ip, ix, rp, rx, re);
1932         c2h rh;
1933         if (!c2SidePlanes(incident, rx, rp, re, &rh)) return;
1934         c2KeepDeep(incident, rh, m);
1935         if (flip) m->n = c2Neg(m->n);
1936 }
1937
1938 #endif // CUTE_C2_IMPLEMENTATION_ONCE
1939 #endif // CUTE_C2_IMPLEMENTATION