+ osg::Group *parent = node.getParent(0);
+ if( !_node_name.empty() && parent->getName() != _node_name )
+ return;
+
+ if( !_parent_name.empty() )
+ {
+ // Traverse nodes upwards starting at the parent node (skip current
+ // node)
+ const osg::NodePath& np = getNodePath();
+ bool found = false;
+ for( int i = static_cast<int>(np.size()) - 2; i >= 0; --i )
+ {
+ const osg::Node* path_segment = np[i];
+ const osg::Node* path_parent = path_segment->getParent(0);
+
+ // A node without a name is always the parent of the root node of
+ // the model just containing the file name
+ if( path_parent && path_parent->getName().empty() )
+ return;
+
+ if( path_segment->getName() == _parent_name )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if( !found )
+ return;
+ }
+
+ for( size_t unit = 0; unit < ss->getNumTextureAttributeLists(); ++unit )
+ {
+ osg::Texture2D* tex = dynamic_cast<osg::Texture2D*>
+ (
+ ss->getTextureAttribute(unit, osg::StateAttribute::TEXTURE)
+ );
+
+ if( !tex || !tex->getImage() || tex == _new_texture )
+ continue;
+
+ if( !_tex_name.empty() )
+ {
+ std::string tex_name = tex->getImage()->getFileName();
+ std::string tex_name_simple = osgDB::getSimpleFileName(tex_name);
+ if( !osgDB::equalCaseInsensitive(_tex_name, tex_name_simple) )
+ continue;
+ }
+
+ // insert a new group between the geode an it's parent which overrides
+ // the texture
+ osg::ref_ptr<osg::Group> group = new osg::Group;
+ group->setName("canvas texture group");
+ group->addChild(eg);
+ parent->removeChild(eg);
+ parent->addChild(group);
+
+ if( _cull_callback )
+ group->setCullCallback(_cull_callback);
+
+ _placements.push_back(group);
+
+ osg::StateSet* stateSet = group->getOrCreateStateSet();
+ stateSet->setTextureAttribute( unit, _new_texture,
+ osg::StateAttribute::OVERRIDE );
+ stateSet->setTextureMode( unit, GL_TEXTURE_2D,
+ osg::StateAttribute::ON );
+
+ SG_LOG
+ (
+ SG_GL,
+ SG_INFO,
+ "Replaced texture '" << _tex_name << "'"
+ << " for object '" << parent->getName() << "'"
+ << (!_parent_name.empty() ? " with parent '" + _parent_name + "'"
+ : "")
+ );
+ return;
+ }
+ }
+
+
+
+ protected:
+
+ std::string _tex_name, ///<! Name of texture to be replaced
+ _node_name, ///<! Only replace if node name matches
+ _parent_name; ///<! Only replace if any parent node matches
+ /// given name (all the tree upwards)
+ osg::Texture2D *_new_texture;
+ osg::NodeCallback *_cull_callback;
+
+ Placements _placements;
+};
+
+//------------------------------------------------------------------------------
+ Placements FGODGauge::set_texture(const char* name, osg::Texture2D* new_texture)
+{
+ osg::Group* root = globals->get_scenery()->get_aircraft_branch();
+ ReplaceStaticTextureVisitor visitor(name, new_texture);
+ root->accept(visitor);
+ return visitor.getPlacements();