1 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3 * Planes-AABB overlap test.
4 * - original code by Ville Miettinen, from Umbra/dPVS (released on the GD-Algorithms mailing list)
5 * - almost used "as-is", I even left the comments (hence the frustum-related notes)
7 * \param center [in] box center
8 * \param extents [in] box extents
9 * \param out_clip_mask [out] bitmask for active planes
10 * \param in_clip_mask [in] bitmask for active planes
11 * \return TRUE if boxes overlap planes
13 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
14 inline_ BOOL
PlanesCollider::PlanesAABBOverlap(const Point
& center
, const Point
& extents
, udword
& out_clip_mask
, udword in_clip_mask
)
19 const Plane
* p
= mPlanes
;
21 // Evaluate through all active frustum planes. We determine the relation
22 // between the AABB and a plane by using the concept of "near" and "far"
23 // vertices originally described by Zhang (and later by Möller). Our
24 // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point
25 // comparisons per plane. The routine early-exits if the AABB is found
26 // to be outside any of the planes. The loop also constructs a new output
27 // clip mask. Most FPUs have a native single-cycle fabsf() operation.
29 udword Mask
= 1; // current mask index (1,2,4,8,..)
30 udword TmpOutClipMask
= 0; // initialize output clip mask into empty.
32 while(Mask
<=in_clip_mask
) // keep looping while we have active planes left...
34 if(in_clip_mask
& Mask
) // if clip plane is active, process it..
36 float NP
= extents
.x
*fabsf(p
->n
.x
) + extents
.y
*fabsf(p
->n
.y
) + extents
.z
*fabsf(p
->n
.z
); // ### fabsf could be precomputed
37 float MP
= center
.x
*p
->n
.x
+ center
.y
*p
->n
.y
+ center
.z
*p
->n
.z
+ p
->d
;
39 if(NP
< MP
) // near vertex behind the clip plane...
40 return FALSE
; // .. so there is no intersection..
41 if((-NP
) < MP
) // near and far vertices on different sides of plane..
42 TmpOutClipMask
|= Mask
; // .. so update the clip mask...
44 Mask
+=Mask
; // mk = (1<<plane)
45 p
++; // advance to next plane
48 out_clip_mask
= TmpOutClipMask
; // copy output value (temp used to resolve aliasing!)
49 return TRUE
; // indicate that AABB intersects frustum