OPC_PlanesAABBOverlap.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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. const Plane* p = mPlanes;
  19. // Evaluate through all active frustum planes. We determine the relation
  20. // between the AABB and a plane by using the concept of "near" and "far"
  21. // vertices originally described by Zhang (and later by Möller). Our
  22. // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point
  23. // comparisons per plane. The routine early-exits if the AABB is found
  24. // to be outside any of the planes. The loop also constructs a new output
  25. // clip mask. Most FPUs have a native single-cycle fabsf() operation.
  26. udword Mask = 1; // current mask index (1,2,4,8,..)
  27. udword TmpOutClipMask = 0; // initialize output clip mask into empty.
  28. while(Mask<=in_clip_mask) // keep looping while we have active planes left...
  29. {
  30. if(in_clip_mask & Mask) // if clip plane is active, process it..
  31. {
  32. float NP = extents.x*fabsf(p->n.x) + extents.y*fabsf(p->n.y) + extents.z*fabsf(p->n.z); // ### fabsf could be precomputed
  33. float MP = center.x*p->n.x + center.y*p->n.y + center.z*p->n.z + p->d;
  34. if(NP < MP) // near vertex behind the clip plane...
  35. return FALSE; // .. so there is no intersection..
  36. if((-NP) < MP) // near and far vertices on different sides of plane..
  37. TmpOutClipMask |= Mask; // .. so update the clip mask...
  38. }
  39. Mask+=Mask; // mk = (1<<plane)
  40. p++; // advance to next plane
  41. }
  42. out_clip_mask = TmpOutClipMask; // copy output value (temp used to resolve aliasing!)
  43. return TRUE; // indicate that AABB intersects frustum
  44. }