As of osgEarth version 2.9 you can not change the Image the TrackNode displays without subclassing and implementing additional logic.
The following is the approach I have taken:
The assumption is that the first drawable on the _geode is the image geometry. There is some sanity checking performed in case there is no image geometry. The sanity checking is not 100%.
No attempt is made to modify the image geometry because of the complexity of the setup. You could keep a reference to the geometry we are replacing so that we can swap it back in.
The shaders have to be regenerated.
Ideally the TrackNode should be re-written to allow changing an Image without so much setup.
Because of the complexity of the setup this is not an operation that should be performed frequently. I am using this to indicate that a TrackNode has been selected.
My tracks are normally red. When a track is selected I change the Icon/Image to bright green.
The following is the approach I have taken:
void MyTrackNode::changeImage(osg::ref_ptr<osg::Image> image)
{
osgEarth::IconSymbol* icon = _style.getOrCreateSymbol<osgEarth::IconSymbol>();
icon->setImage(image);
osg::Image* iconImage = icon ? icon->getImage() : 0L;
if ( icon && iconImage )
{
osg::Drawable *oldDrawable = reinterpret_cast<osg::Geometry*>(_geode->getDrawable( 0 ));
if (nullptr != oldDrawable)
{
for (auto drawable : _namedDrawables)
{
if (drawable.second == oldDrawable)
{
oldDrawable = nullptr;
}
}
}
if (oldDrawable == nullptr)
{
oldDrawable = getDrawable("track_icon");
}
// apply the image icon.
osg::Geometry* imageGeom = osgEarth::Annotation::AnnotationUtils::createImageGeometry(
iconImage, // image
osg::Vec2s(0,0), // offset
0, // tex image unit
icon->heading()->eval(),
icon->scale()->eval() );
if ( imageGeom )
{
if (nullptr == oldDrawable)
{
addDrawable( "track_icon", imageGeom);
}
else
{
_geode->replaceDrawable( oldDrawable, imageGeom );
}
ScreenSpaceLayoutData* layout = new ScreenSpaceLayoutData();
layout->setPriority(getPriority());
imageGeom->setUserData(layout);
// generate shaders:
Registry::shaderGenerator().run(
this,
"osgEarth.TrackNode",
Registry::stateSetCache() );
}
}
}
The assumption is that the first drawable on the _geode is the image geometry. There is some sanity checking performed in case there is no image geometry. The sanity checking is not 100%.
No attempt is made to modify the image geometry because of the complexity of the setup. You could keep a reference to the geometry we are replacing so that we can swap it back in.
The shaders have to be regenerated.
Ideally the TrackNode should be re-written to allow changing an Image without so much setup.
Because of the complexity of the setup this is not an operation that should be performed frequently. I am using this to indicate that a TrackNode has been selected.
My tracks are normally red. When a track is selected I change the Icon/Image to bright green.
Map data is (c) Open Street Map contributors.
Comments
Post a Comment