void TerrainTileModelFactory::addPatchLayers(TerrainTileModel* model, const Map* map, const TileKey& key, const CreateTileModelFilter& filter, ProgressCallback* progress) { OE_START_TIMER(fetch_patch_layers); PatchLayerVector patchLayers; map->getLayers(patchLayers); for(PatchLayerVector::const_iterator i = patchLayers.begin(); i != patchLayers.end(); ++i ) { PatchLayer* layer = i->get(); if (!filter.accept(layer)) continue; if (!layer->getEnabled()) continue; if (layer->getAcceptCallback() == 0L || layer->getAcceptCallback()->acceptKey(key)) { PatchLayer::TileData* tileData = layer->createTileData(key); if (tileData) { TerrainTilePatchLayerModel* patchModel = new TerrainTilePatchLayerModel(); patchModel->setPatchLayer(layer); patchModel->setTileData(tileData); model->patchLayers().push_back(patchModel); } } } if (progress) progress->stats()["fetch_patches_time"] += OE_STOP_TIMER(fetch_patch_layers); }
void TerrainCuller::apply(osg::Node& node) { // push the node's state. osg::StateSet* node_state = node.getStateSet(); TileNode* tileNode = dynamic_cast<TileNode*>(&node); if (tileNode) { _currentTileNode = tileNode; _currentTileDrawCommands = 0u; if (!_terrain.patchLayers().empty()) { // todo: check for patch/virtual const RenderBindings& bindings = _context->getRenderBindings(); TileRenderModel& renderModel = _currentTileNode->renderModel(); bool pushedMatrix = false; for (PatchLayerVector::const_iterator i = _terrain.patchLayers().begin(); i != _terrain.patchLayers().end(); ++i) { PatchLayer* layer = i->get(); if (layer->getAcceptCallback() == 0L || layer->getAcceptCallback()->acceptKey(_currentTileNode->getKey())) { // Push this tile's matrix if we haven't already done so: if (!pushedMatrix) { SurfaceNode* surface = tileNode->getSurfaceNode(); // push the surface matrix: osg::Matrix mvm = *getModelViewMatrix(); surface->computeLocalToWorldMatrix(mvm, this); pushModelViewMatrix(createOrReuseMatrix(mvm), surface->getReferenceFrame()); pushedMatrix = true; } // Add the draw command: DrawTileCommand* cmd = addDrawCommand(layer->getUID(), &renderModel, 0L, tileNode); if (cmd) { cmd->_drawPatch = true; cmd->_drawCallback = layer->getDrawCallback(); ++_currentTileDrawCommands; } } } if (pushedMatrix) { popModelViewMatrix(); } } } else { SurfaceNode* surface = dynamic_cast<SurfaceNode*>(&node); if (surface) { TileRenderModel& renderModel = _currentTileNode->renderModel(); // push the surface matrix: osg::Matrix mvm = *getModelViewMatrix(); surface->computeLocalToWorldMatrix(mvm, this); pushModelViewMatrix(createOrReuseMatrix(mvm), surface->getReferenceFrame()); // First go through any legit rendering pass data in the Tile and // and add a DrawCommand for each. for (unsigned p = 0; p < renderModel._passes.size(); ++p) { const RenderingPass& pass = renderModel._passes[p]; if (pass._layer.valid() && pass._layer->getRenderType() == Layer::RENDERTYPE_TILE) { if (addDrawCommand(pass._sourceUID, &renderModel, &pass, _currentTileNode)) { ++_currentTileDrawCommands; } } } // Next, add a DrawCommand for each tile layer not represented in the TerrainTileModel // as a rendering pass. for (LayerVector::const_iterator i = _terrain.tileLayers().begin(); i != _terrain.tileLayers().end(); ++i) { Layer* layer = i->get(); if (addDrawCommand(layer->getUID(), &renderModel, 0L, _currentTileNode)) { ++_currentTileDrawCommands; } } // If the culler added no draw commands for this tile... do something! if (_currentTileDrawCommands == 0) { //OE_INFO << LC << "Adding blank render.\n"; addDrawCommand(-1, &renderModel, 0L, _currentTileNode); } popModelViewMatrix(); _terrain._drawState->_bs.expandBy(surface->getBound()); _terrain._drawState->_box.expandBy(_terrain._drawState->_bs); } } traverse(node); }
void TerrainRenderData::setup(const Map* map, const RenderBindings& bindings, unsigned frameNum, osgUtil::CullVisitor* cv) { _bindings = &bindings; // Create a new State object to track sampler and uniform settings _drawState = new DrawState(); _drawState->_frame = frameNum; _drawState->_bindings = &bindings; // Is this a depth camera? Because if it is, we don't need any color layers. const osg::Camera* cam = cv->getCurrentCamera(); bool isDepthCamera = ClampableNode::isDepthCamera(cam); // Make a drawable for each rendering pass (i.e. each render-able map layer). LayerVector layers; map->getLayers(layers); for (LayerVector::const_iterator i = layers.begin(); i != layers.end(); ++i) { Layer* layer = i->get(); if (layer->getEnabled()) { bool render = (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_SURFACE) || // && !isDepthCamera) || (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_PATCH); if ( render ) { // If this is an image layer, check the enabled/visible states. VisibleLayer* visLayer = dynamic_cast<VisibleLayer*>(layer); if (visLayer) { render = visLayer->getVisible(); } if (render) { if (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_SURFACE) { LayerDrawable* ld = addLayerDrawable(layer); // If the current camera is depth-only, leave this layer in the set // but mark it as no-draw. We keep it in the set so the culler doesn't // inadvertently think it's an orphaned layer. if (isDepthCamera) { ld->_draw = false; } } else // if (layer->getRenderType() == Layer::RENDERTYPE_TERRAIN_PATCH) { PatchLayer* patchLayer = static_cast<PatchLayer*>(layer); // asumption! if (patchLayer->getAcceptCallback() != 0L && patchLayer->getAcceptCallback()->acceptLayer(*cv, cv->getCurrentCamera())) { patchLayers().push_back(dynamic_cast<PatchLayer*>(layer)); addLayerDrawable(layer); } } } } } } // Include a "blank" layer for missing data. LayerDrawable* blank = addLayerDrawable(0L); }
void TerrainRenderData::setup(const MapFrame& frame, const RenderBindings& bindings, unsigned frameNum, osgUtil::CullVisitor* cv) { _bindings = &bindings; // Create a new State object to track sampler and uniform settings _drawState = new DrawState(); _drawState->_frame = frameNum; _drawState->_bindings = &bindings; // Make a drawable for each rendering pass (i.e. each render-able map layer). for(LayerVector::const_iterator i = frame.layers().begin(); i != frame.layers().end(); ++i) { Layer* layer = i->get(); if (layer->getEnabled()) { if (layer->getRenderType() == Layer::RENDERTYPE_TILE || layer->getRenderType() == Layer::RENDERTYPE_PATCH) { bool render = true; // If this is an image layer, check the enabled/visible states. VisibleLayer* visLayer = dynamic_cast<VisibleLayer*>(layer); if (visLayer) { render = visLayer->getVisible(); } if (render) { ImageLayer* imgLayer = dynamic_cast<ImageLayer*>(layer); // Make a list of "global" layers. There are layers whose data is not // represented in the TerrainTileModel, like a splatting layer or a patch // layer. The data for these is dynamic and not based on data fetched. if (imgLayer == 0L && layer->getRenderType() == Layer::RENDERTYPE_TILE) { tileLayers().push_back(layer); addLayerDrawable(layer); } else if (layer->getRenderType() == Layer::RENDERTYPE_PATCH) { PatchLayer* patchLayer = static_cast<PatchLayer*>(layer); // asumption! if (patchLayer->getAcceptCallback() != 0L && patchLayer->getAcceptCallback()->acceptLayer(*cv, cv->getCurrentCamera())) { patchLayers().push_back(dynamic_cast<PatchLayer*>(layer)); addLayerDrawable(layer); } } else { addLayerDrawable(layer); } } } } } // Include a "blank" layer for missing data. LayerDrawable* blank = addLayerDrawable(0L); blank->getOrCreateStateSet()->setDefine("OE_TERRAIN_RENDER_IMAGERY", osg::StateAttribute::OFF); }
void TerrainCuller::apply(osg::Node& node) { // push the node's state. osg::StateSet* node_state = node.getStateSet(); TileNode* tileNode = dynamic_cast<TileNode*>(&node); if (tileNode) { _currentTileNode = tileNode; // reset the pointer to the first DrawTileCommand. We keep track of this so // we can set it's "order" member to zero at the end, so the rendering engine // knows to blend it with the terrain geometry color. _firstTileDrawCommandForTile = 0L; //_currentTileDrawCommands = 0u; if (!_terrain.patchLayers().empty()) { // todo: check for patch/virtual const RenderBindings& bindings = _context->getRenderBindings(); TileRenderModel& renderModel = _currentTileNode->renderModel(); bool pushedMatrix = false; for (PatchLayerVector::const_iterator i = _terrain.patchLayers().begin(); i != _terrain.patchLayers().end(); ++i) { PatchLayer* layer = i->get(); if (layer->getAcceptCallback() == 0L || layer->getAcceptCallback()->acceptKey(_currentTileNode->getKey())) { // Push this tile's matrix if we haven't already done so: if (!pushedMatrix) { SurfaceNode* surface = tileNode->getSurfaceNode(); // push the surface matrix: osg::Matrix mvm = *getModelViewMatrix(); surface->computeLocalToWorldMatrix(mvm, this); pushModelViewMatrix(createOrReuseMatrix(mvm), surface->getReferenceFrame()); pushedMatrix = true; } // Add the draw command: DrawTileCommand* cmd = addDrawCommand(layer->getUID(), &renderModel, 0L, tileNode); if (cmd) { cmd->_drawPatch = true; cmd->_drawCallback = layer->getDrawCallback(); } } } if (pushedMatrix) { popModelViewMatrix(); } } } else { SurfaceNode* surface = dynamic_cast<SurfaceNode*>(&node); if (surface) { TileRenderModel& renderModel = _currentTileNode->renderModel(); // push the surface matrix: osg::Matrix mvm = *getModelViewMatrix(); surface->computeLocalToWorldMatrix(mvm, this); pushModelViewMatrix(createOrReuseMatrix(mvm), surface->getReferenceFrame()); int order = 0; // First go through any legit rendering pass data in the Tile and // and add a DrawCommand for each. for (unsigned p = 0; p < renderModel._passes.size(); ++p) { const RenderingPass& pass = renderModel._passes[p]; DrawTileCommand* cmd = addDrawCommand(pass.sourceUID(), &renderModel, &pass, _currentTileNode); if (cmd) { if (_firstTileDrawCommandForTile == 0L) { _firstTileDrawCommandForTile = cmd; } else if (cmd->_order < _firstTileDrawCommandForTile->_order) { //_firstTileDrawCommandForTile->_order = 1; _firstTileDrawCommandForTile = cmd; } } } // If the culler added no draw commands for this tile... we still need // to draw something or else there will be a hole! So draw a blank tile. // UID = -1 is the special UID code for a blank. if (_firstTileDrawCommandForTile == 0L) { //OE_INFO << LC << "Adding blank render for tile " << _currentTileNode->getKey().str() << std::endl; DrawTileCommand* cmd = addDrawCommand(-1, &renderModel, 0L, _currentTileNode); if (cmd) cmd->_order = 0; } // Set the layer order of the first draw command for this tile to zero, // to support proper terrain blending. if (_firstTileDrawCommandForTile) { _firstTileDrawCommandForTile->_order = 0; } // pop the matrix from the cull stack popModelViewMatrix(); // update our bounds _terrain._drawState->_bs.expandBy(surface->getBound()); _terrain._drawState->_box.expandBy(_terrain._drawState->_bs); } } // Handle any CullCallbacks and traverse. osg::Callback* cullCallback = node.getCullCallback(); if (cullCallback) cullCallback->run(&node, this); else traverse(node); }