示例#1
0
void Terrain::traverse(osg::NodeVisitor &nv)
{
    if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
    {
        // need to check if any TerrainTechniques need to have their update called on them.
        osgUtil::UpdateVisitor *uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
        if (uv)
        {
            typedef std::list<osg::ref_ptr<TerrainTile> >  TerrainTileList;
            TerrainTileList tiles;
            {
                OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_mutex);

                for (TerrainTileSet::iterator itr = _updateTerrainTileSet.begin(); itr != _updateTerrainTileSet.end(); ++itr)
                {
                    // take a reference first to make sure that the referenceCount can be safely read without another thread decrementing it to zero.
                    (*itr)->ref();

                    // only if referenceCount is 2 or more indicating there is still a reference held elsewhere is it safe to add it to list of tiles to be updated
                    if ((*itr)->referenceCount() > 1)
                        tiles.push_back(*itr);

                    // use unref_nodelete to avoid any issues when the *itr TerrainTile has been deleted by another thread while this for loop has been running.
                    (*itr)->unref_nodelete();
                }

                _updateTerrainTileSet.clear();
            }

            for (TerrainTileList::iterator itr = tiles.begin();
                 itr != tiles.end();
                 ++itr)
            {
                TerrainTile *tile = itr->get();
                tile->traverse(nv);
            }
        }
    }

    if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
    {
        osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
        osg::StateSet        *ss = _geometryPool.valid() ? _geometryPool->getRootStateSetForTerrain(this) : 0;
        if (cv && ss)
        {
            cv->pushStateSet(ss);
            Group::traverse(nv);
            cv->popStateSet();
            return;
        }
    }

    Group::traverse(nv);
}
void Terrain::traverse(osg::NodeVisitor& nv)
{
    if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
    {
        // need to check if any TerrainTechniques need to have their update called on them.
        osgUtil::UpdateVisitor* uv = dynamic_cast<osgUtil::UpdateVisitor*>(&nv);
        if (uv)
        {
            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
            for(TerrainTileSet::iterator itr = _updateTerrainTileSet.begin();
                itr != _updateTerrainTileSet.end();
                ++itr)
            {
                TerrainTile* tile = *itr;
                tile->traverse(nv);
            }
            _updateTerrainTileSet.clear();
        }
    }

    Group::traverse(nv);
}