00001 00002 00013 00014 inline_ BOOL PlanesCollider::PlanesAABBOverlap(const Point& center, const Point& extents, udword& out_clip_mask, udword in_clip_mask) 00015 { 00016 // Stats 00017 mNbVolumeBVTests++; 00018 00019 const Plane* p = mPlanes; 00020 00021 // Evaluate through all active frustum planes. We determine the relation 00022 // between the AABB and a plane by using the concept of "near" and "far" 00023 // vertices originally described by Zhang (and later by Moller). Our 00024 // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point 00025 // comparisons per plane. The routine early-exits if the AABB is found 00026 // to be outside any of the planes. The loop also constructs a new output 00027 // clip mask. Most FPUs have a native single-cycle fabsf() operation. 00028 00029 udword Mask = 1; // current mask index (1,2,4,8,..) 00030 udword TmpOutClipMask = 0; // initialize output clip mask into empty. 00031 00032 while(Mask<=in_clip_mask) // keep looping while we have active planes left... 00033 { 00034 if(in_clip_mask & Mask) // if clip plane is active, process it.. 00035 { 00036 float NP = extents.x*fabsf(p->n.x) + extents.y*fabsf(p->n.y) + extents.z*fabsf(p->n.z); // ### fabsf could be precomputed 00037 float MP = center.x*p->n.x + center.y*p->n.y + center.z*p->n.z + p->d; 00038 00039 if(NP < MP) // near vertex behind the clip plane... 00040 return FALSE; // .. so there is no intersection.. 00041 if((-NP) < MP) // near and far vertices on different sides of plane.. 00042 TmpOutClipMask |= Mask; // .. so update the clip mask... 00043 } 00044 Mask+=Mask; // mk = (1<<plane) 00045 p++; // advance to next plane 00046 } 00047 00048 out_clip_mask = TmpOutClipMask; // copy output value (temp used to resolve aliasing!) 00049 return TRUE; // indicate that AABB intersects frustum 00050 }