Ejemplo n.º 1
0
void 
ProxyCullVisitor::apply(osg::Geode& node)
{
    //OE_INFO << "Geode!" << std::endl;

    if ( isCulledByProxyFrustum(node) )
        return;

    _cv->pushOntoNodePath( &node );

    // push the node's state.
    osg::StateSet* node_state = node.getStateSet();
    if (node_state) _cv->pushStateSet(node_state);

    // traverse any call callbacks and traverse any children.
    handle_cull_callbacks_and_traverse(node);

    osg::RefMatrix& matrix = *_cv->getModelViewMatrix();
    for(unsigned int i=0;i<node.getNumDrawables();++i)
    {
        osg::Drawable* drawable = node.getDrawable(i);
        const osg::BoundingBox& bb =drawable->getBound();

        if( drawable->getCullCallback() )
        {
            if( drawable->getCullCallback()->cull( _cv, drawable, &_cv->getRenderInfo() ) == true )
                continue;
        }

        //else
        {
            if (node.isCullingActive() && isCulledByProxyFrustum(bb)) continue;
        }


        if ( _cv->getComputeNearFarMode() && bb.valid())
        {
            if (!_cv->updateCalculatedNearFar(matrix,*drawable,false)) continue;
        }

        // need to track how push/pops there are, so we can unravel the stack correctly.
        unsigned int numPopStateSetRequired = 0;

        // push the geoset's state on the geostate stack.
        osg::StateSet* stateset = drawable->getStateSet();
        if (stateset)
        {
            ++numPopStateSetRequired;
            _cv->pushStateSet(stateset);
        }

        osg::CullingSet& cs = _cv->getCurrentCullingSet();
        if (!cs.getStateFrustumList().empty())
        {
            osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
            for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
                itr != sfl.end();
                ++itr)
            {
                if (itr->second.contains(bb))
                {
                    ++numPopStateSetRequired;
                    _cv->pushStateSet(itr->first.get());
                }
            }
        }

        float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;

        if (osg::isNaN(depth))
        {
            for (osg::NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i)
            {
                OSG_DEBUG << "        \"" << (*i)->getName() << "\"" << std::endl;
            }
        }
        else
        {
            _cv->addDrawableAndDepth(drawable,&matrix,depth);
        }

        for(unsigned int i=0;i< numPopStateSetRequired; ++i)
        {
            _cv->popStateSet();
        }

    }

    // pop the node's state off the geostate stack.
    if (node_state) _cv->popStateSet();

    _cv->popFromNodePath();
}
Ejemplo n.º 2
0
void CVRCullVisitor::apply(osg::Geode& node)
{
    bool status = _cullingStatus;
    bool firstStatus = _firstCullStatus;
    if(isCulled(node))
    {
        _firstCullStatus = firstStatus;
        _cullingStatus = status;
        return;
    }

    // push the node's state.
    StateSet* node_state = node.getStateSet();
    if(node_state)
        pushStateSet(node_state);

    // traverse any call callbacks and traverse any children.
    handle_cull_callbacks_and_traverse(node);

    RefMatrix& matrix = *getModelViewMatrix();
    for(unsigned int i = 0; i < node.getNumDrawables(); ++i)
    {
        Drawable* drawable = node.getDrawable(i);
        const BoundingBox &bb = drawable->getBound();

        if(drawable->getCullCallback())
        {
            if(drawable->getCullCallback()->cull(this,drawable,&_renderInfo)
                    == true)
                continue;
        }

        //else
        {
            if(node.isCullingActive() && isCulled(bb))
                continue;
        }

        if(_computeNearFar && bb.valid())
        {
            if(!updateCalculatedNearFar(matrix,*drawable,false))
                continue;
        }

        // need to track how push/pops there are, so we can unravel the stack correctly.
        unsigned int numPopStateSetRequired = 0;

        // push the geoset's state on the geostate stack.    
        StateSet* stateset = drawable->getStateSet();
        if(stateset)
        {
            ++numPopStateSetRequired;
            pushStateSet(stateset);
        }

        CullingSet& cs = getCurrentCullingSet();
        if(!cs.getStateFrustumList().empty())
        {
            osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
            for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
                    itr != sfl.end(); ++itr)
            {
                if(itr->second.contains(bb))
                {
                    ++numPopStateSetRequired;
                    pushStateSet(itr->first.get());
                }
            }
        }

        float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;

        if(osg::isNaN(depth))
        {
            /*OSG_NOTIFY(osg::NOTICE)<<"CullVisitor::apply(Geode&) detected NaN,"<<std::endl
             <<"    depth="<<depth<<", center=("<<bb.center()<<"),"<<std::endl
             <<"    matrix="<<matrix<<std::endl;
             OSG_NOTIFY(osg::DEBUG_INFO) << "    NodePath:" << std::endl;
             for (NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i)
             {
             OSG_NOTIFY(osg::DEBUG_INFO) << "        \"" << (*i)->getName() << "\"" << std::endl;
             }*/
        }
        else
        {
            addDrawableAndDepth(drawable,&matrix,depth);
        }

        for(unsigned int i = 0; i < numPopStateSetRequired; ++i)
        {
            popStateSet();
        }

    }

    // pop the node's state off the geostate stack.    
    if(node_state)
        popStateSet();

    _firstCullStatus = firstStatus;
    _cullingStatus = status;
}