void MapNode::onModelLayerOverlayChanged( ModelLayer* layer ) { osg::ref_ptr<osg::Node> node = _modelLayerNodes[ layer ]; if ( node.get() ) { DrapeableNode* draper = dynamic_cast<DrapeableNode*>(node.get()); if ( !draper && layer->getOverlay() ) { draper = new DrapeableNode(this); draper->addChild( node.get() ); _models->replaceChild( node.get(), draper ); } else { draper->setDraped( layer->getOverlay() ); } } //OE_NOTICE << "Overlay changed to " << layer->getOverlay() << std::endl; //osg::ref_ptr< osg::Group > origParent = layer->getOverlay() ? _models.get() : _overlayModels.get(); //osg::ref_ptr< osg::Group > newParent = layer->getOverlay() ? _overlayModels.get() : _models.get(); //osg::ref_ptr< osg::Node > node = layer->getOrCreateNode(); //if (node.valid()) //{ // //Remove it from the original parent and add it to the new parent // origParent->removeChild( node.get() ); // newParent->addChild( node.get() ); //} updateOverlayGraph(); }
void ImageOverlay::postCTOR() { _geode = new osg::Geode; _transform = new osg::MatrixTransform; _transform->addChild( _geode ); // place the geometry under a drapeable node so it will project onto the terrain DrapeableNode* d = new DrapeableNode( getMapNode() ); addChild( d ); d->addChild( _transform ); init(); if ( Registry::capabilities().supportsGLSL() ) { ShaderGenerator gen; d->accept( gen ); //// need a shader that supports one texture //VirtualProgram* vp = new VirtualProgram(); //vp->setName( "imageoverlay"); //vp->installDefaultColoringShaders(1); //d->getOrCreateStateSet()->setAttributeAndModes( vp, 1 ); } ADJUST_UPDATE_TRAV_COUNT( this, 1 ); }
osg::Node* AnnotationUtils::installOverlayParent(osg::Node* node, const Style& style) { AnnotationUtils::AltitudePolicy ap; AnnotationUtils::getAltitudePolicy( style, ap ); // Draped (projected) geometry if ( ap.draping ) { DrapeableNode* drapable = new DrapeableNode(); drapable->addChild( node ); node = drapable; } // gw - not sure whether is makes sense to support this for LocalizedNode // GPU-clamped geometry else if ( ap.gpuClamping ) { ClampableNode* clampable = new ClampableNode(); clampable->addChild( node ); node = clampable; } return node; }
void MapNode::onModelLayerAdded( ModelLayer* layer, unsigned int index ) { if ( !layer->getEnabled() ) return; osg::Node* node = layer->getOrCreateNode(); layer->addCallback(_modelLayerCallback.get() ); if ( node ) { if ( _modelLayerNodes.find( layer ) != _modelLayerNodes.end() ) { OE_WARN << "Illegal: tried to add the name model layer more than once: " << layer->getName() << std::endl; } else { if ( dynamic_cast<TerrainDecorator*>(node) || dynamic_cast<osgSim::OverlayNode*>(node) ) { OE_INFO << LC << "Installing overlay node" << std::endl; addTerrainDecorator( node->asGroup() ); } else { if ( layer->getOverlay() ) { #if 0 _overlayModels->addChild( node ); updateOverlayGraph(); #else DrapeableNode* draper = new DrapeableNode( this ); draper->addChild( node ); _models->insertChild( index, draper ); #endif } else { _models->insertChild( index, node ); } } ModelSource* ms = layer->getModelSource(); if ( ms && ms->getOptions().renderOrder().isSet() ) { node->getOrCreateStateSet()->setRenderBinDetails( ms->getOptions().renderOrder().value(), "RenderBin" ); } _modelLayerNodes[ layer ] = node; } dirtyBound(); } }
HTMNode::HTMNode(HTMSettings& settings, const osg::Vec3d& v0, const osg::Vec3d& v1, const osg::Vec3d& v2, const std::string& id) : _settings(settings) { setName(id); _isLeaf = true; _tri.set( v0, v1, v2 ); if (settings._debugGeom) { const double R = SpatialReference::get("wgs84")->getEllipsoid()->getRadiusEquator(); osg::Geometry* geom = new osg::Geometry(); geom->setUseVertexBufferObjects(true); osg::Vec3Array* verts = new osg::Vec3Array(); for (double t=0.0; t<1.0; t+=0.05) verts->push_back((v0 + (v1-v0)*t) * R); for (double t=0.0; t<1.0; t+=0.05) verts->push_back((v1 + (v2-v1)*t) * R); for (double t=0.0; t<1.0; t+=0.05) verts->push_back((v2 + (v0-v2)*t) * R); geom->setVertexArray(verts); osg::Vec4Array* color = new osg::Vec4Array(); color->push_back(osg::Vec4(1,1,0,1)); color->setBinding(color->BIND_OVERALL); geom->setColorArray(color); geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_LOOP, 0, verts->size())); geom->getOrCreateStateSet()->setAttribute(new osg::Program(), osg::StateAttribute::PROTECTED); osgText::Text* text = new osgText::Text(); text->setText(Stringify() << getName() << "\nS=" << geom->getBound().radius()*2.0); text->setPosition((v0+v1+v2)/3 * R); text->setCharacterSizeMode(text->SCREEN_COORDS); text->setCharacterSize(48); text->setAutoRotateToScreen(true); text->setAlignment(text->CENTER_CENTER); text->getOrCreateStateSet()->setAttribute(new osg::Program(), osg::StateAttribute::PROTECTED); DrapeableNode* drape = new DrapeableNode(); drape->addChild(geom); drape->addChild(text); _debug = drape; } }
osg::Node* AnnotationUtils::installOverlayParent(osg::Node* node, const Style& style) { AnnotationUtils::AltitudePolicy ap; AnnotationUtils::getAltitudePolicy( style, ap ); // Draped (projected) geometry if ( ap.draping ) { DrapeableNode* drapable = new DrapeableNode(); drapable->addChild( node ); node = drapable; } // gw - not sure whether is makes sense to support this for LocalizedNode // GPU-clamped geometry else if ( ap.gpuClamping ) { ClampableNode* clampable = new ClampableNode( 0L ); clampable->addChild( node ); node = clampable; const RenderSymbol* render = style.get<RenderSymbol>(); if ( render && render->depthOffset().isSet() ) { clampable->setDepthOffsetOptions( *render->depthOffset() ); } } #if 0 // TODO -- constuct a callback instead. // scenegraph-clamped geometry else if ( ap.sceneClamping ) { // save for later when we need to reclamp the mesh on the CPU _altitude = style.get<AltitudeSymbol>(); // activate the terrain callback: setCPUAutoClamping( true ); } #endif return node; }
void ImageOverlay::postCTOR() { _geode = new osg::Geode; _transform = new osg::MatrixTransform; _transform->addChild( _geode ); // place the geometry under a drapeable node so it will project onto the terrain DrapeableNode* d = new DrapeableNode( getMapNode() ); addChild( d ); d->addChild( _transform ); init(); ADJUST_UPDATE_TRAV_COUNT( this, 1 ); }
void ImageOverlay::postCTOR() { _updateScheduled = false; _root = new osg::Group; // place the geometry under a drapeable node so it will project onto the terrain DrapeableNode* d = new DrapeableNode(); d->setDrapingEnabled(*_draped); addChild( d ); d->addChild( _root ); init(); ADJUST_EVENT_TRAV_COUNT(this, 1); }
void EllipseNode::rebuild() { std::string currentDecoration = getDecoration(); clearDecoration(); //Remove all children from this node removeChildren( 0, getNumChildren() ); //Remove all children from the attach point getAttachPoint()->removeChildren( 0, getAttachPoint()->getNumChildren() ); // construct a local-origin ellipse. GeometryFactory factory; Geometry* geom = factory.createEllipse(osg::Vec3d(0,0,0), _radiusMajor, _radiusMinor, _rotationAngle, _numSegments); if ( geom ) { GeometryCompiler compiler; osg::ref_ptr<Feature> feature = new Feature(geom, 0L); //todo: consider the SRS osg::Node* node = compiler.compile( feature.get(), _style, FilterContext(0L) ); if ( node ) { getAttachPoint()->addChild( node ); if ( _draped ) { DrapeableNode* drapeable = new DrapeableNode( _mapNode.get() ); drapeable->addChild( getAttachPoint() ); this->addChild( drapeable ); } else { this->addChild( getAttachPoint() ); } } applyStyle( _style, _draped ); } setDecoration( currentDecoration ); }
void MapNode::onModelLayerAdded( ModelLayer* layer, unsigned int index ) { if ( !layer->getEnabled() ) return; // install a noe operation that will associate this mapnode with // any MapNodeObservers loaded by the model layer: ModelSource* modelSource = layer->getModelSource(); if ( modelSource ) { // install a post-processing callback on the ModelLayer's source // so we can update the MapNode on new data that comes in: modelSource->addPostProcessor( new MapNodeObserverInstaller(this) ); } // create the scene graph: osg::Node* node = layer->getOrCreateNode(); layer->addCallback(_modelLayerCallback.get() ); if ( node ) { if ( _modelLayerNodes.find( layer ) != _modelLayerNodes.end() ) { OE_WARN << "Illegal: tried to add the name model layer more than once: " << layer->getName() << std::endl; } else { if ( dynamic_cast<TerrainDecorator*>(node) ) { OE_INFO << LC << "Installing overlay node" << std::endl; addTerrainDecorator( node->asGroup() ); } else { if ( layer->getOverlay() ) { DrapeableNode* draper = new DrapeableNode( this ); draper->addChild( node ); node = draper; } _models->insertChild( index, node ); } ModelSource* ms = layer->getModelSource(); if ( ms ) { // enfore a rendering bin if necessary: if ( ms->getOptions().renderOrder().isSet() ) { node->getOrCreateStateSet()->setRenderBinDetails( ms->getOptions().renderOrder().value(), "RenderBin" ); } } _modelLayerNodes[ layer ] = node; } dirtyBound(); } }
void FeatureNode::build() { if ( !_clampCallback.valid() ) _clampCallback = new ClampCallback(this); _attachPoint = 0L; // if there is existing geometry, kill it this->removeChildren( 0, this->getNumChildren() ); if ( !getMapNode() ) return; if ( _features.empty() ) return; const Style &style = getStyle(); // compilation options. GeometryCompilerOptions options = _options; // figure out what kind of altitude manipulation we need to perform. AnnotationUtils::AltitudePolicy ap; AnnotationUtils::getAltitudePolicy( style, ap ); // If we're doing auto-clamping on the CPU, shut off compiler map clamping // clamping since it would be redundant. if ( ap.sceneClamping ) { options.ignoreAltitudeSymbol() = true; } _clamperData.clear(); osg::Node* node = _compiled.get(); if (_needsRebuild || !_compiled.valid() ) { // Clone the Features before rendering as the GeometryCompiler and it's filters can change the coordinates // of the geometry when performing localization or converting to geocentric. _extent = GeoExtent::INVALID; FeatureList clone; for(FeatureList::iterator itr = _features.begin(); itr != _features.end(); ++itr) { Feature* feature = new Feature( *itr->get(), osg::CopyOp::DEEP_COPY_ALL); GeoExtent featureExtent(feature->getSRS(), feature->getGeometry()->getBounds()); if (_extent.isInvalid()) { _extent = featureExtent; } else { _extent.expandToInclude( featureExtent ); } clone.push_back( feature ); } // prep the compiler: GeometryCompiler compiler( options ); Session* session = new Session( getMapNode()->getMap(), _styleSheet.get() ); FilterContext context( session, new FeatureProfile( _extent ), _extent, _index); _compiled = compiler.compile( clone, style, context ); node = _compiled.get(); _needsRebuild = false; // Compute the world bounds osg::BoundingSphered bounds; for( FeatureList::iterator itr = _features.begin(); itr != _features.end(); ++itr) { osg::BoundingSphered bs; itr->get()->getWorldBound(getMapNode()->getMapSRS(), bs); bounds.expandBy(bs); } // The polytope will ensure we only clamp to intersecting tiles: Feature::getWorldBoundingPolytope(bounds, getMapNode()->getMapSRS(), _featurePolytope); } if ( node ) { if ( AnnotationUtils::styleRequiresAlphaBlending( style ) && getStyle().get<ExtrusionSymbol>() ) { node = AnnotationUtils::installTwoPassAlpha( node ); } _attachPoint = new osg::Group(); _attachPoint->addChild( node ); // Draped (projected) geometry if ( ap.draping ) { DrapeableNode* d = new DrapeableNode(); d->addChild( _attachPoint ); this->addChild( d ); } // GPU-clamped geometry else if ( ap.gpuClamping ) { ClampableNode* clampable = new ClampableNode(); clampable->addChild( _attachPoint ); this->addChild( clampable ); } else { this->addChild( _attachPoint ); // set default lighting based on whether we are extruding: setDefaultLighting( style.has<ExtrusionSymbol>() ); } applyRenderSymbology(style); if ( getMapNode()->getTerrain() ) { if ( ap.sceneClamping ) { // Need dynamic data variance since scene clamping will change the verts SetDataVarianceVisitor sdv(osg::Object::DYNAMIC); this->accept(sdv); getMapNode()->getTerrain()->addTerrainCallback(_clampCallback.get()); clamp(getMapNode()->getTerrain()->getGraph(), getMapNode()->getTerrain()); } else { getMapNode()->getTerrain()->removeTerrainCallback( _clampCallback.get() ); } } } }
void FeatureNode::build() { // if there's a decoration, clear it out first. this->clearDecoration(); _attachPoint = 0L; // if there is existing geometry, kill it this->removeChildren( 0, this->getNumChildren() ); if ( !getMapNode() ) return; if ( _features.empty() ) return; const Style &style = getStyle(); // compilation options. GeometryCompilerOptions options = _options; // figure out what kind of altitude manipulation we need to perform. AnnotationUtils::AltitudePolicy ap; AnnotationUtils::getAltitudePolicy( style, ap ); // If we're doing auto-clamping on the CPU, shut off compiler map clamping // clamping since it would be redundant. // TODO: I think this is OBE now that we have "scene" clamping technique.. if ( ap.sceneClamping ) { options.ignoreAltitudeSymbol() = true; } osg::Node* node = _compiled.get(); if (_needsRebuild || !_compiled.valid() ) { // Clone the Features before rendering as the GeometryCompiler and it's filters can change the coordinates // of the geometry when performing localization or converting to geocentric. _extent = GeoExtent::INVALID; FeatureList clone; for(FeatureList::iterator itr = _features.begin(); itr != _features.end(); ++itr) { Feature* feature = new Feature( *itr->get(), osg::CopyOp::DEEP_COPY_ALL); GeoExtent featureExtent(feature->getSRS(), feature->getGeometry()->getBounds()); if (_extent.isInvalid()) { _extent = featureExtent; } else { _extent.expandToInclude( featureExtent ); } clone.push_back( feature ); } // prep the compiler: GeometryCompiler compiler( options ); Session* session = new Session( getMapNode()->getMap(), _styleSheet.get() ); FilterContext context( session, new FeatureProfile( _extent ), _extent ); _compiled = compiler.compile( clone, style, context ); node = _compiled.get(); _needsRebuild = false; // Compute the world bounds osg::BoundingSphered bounds; for( FeatureList::iterator itr = _features.begin(); itr != _features.end(); ++itr) { osg::BoundingSphered bs; itr->get()->getWorldBound(getMapNode()->getMapSRS(), bs); bounds.expandBy(bs); } // The polytope will ensure we only clamp to intersecting tiles: Feature::getWorldBoundingPolytope(bounds, getMapNode()->getMapSRS(), _featurePolytope); } if ( node ) { if ( AnnotationUtils::styleRequiresAlphaBlending( style ) && getStyle().get<ExtrusionSymbol>() ) { node = AnnotationUtils::installTwoPassAlpha( node ); } //OE_NOTICE << GeometryUtils::geometryToGeoJSON( _feature->getGeometry() ) << std::endl; _attachPoint = new osg::Group(); _attachPoint->addChild( node ); // Draped (projected) geometry if ( ap.draping ) { DrapeableNode* d = new DrapeableNode(); // getMapNode() ); d->addChild( _attachPoint ); this->addChild( d ); } // GPU-clamped geometry else if ( ap.gpuClamping ) { ClampableNode* clampable = new ClampableNode( getMapNode() ); clampable->addChild( _attachPoint ); this->addChild( clampable ); const RenderSymbol* render = style.get<RenderSymbol>(); if ( render && render->depthOffset().isSet() ) { clampable->setDepthOffsetOptions( *render->depthOffset() ); } } else { this->addChild( _attachPoint ); // CPU-clamped geometry? if ( ap.sceneClamping ) { // save for later when we need to reclamp the mesh on the CPU _altitude = style.get<AltitudeSymbol>(); // activate the terrain callback: setCPUAutoClamping( true ); // set default lighting based on whether we are extruding: setLightingIfNotSet( style.has<ExtrusionSymbol>() ); // do an initial clamp to get started. clampMesh( getMapNode()->getTerrain()->getGraph() ); } applyRenderSymbology( style ); } } updateClusterCulling(); }
void FeatureNode::init() { // if there's a decoration, clear it out first. this->clearDecoration(); _attachPoint = 0L; // if there is existing geometry, kill it this->removeChildren( 0, this->getNumChildren() ); if ( !getMapNode() ) return; if ( !_feature.valid() ) return; // compilation options. GeometryCompilerOptions options = _options; // figure out what kind of altitude manipulation we need to perform. AnnotationUtils::AltitudePolicy ap; AnnotationUtils::getAltitudePolicy( *_feature->style(), ap ); // If we're doing auto-clamping on the CPU, shut off compiler map clamping // clamping since it would be redundant. // TODO: I think this is OBE now that we have "scene" clamping technique.. if ( ap.sceneClamping ) { options.ignoreAltitudeSymbol() = true; } // prep the compiler: GeometryCompiler compiler( options ); Session* session = new Session( getMapNode()->getMap() ); GeoExtent extent(_feature->getSRS(), _feature->getGeometry()->getBounds()); osg::ref_ptr<FeatureProfile> profile = new FeatureProfile( extent ); FilterContext context( session, profile.get(), extent ); // Clone the Feature before rendering as the GeometryCompiler and it's filters can change the coordinates // of the geometry when performing localization or converting to geocentric. osg::ref_ptr< Feature > clone = new Feature(*_feature.get(), osg::CopyOp::DEEP_COPY_ALL); osg::Node* node = compiler.compile( clone.get(), *clone->style(), context ); if ( node ) { if ( _feature->style().isSet() && AnnotationUtils::styleRequiresAlphaBlending( *_feature->style() ) && _feature->style()->get<ExtrusionSymbol>() ) { node = AnnotationUtils::installTwoPassAlpha( node ); } _attachPoint = new osg::Group(); _attachPoint->addChild( node ); // Draped (projected) geometry if ( ap.draping ) { DrapeableNode* d = new DrapeableNode( getMapNode() ); d->addChild( _attachPoint ); this->addChild( d ); } // GPU-clamped geometry else if ( ap.gpuClamping ) { ClampableNode* clampable = new ClampableNode( getMapNode() ); clampable->addChild( _attachPoint ); this->addChild( clampable ); const RenderSymbol* render = _feature->style()->get<RenderSymbol>(); if ( render && render->depthOffset().isSet() ) { clampable->setDepthOffsetOptions( *render->depthOffset() ); } } else { this->addChild( _attachPoint ); // CPU-clamped geometry? if ( ap.sceneClamping ) { // save for later when we need to reclamp the mesh on the CPU _altitude = _feature->style()->get<AltitudeSymbol>(); // The polytope will ensure we only clamp to intersecting tiles: _feature->getWorldBoundingPolytope( getMapNode()->getMapSRS(), _featurePolytope ); // activate the terrain callback: setCPUAutoClamping( true ); // set default lighting based on whether we are extruding: setLightingIfNotSet( _feature->style()->has<ExtrusionSymbol>() ); // do an initial clamp to get started. clampMesh( getMapNode()->getTerrain()->getGraph() ); } } } }
void FeatureNode::init() { // if there's a decoration, clear it out first. this->clearDecoration(); _attachPoint = 0L; // if there is existing geometry, kill it this->removeChildren( 0, this->getNumChildren() ); if ( !getMapNode() ) return; // build the new feature geometry { if ( _feature.valid() ) { _feature->getWorldBoundingPolytope( getMapNode()->getMapSRS(), _featurePolytope ); } GeometryCompilerOptions options = _options; // have to disable compiler clamping if we're doing auto-clamping; especially // in terrain-relative mode because the auto-clamper will think the clamped // coords are the relative coords. bool autoClamping = !_draped && supportsAutoClamping(*_feature->style()); if ( autoClamping ) { options.ignoreAltitudeSymbol() = true; } // prep the compiler: GeometryCompiler compiler( options ); Session* session = new Session( getMapNode()->getMap() ); GeoExtent extent(_feature->getSRS(), _feature->getGeometry()->getBounds()); osg::ref_ptr<FeatureProfile> profile = new FeatureProfile( extent ); FilterContext context( session, profile.get(), extent ); // Clone the Feature before rendering as the GeometryCompiler and it's filters can change the coordinates // of the geometry when performing localization or converting to geocentric. osg::ref_ptr< Feature > clone = new Feature(*_feature.get(), osg::CopyOp::DEEP_COPY_ALL); osg::Node* node = compiler.compile( clone.get(), *clone->style(), context ); if ( node ) { if ( _feature->style().isSet() && AnnotationUtils::styleRequiresAlphaBlending( *_feature->style() ) && _feature->style()->get<ExtrusionSymbol>() ) { node = AnnotationUtils::installTwoPassAlpha( node ); } _attachPoint = new osg::Group(); _attachPoint->addChild( node ); if ( _draped ) { DrapeableNode* d = new DrapeableNode( getMapNode() ); d->addChild( _attachPoint ); this->addChild( d ); } else { this->addChild( _attachPoint ); } } // workaround until we can auto-clamp extruded/sub'd geometries. if ( autoClamping ) { applyStyle( *_feature->style() ); clampMesh( getMapNode()->getTerrain()->getGraph() ); } } }