Exemplo n.º 1
0
void CURRENT_CLASS::apply(osg::Geode &geode)
{
    // Contained drawables will only be individually considered if we are
    // allowed to continue traversing.
    if(shouldContinueTraversal(geode))
    {
        osg::Drawable *drawable;
        double zNear, zFar;

        // Handle each drawable in this geode
        for(unsigned int i = 0; i < geode.getNumDrawables(); ++i)
        {
            drawable = geode.getDrawable(i);

            const osg::BoundingBox &bb = drawable->getBound();
            if(bb.valid())
            {
                bool containsTest = _localFrusta.back().contains(bb);
                // Make sure drawable will be visible in the scene
                if(!containsTest)
                    continue;

                // Compute near/far distances for current drawable
                zNear = distanceDA(bb.corner(_bbCorners.back().first),
                        _viewMatrices.back());
                zFar = distanceDA(bb.corner(_bbCorners.back().second),
                        _viewMatrices.back());
                if(zNear > zFar)
                    std::swap(zNear,zFar);
                pushDistancePair(zNear,zFar);
            }
        }
    }
}
Exemplo n.º 2
0
/** 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;
}
Exemplo n.º 3
0
/** 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;
}