bool Frustum::TestSweptSphere( const SVector3& pos, float radius, const SVector3& sweepDir ) const { // algorithm -- get all 12 intersection points of the swept sphere with the view frustum // for all points >0, displace sphere along the sweep direction. if the displaced sphere // is inside the frustum, return true. else, return false float displacements[12]; int cnt = 0; float a, b; bool inFrustum = false; for (int i=0; i<6; i++) { if (SweptSpherePlaneIntersect(a, b, camPlanes[i], pos, radius, sweepDir)) { if (a>=0.f) displacements[cnt++] = a; if (b>=0.f) displacements[cnt++] = b; } } for (int i=0; i<cnt; i++) { SVector3 displPos = pos + sweepDir * displacements[i]; float displRadius = radius * 1.1f; inFrustum |= TestSphere( displPos, displRadius ); } return inFrustum; }
plCullNode::plCullStatus plCullNode::ITestSphereRecur(const hsPoint3& center, float rad) const { plCullNode::plCullStatus retVal = TestSphere(center, rad); // No Children, what we say goes. if( (fOuterChild < 0) && (fInnerChild < 0) ) return retVal; // No innerchild. If we cull, it's culled, else we // hope our outerchild culls it. if( fInnerChild < 0 ) { if( retVal == kCulled ) return kCulled; return IGetNode(fOuterChild)->ITestSphereRecur(center, rad); } // No outerchild. If we say it's clear, it's clear (or split), but if // it's culled, we have to pass it to innerchild, who may pronounce it clear if( fOuterChild < 0 ) { if( retVal == kClear ) return kClear; if( retVal == kSplit ) return kSplit; return IGetNode(fInnerChild)->ITestSphereRecur(center, rad); } // We've got both children to feed. // We pass the clear ones to the inner child, culled to outer, // and split to both. Remember, a both children have to agree to cull a split. if( retVal == kClear ) return IGetNode(fOuterChild)->ITestSphereRecur(center, rad); if( retVal == kCulled ) return IGetNode(fInnerChild)->ITestSphereRecur(center, rad); // Here's the split, to be culled, both children have to // say its culled. if( kCulled != IGetNode(fOuterChild)->ITestSphereRecur(center, rad) ) return kSplit; if( kCulled != IGetNode(fInnerChild)->ITestSphereRecur(center, rad) ) return kSplit; return kCulled; }