(C++) How to affect all scene nodes, including child nodes

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Panther
Posts: 34
Joined: Tue Jun 06, 2006 1:05 am

(C++) How to affect all scene nodes, including child nodes

Post by Panther »

This is a really small, simple snippet, but very useful. What it does is affect every object in your scene the same way. One classic example of needing to do this is with fog. First, you enable fog; then you have to turn it on for every object. Here's how to do that:

Code: Select all

	//Add some fog
	driver->setFog(video::SColor(0,200,200,200), true, 50, 3000, 0, true);

	//Go through all the scene nodes and make fog visible
	//(affects three levels of recursion, i.e. nodes, children, grandchildren)
	core::list<ISceneNode*>::Iterator it = smgr->getRootSceneNode()->getChildren().begin();
	for (; it != smgr->getRootSceneNode()->getChildren().end(); ++it)
	{
		(*it)->setMaterialFlag(video::EMF_FOG_ENABLE, true); //***
		core::list<ISceneNode*>::Iterator it2 = (*it)->getChildren().begin();
		for (; it2 != (*it)->getChildren().end(); ++it2)
		{
			(*it2)->setMaterialFlag(video::EMF_FOG_ENABLE, true);  //***
			core::list<ISceneNode*>::Iterator it3 = (*it2)->getChildren().begin();
			for (; it3 != (*it2)->getChildren().end(); ++it3)
			{
				(*it3)->setMaterialFlag(video::EMF_FOG_ENABLE, true); //***
			}
		}
	}
The above code can be easily modified to affect every object in a different way (other than fog). Just change the lines marked with ***.
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Why avoid real recursion?

Code: Select all

void RecursiveFunction(scene::ISceneNode* node_)
{
    if (!node_ )
        return;

    // Do something with the node here.

    // recursive call to children
    const core::list<scene::ISceneNode*> & children = node_->getChildren();
    core::list<scene::ISceneNode*>::Iterator it = children.begin();
    for (; it != children.end(); ++it)
    {
        RecursiveFunction(*it);
    }
}
To affect all nodes you can call the function now like:

Code: Select all

RecursiveFunction(smgr->getRootSceneNode());
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Use real recursion, and make it generic...

Code: Select all

template< class Fun >
void applyToScene(Fun function, ISceneNode* node)
{
   function(node);

   core::list<ISceneNode*>::Iterator it = node->getChildren().begin(); 
   for (; it != node->getChildren().end(); ++it)
      applyToScene(function, *it);
}
To enable fog on the entire scene...

Code: Select all

struct setMaterialFlag
{
   setMaterialFlag(video::E_MATERIAL_FLAG flag, bool value)
      : Flag(flag)
      , Value(value)
   {
   }

   void operator()(ISceneNode* node)
   {
      node->setMaterialFlag(Flag, Value);
   }

   video::E_MATERIAL_FLAG Flag;
   bool Value;
};

// this does everything
applyToScene(setMaterialFlag(video::EMF_FOG_ENABLE, true), smgr->getRootSceneNode());
To set debug data visible...

Code: Select all

struct setDebugDataVisible
{
   setDebugDataVisible(bool visible)
      : Visible(visible)
   {
   }

   void operator()(ISceneNode* node)
   {
      node->setDebugDataVisible(Visible);
   }

   bool Visible;
};

// this does everything
applyToScene(setDebugDataVisible(true), smgr->getRootSceneNode());
Post Reply