void RexTerrainEngineNode::traverse(osg::NodeVisitor& nv) { if ( nv.getVisitorType() == nv.CULL_VISITOR ) { // Inform the registry of the current frame so that Tiles have access // to the information. if ( _liveTiles.valid() && nv.getFrameStamp() ) { _liveTiles->setTraversalFrame( nv.getFrameStamp()->getFrameNumber() ); } } #if 0 static int c = 0; if ( ++c % 60 == 0 ) { OE_NOTICE << LC << "Live = " << _liveTiles->size() << ", Dead = " << _deadTiles->size() << std::endl; _liveTiles->run( CheckForOrphans() ); } #endif if ( nv.getVisitorType() == nv.CULL_VISITOR && _loader.valid() ) // ensures that postInitialize has run { osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv); this->getEngineContext()->startCull( cv ); TerrainCuller culler; culler.setFrameStamp(new osg::FrameStamp(*nv.getFrameStamp())); culler.setDatabaseRequestHandler(nv.getDatabaseRequestHandler()); culler.pushReferenceViewPoint(cv->getReferenceViewPoint()); culler.pushViewport(cv->getViewport()); culler.pushProjectionMatrix(cv->getProjectionMatrix()); culler.pushModelViewMatrix(cv->getModelViewMatrix(), cv->getCurrentCamera()->getReferenceFrame()); culler._camera = cv->getCurrentCamera(); culler._context = this->getEngineContext(); culler.setup(*_update_mapf, this->getEngineContext()->getRenderBindings(), getSurfaceStateSet()); // Assemble the terrain drawable: _terrain->accept(culler); // If we're using geometry pooling, optimize the drawable for shared state: if (getEngineContext()->getGeometryPool()->isEnabled()) { culler._terrain.sortDrawCommands(); } // The common stateset for the terrain: cv->pushStateSet(_terrain->getOrCreateStateSet()); // Push all the layers to draw on to the cull visitor, // keeping track of render order. LayerDrawable* lastLayer = 0L; unsigned order = 0; bool surfaceStateSetPushed = false; // OE_INFO << "CULL:\n"; for(LayerDrawableList::iterator i = culler._terrain.layers().begin(); i != culler._terrain.layers().end(); ++i) { if (!i->get()->_tiles.empty()) { lastLayer = i->get(); lastLayer->_order = -1; // if this is a RENDERTYPE_TILE, we need to activate the default surface state set. if (lastLayer->_layer && lastLayer->_layer->getRenderType() == Layer::RENDERTYPE_TILE) { lastLayer->_order = order++; if (!surfaceStateSetPushed) cv->pushStateSet(getSurfaceStateSet()); surfaceStateSetPushed = true; } else if (surfaceStateSetPushed) { cv->popStateSet(); surfaceStateSetPushed = false; } // OE_INFO << " Apply: " << (lastLayer->_layer ? lastLayer->_layer->getName() : "-1") << std::endl; cv->apply(*lastLayer); } } // The last layer to render must clear up the OSG state, // otherwise it will be corrupt and can lead to crashing. if (lastLayer) { lastLayer->_clearOsgState = true; } if (surfaceStateSetPushed) { cv->popStateSet(); surfaceStateSetPushed = false; } // pop the common terrain state set cv->popStateSet(); this->getEngineContext()->endCull( cv ); // traverse all the other children (geometry pool, loader/unloader, etc.) for (unsigned i = 0; i<getNumChildren(); ++i) { if (getChild(i) != _terrain.get()) getChild(i)->accept(nv); } } //else { TerrainEngineNode::traverse( nv ); } }
void RexTerrainEngineNode::traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType() == nv.UPDATE_VISITOR) { if (_renderModelUpdateRequired) { UpdateRenderModels visitor(_mapFrame); _terrain->accept(visitor); _renderModelUpdateRequired = false; } TerrainEngineNode::traverse( nv ); } else if ( nv.getVisitorType() == nv.CULL_VISITOR ) { // Inform the registry of the current frame so that Tiles have access // to the information. if ( _liveTiles.valid() && nv.getFrameStamp() ) { _liveTiles->setTraversalFrame( nv.getFrameStamp()->getFrameNumber() ); } osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv); getEngineContext()->startCull( cv ); TerrainCuller culler; culler.setFrameStamp(new osg::FrameStamp(*nv.getFrameStamp())); culler.setDatabaseRequestHandler(nv.getDatabaseRequestHandler()); culler.pushReferenceViewPoint(cv->getReferenceViewPoint()); culler.pushViewport(cv->getViewport()); culler.pushProjectionMatrix(cv->getProjectionMatrix()); culler.pushModelViewMatrix(cv->getModelViewMatrix(), cv->getCurrentCamera()->getReferenceFrame()); culler._camera = cv->getCurrentCamera(); culler._context = this->getEngineContext(); // Prepare the culler with the set of renderable layers: culler.setup(_mapFrame, this->getEngineContext()->getRenderBindings()); // Assemble the terrain drawable: _terrain->accept(culler); // If we're using geometry pooling, optimize the drawable for shared state: if (getEngineContext()->getGeometryPool()->isEnabled()) { culler._terrain.sortDrawCommands(); } // The common stateset for the terrain: cv->pushStateSet(_terrain->getOrCreateStateSet()); // Push all the layers to draw on to the cull visitor, // keeping track of render order. LayerDrawable* lastLayer = 0L; unsigned order = 0; bool surfaceStateSetPushed = false; //OE_INFO << "CULL\n"; for(LayerDrawableList::iterator i = culler._terrain.layers().begin(); i != culler._terrain.layers().end(); ++i) { if (!i->get()->_tiles.empty()) { lastLayer = i->get(); lastLayer->_order = -1; // if this is a RENDERTYPE_TILE, we need to activate the default surface state set. if (lastLayer->_renderType == Layer::RENDERTYPE_TILE) { lastLayer->_order = order++; if (!surfaceStateSetPushed) cv->pushStateSet(getSurfaceStateSet()); surfaceStateSetPushed = true; } else if (surfaceStateSetPushed) { cv->popStateSet(); surfaceStateSetPushed = false; } //OE_INFO << " Apply: " << (lastLayer->_layer ? lastLayer->_layer->getName() : "-1") << "; tiles=" << lastLayer->_tiles.size() << std::endl; cv->apply(*lastLayer); } } // The last layer to render must clear up the OSG state, // otherwise it will be corrupt and can lead to crashing. if (lastLayer) { lastLayer->_clearOsgState = true; } if (surfaceStateSetPushed) { cv->popStateSet(); surfaceStateSetPushed = false; } // pop the common terrain state set cv->popStateSet(); this->getEngineContext()->endCull( cv ); // If the culler found any orphaned data, we need to update the render model // during the next update cycle. if (culler._orphanedPassesDetected > 0u) { _renderModelUpdateRequired = true; OE_INFO << LC << "Detected " << culler._orphanedPassesDetected << " orphaned rendering passes\n"; } // we don't call this b/c we don't want _terrain //TerrainEngineNode::traverse(nv); // traverse all the other children (geometry pool, loader/unloader, etc.) _geometryPool->accept(nv); _loader->accept(nv); _unloader->accept(nv); _releaser->accept(nv); _rasterizer->accept(nv); } else { TerrainEngineNode::traverse( nv ); } }