1bool AABBvsCircle( Manifold *m )
2{
3 // Setup a couple pointers to each object
4 Object *A = m->A
5 Object *B = m->B
6
7 // Vector from A to B
8 Vec2 n = B->pos - A->pos
9
10 // Closest point on A to center of B
11 Vec2 closest = n
12
13 // Calculate half extents along each axis
14 float x_extent = (A->aabb.max.x - A->aabb.min.x) / 2
15 float y_extent = (A->aabb.max.y - A->aabb.min.y) / 2
16
17 // Clamp point to edges of the AABB
18 closest.x = Clamp( -x_extent, x_extent, closest.x )
19 closest.y = Clamp( -y_extent, y_extent, closest.y )
20
21 bool inside = false
22
23 // Circle is inside the AABB, so we need to clamp the circle's center
24 // to the closest edge
25 if(n == closest)
26 {
27 inside = true
28
29 // Find closest axis
30 if(abs( n.x ) > abs( n.y ))
31 {
32 // Clamp to closest extent
33 if(closest.x > 0)
34 closest.x = x_extent
35 else
36 closest.x = -x_extent
37 }
38
39 // y axis is shorter
40 else
41 {
42 // Clamp to closest extent
43 if(closest.y > 0)
44 closest.y = y_extent
45 else
46 closest.y = -y_extent
47 }
48 }
49
50 Vec2 normal = n - closest
51 real d = normal.LengthSquared( )
52 real r = B->radius
53
54 // Early out of the radius is shorter than distance to closest point and
55 // Circle not inside the AABB
56 if(d > r * r && !inside)
57 return false
58
59 // Avoided sqrt until we needed
60 d = sqrt( d )
61
62 // Collision normal needs to be flipped to point outside if circle was
63 // inside the AABB
64 if(inside)
65 {
66 m->normal = -n
67 m->penetration = r - d
68 }
69 else
70 {
71 m->normal = n
72 m->penetration = r - d
73 }
74
75 return true
76}
77