Jump to content

photo

Recommended Posts

Hi,

I would like to be able to set a node (and its childern ) visible/hide it with a click of a gui button (VR Tempalte, GuiSample).
I have two buttons; one for hiding/one for setting it visible again: 

void GuiSample::icon_furniture_hide()
{
    NodePtr node = Editor::get()->getNodeByName("furniture");


}

void GuiSample::icon_furniture_show()
{
    NodePtr node = Editor::get()->getNodeByName("furniture");


}

Can I use the getNodeByName method here? Colud you please help me on finishing these methods?

Thanks!

Link to comment

Hi Piotr,

Without components assigned to your nodes you could simply use Node::setEnabled() method to hide/show your node with all its hierarchy, but we have to think about components.

So, you could use something like this, to hide/show all objects in the hierarchy of a node with a given name without disabling components:

/// function setting visibility for all objects in the hierarchy of a given node
int setVisibility(NodePtr node, int visible)
{
	// recursively calling this method for all node's children
	int n = node->getNumChildren();
	if (n){
		for (int i = 0; i < n; i++)
			setVisibility(node->getChild(i), visible);
	}

	// checking if it is an object
	if (node->isObject())
	{
		// hide object's surfaces without disabling components
		ObjectPtr obj = Object::cast(node);
		for (int i = 0; i < obj->getNumSurfaces(); i++)
			obj->setEnabled(visible, i);
	}

	return 1;
}
// method for hiding all objects in the hierarchy of a node with a given name
void GuiSample::icon_furniture_hide()
{
      // trying to get a node named "furniture"
      NodePtr node = Editor::get()->getNodeByName("furniture");
  	
      // if such a node exists, hiding all objects in its hierarchy
      if(node)
          setVisibility(node, 0);
}

// method for shoving all objects in the hierarchy of a node with a given name
void GuiSample::icon_furniture_show()
{
      // trying to get a node named "furniture"
      NodePtr node = Editor::get()->getNodeByName("furniture");
  	
      // if such a node exists, showing all objects in its hierarchy
      if(node)
          setVisibility(node, 1);
}

As for the Editor::getNodeByName() method, there's no problem in using it, but the nodes, that you're trying to find this way must be owned by the Editor.

Hope this helps!

Thank you!

 

Link to comment

Hi Fox!

Thanks, this code works, but now both of my buttons hide the furniture node, and none of them shows it.
I was looking where I could have made a mistake, but I couldn't find it.


Gui Sample.cpp:
 

	//icon furnitureOn
	furnitureOn = WidgetIcon::create(gui, "manual_icon_icon.png", 64, 64);
	furnitureOn->setPosition(290, 310);
	furnitureOn->setToolTip("Show Furniture");
	gui->addChild(furnitureOn->getWidget(), Gui::ALIGN_OVERLAP);
	furnitureOn->setCallback0(Gui::CLICKED, MakeCallback(this, &GuiSample::furnitureShow));

	//icon furnitureOff
	furnitureOff = WidgetIcon::create(gui, "manual_icon_icon.png", 64, 64);
	furnitureOff->setPosition(370, 310);
	furnitureOff->setToolTip("Hide Furniture");
	gui->addChild(furnitureOff->getWidget(), Gui::ALIGN_OVERLAP);
	furnitureOff->setCallback0(Gui::CLICKED, MakeCallback(this, &GuiSample::furnitureHide));

	//...

	/// function setting visibility for all objects in the hierarchy of a given node
int setVisibility(NodePtr node, int visible)
{
	// recursively calling this method for all node's children
	int n = node->getNumChildren();
	if (n) {
		for (int i = 0; i < n; i++)
			setVisibility(node->getChild(i), visible);
	}

	// checking if it is an object
	if (node->isObject())
	{
		// hide object's surfaces without disabling components
		ObjectPtr obj = Object::cast(node);
		for (int i = 0; i < obj->getNumSurfaces(); i++)
			obj->setEnabled(0, i);
	}

	return 1;
}

void GuiSample::furnitureShow()
{
	// trying to get a node named "furniture"
	NodePtr node = Editor::get()->getNodeByName("furniture");

	// if such a node exists, showing all objects in its hierarchy
	if (node)
		setVisibility(node, 1);
}

// method for hiding all objects in the hierarchy of a node with a given name
void GuiSample::furnitureHide()
{
	// trying to get a node named "furniture"
	NodePtr node = Editor::get()->getNodeByName("furniture");

	// if such a node exists, hiding all objects in its hierarchy
	if (node)
		setVisibility(node, 0); 
}


GuiSample.h:

private:

	WidgetIconPtr furnitureOn;

	WidgetIconPtr furnitureOff;

	void furnitureShow();
	void furnitureHide();

Thanks!

Link to comment

Hi Piotr,

Oops, sorry, my bad! The setEnabled() in the setVisibility() method instead of 

obj->setEnabled(0, i);

should be called like this:

obj->setEnabled(visible, i);

I've fixed that in the code above, sorry for the inconvenience caused!

Thank you!

Link to comment
  • 4 months later...

Hi,

I now have two sets of objects, two different furniture scenarios. So when one is set visible, the visibility of the second one should be then set to 0, so that one button performs both actions. Then there is a second button, basically almost a copy of the first one, but it sets the first one not visibile and the other one visible. As far as I understand, I dont need a new callback there, but I can´t figure out how to access both of the nodes via the getNodeByName() method in furnitureShow(). Could you please have a look at it?

Thanks!

Link to comment

Hi Piotr,

May I ask you to elaborate a bit more on the desired logic?

  1. You have two sets of objects.
  2. Button "A" enable 1st set  and disable 2nd set.
  3. Button "B" sets disable 1st set and enable 2nd

Is that what you want to do? What if you'll decide to add n more sets of furniture? Maybe it's better to do cycling on/off with one button?

Thanks.

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

Hi Morbid, 

Thats actually a very good idea, to be able to cycle through the children of a node, setting visible only one of them at a time and keeping all the others not visible. Could you please help me on programming that?

Thanks.

Link to comment

Please, check the attached scene. It was built on VR template from UNIGINE SDK 2.8.

You'll see two buttons: "Previous" and "Next". They are cycling nodes in the hierarchy. All groups should be enabled in the world hierarchy, Set 1 will be shown by default in your application.

furnitures_sample.zip

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to comment

This works great! Once again I get an excellent support, thank you!
One question though - i have some movable objects (movable.prop, rigid bodies) which fall down to the ground after they and the furniture they stand on are hidden. So the next time the set gets visible, all these objects lay on the ground. Is there a way to avoid it?

Link to comment

The method does not hide the lights (all set to dynamic), they are still visible, allthough being a child of a node that is hidden
Also the objects, which can be grabbed ( movable.prop) are still active (controller rumbling) allthough set to invisible

Link to comment

Hi Piotr,

The current implementation of the setVisibility function set only visible parts of objects.
In your new case, you can try set activity of root node using setEnabled method.
Replace current setVisibility with:
int setVisibility(NodePtr node, int visible)
{
    node->setEnabled(visible);
    return 1;
}

You can check this in a new sample that contains movable objects and light sources.

furnitures_sample.zip

Link to comment
×
×
  • Create New...