| 392 | //------------------------------------------------------------------------ |
| 393 | |
| 394 | static PX_FORCE_INLINE bool planesAABBOverlap(const PxBounds3& a, const PxPlane* p, PxU32& out_clip_mask, PxU32 in_clip_mask) |
| 395 | { |
| 396 | //------------------------------------------------------------------------ |
| 397 | // Convert the AABB from (minimum,maximum) form into (center,half-diagonal). |
| 398 | // Note that we could get rid of these six subtractions and three |
| 399 | // multiplications if the AABB was originally expressed in (center, |
| 400 | // half-diagonal) form. |
| 401 | //------------------------------------------------------------------------ |
| 402 | |
| 403 | PxVec3 m = a.getCenter(); // get center of AABB ((minimum+maximum)*0.5f) |
| 404 | PxVec3 d = a.maximum; d-=m; // get positive half-diagonal (maximum - center) |
| 405 | |
| 406 | //------------------------------------------------------------------------ |
| 407 | // Evaluate through all active frustum planes. We determine the relation |
| 408 | // between the AABB and a plane by using the concept of "near" and "far" |
| 409 | // vertices originally described by Zhang (and later by Moeller). Our |
| 410 | // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point |
| 411 | // comparisons per plane. The routine early-exits if the AABB is found |
| 412 | // to be outside any of the planes. The loop also constructs a new output |
| 413 | // clip mask. Most FPUs have a native single-cycle fabsf() operation. |
| 414 | //------------------------------------------------------------------------ |
| 415 | |
| 416 | PxU32 Mask = 1; // current mask index (1,2,4,8,..) |
| 417 | PxU32 TmpOutClipMask = 0; // initialize output clip mask into empty. |
| 418 | |
| 419 | while(Mask<=in_clip_mask) // keep looping while we have active planes left... |
| 420 | { |
| 421 | if(in_clip_mask & Mask) // if clip plane is active, process it.. |
| 422 | { |
| 423 | const float NP = d.x*PxAbs(p->n.x) + d.y*PxAbs(p->n.y) + d.z*PxAbs(p->n.z); |
| 424 | const float MP = m.x*p->n.x + m.y*p->n.y + m.z*p->n.z + p->d; |
| 425 | |
| 426 | if(NP < MP) // near vertex behind the clip plane... |
| 427 | return false; // .. so there is no intersection.. |
| 428 | if((-NP) < MP) // near and far vertices on different sides of plane.. |
| 429 | TmpOutClipMask |= Mask; // .. so update the clip mask... |
| 430 | } |
| 431 | Mask+=Mask; // mk = (1<<plane) |
| 432 | p++; // advance to next plane |
| 433 | } |
| 434 | |
| 435 | out_clip_mask = TmpOutClipMask; // copy output value (temp used to resolve aliasing!) |
| 436 | return true; // indicate that AABB intersects frustum |
| 437 | } |
| 438 | |
| 439 | PlaneAABBCode Camera::cull(const PxBounds3& aabb) const |
| 440 | { |