1 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
2 | /** |
---|
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) |
---|
6 | * |
---|
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 |
---|
12 | */ |
---|
13 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
---|
14 | inline_ BOOL PlanesCollider::PlanesAABBOverlap(const Point& center, const Point& extents, udword& out_clip_mask, udword in_clip_mask) |
---|
15 | { |
---|
16 | // Stats |
---|
17 | mNbVolumeBVTests++; |
---|
18 | |
---|
19 | const Plane* p = mPlanes; |
---|
20 | |
---|
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. |
---|
28 | |
---|
29 | udword Mask = 1; // current mask index (1,2,4,8,..) |
---|
30 | udword TmpOutClipMask = 0; // initialize output clip mask into empty. |
---|
31 | |
---|
32 | while(Mask<=in_clip_mask) // keep looping while we have active planes left... |
---|
33 | { |
---|
34 | if(in_clip_mask & Mask) // if clip plane is active, process it.. |
---|
35 | { |
---|
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; |
---|
38 | |
---|
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... |
---|
43 | } |
---|
44 | Mask+=Mask; // mk = (1<<plane) |
---|
45 | p++; // advance to next plane |
---|
46 | } |
---|
47 | |
---|
48 | out_clip_mask = TmpOutClipMask; // copy output value (temp used to resolve aliasing!) |
---|
49 | return TRUE; // indicate that AABB intersects frustum |
---|
50 | } |
---|