/** Return true if the node should be traversed, and false if the bounding sphere of the node is small enough to be rendered by one Camera. If the latter is true, then store the node's near & far plane distances. */ bool CURRENT_CLASS::shouldContinueTraversal(osg::Node &node) { // Allow traversal to continue if we haven't reached maximum depth. bool keepTraversing = (_currentDepth < _maxDepth); const osg::BoundingSphere &bs = node.getBound(); double zNear = 0.0, zFar = 0.0; // Make sure bounding sphere is valid and within viewing volume if(bs.valid()) { if(!_localFrusta.back().contains(bs)) keepTraversing = false; else { // Compute near and far planes for this node zNear = distance(bs._center, _viewMatrices.back()); zFar = zNear + bs._radius; zNear -= bs._radius; // If near/far ratio is big enough, then we don't need to keep // traversing children of this node. if(zNear >= zFar*_nearFarRatio) keepTraversing = false; } } // If traversal should stop, then store this node's (near,far) pair if(!keepTraversing) pushDistancePair(zNear, zFar); return keepTraversing; }
bool PrimitiveIntersector::enter(const osg::Node& node) { if (reachedLimit()) return false; osg::BoundingSphere bs = node.getBound(); if (bs.valid()) { bs.radius() += (_thickness - _start).length(); } return !node.isCullingActive() || intersects(bs); }
bool PosterIntersector::enter( const osg::Node& node ) { if ( !node.isCullingActive() ) return true; if ( _polytope.contains(node.getBound()) ) { if ( node.getCullCallback() ) { const osg::ClusterCullingCallback* cccb = dynamic_cast<const osg::ClusterCullingCallback*>( node.getCullCallback() ); if ( cccb && cccb->cull(_intersectionVisitor, 0, NULL) ) return false; } return true; } return false; }
/** Return true if the node should be traversed, and false if the bounding sphere of the node is small enough to be rendered by one Camera. If the latter is true, then store the node's near & far plane distances. */ bool CURRENT_CLASS::shouldContinueTraversal(osg::Node &node) { // Allow traversal to continue if we haven't reached maximum depth. bool keepTraversing = (_currentDepth < _maxDepth); osg::BoundingSphere bs = node.getBound(); double zNear = 0.0, zFar = 0.0; // Make sure bounding sphere is valid if(bs.valid()) { // Make sure bounding sphere is within the viewing volume bool containsTest = _localFrusta.back().contains(bs); if(!containsTest) keepTraversing = false; else // Compute near and far planes for this node { // Since the view matrix could involve complex transformations, // we need to determine a new BoundingSphere that would encompass // the transformed BoundingSphere. const osg::Matrix &l2w = _viewMatrices.back(); // Get the transformed x-axis of the BoundingSphere osg::Vec3d newX = bs._center; newX.x() += bs._radius; // Get X-edge of bounding sphere newX = newX * l2w; // Get the transformed y-axis of the BoundingSphere osg::Vec3d newY = bs._center; newY.y() += bs._radius; // Get Y-edge of bounding sphere newY = newY * l2w; // Get the transformed z-axis of the BoundingSphere osg::Vec3d newZ = bs._center; newZ.z() += bs._radius; // Get Z-edge of bounding sphere newZ = newZ * l2w; // Get the transformed center of the BoundingSphere bs._center = bs._center * l2w; // Compute lengths of transformed x, y, and z axes double newXLen = (newX - bs._center).length(); double newYLen = (newY - bs._center).length(); double newZLen = (newZ - bs._center).length(); // The encompassing radius is the max of the transformed lengths bs._radius = newXLen; if(newYLen > bs._radius) bs._radius = newYLen; if(newZLen > bs._radius) bs._radius = newZLen; // Now we can compute the near & far planes, noting that for // complex view transformations (ie. involving scales) the new // BoundingSphere may be bigger than the original one. // Note that the negative sign on the bounding sphere center is // because we want distance to increase INTO the screen. zNear = -bs._center.z() - bs._radius; zFar = -bs._center.z() + bs._radius; // If near/far ratio is big enough, then we don't need to keep // traversing children of this node. if(zNear >= zFar * _nearFarRatio) keepTraversing = false; } } // If traversal should stop, then store this node's (near,far) pair if(!keepTraversing) pushDistancePair(zNear,zFar); return keepTraversing; }
bool ProxyCullVisitor::isCulledByProxyFrustum(osg::Node& node) { return node.isCullingActive() && !_proxyFrustum.contains(node.getBound()); }
bool PolytopeIntersector::enter(const osg::Node& node) { if (reachedLimit()) return false; return !node.isCullingActive() || _polytope.contains( node.getBound() ); }
bool LineSegmentIntersector::enter(const osg::Node& node) { return !node.isCullingActive() || intersects( node.getBound() ); }