Jump to content

Hierarchy Bounding Box


photo

Recommended Posts

Posted

Hello,

I'm trying to compute a world-transformed 'locale' bounding box: this would be the bounding box of a group of objects, computed in its locale coordinates and then transformed to the world. I found two functions: Node::getHierarchyBoundBox() and Node::getHierarchySpatialBoundBox(). But for the same group of objects, they give vastly different results (no Rigid Body involved):

image.png.63e2c369ab76f5f97416f2d822c65c7b.png

Here, the green box shows the expected result (given by getHierarchyBoundBox(), and the red one is incorrect, but they both use the same code:

	{
		auto hbb = node->getHierarchySpatialBoundBox();
		auto s = hbb.getSize();
		auto c = hbb.getCenter();
		Mat4 m{ node->getWorldTransform() };
		m.setColumn3(3, m * c); // set translation to center of the bounding box in world coordinates
		Visualizer::renderBox(vec3{ s }, m, vec4_red, 0, true);
	}
	{
		auto hbb = node->getHierarchyBoundBox();
		auto s = hbb.getSize();
		auto c = hbb.getCenter();
		Mat4 m{ node->getWorldTransform() };
		m.setColumn3(3, m * c); // set translation to center of the bounding box in world coordinates
		Visualizer::renderBox(vec3{ s }, m, vec4_green, 0, true);
	}

The white box are all parented together in a group, with various rotation and scale applied.

Q1: is this normal for getHierarchySpatialBoundBox()? What am I missing?

Now, my need is to compute this green bounding box but I need to filter out some nodes in the hierarchy (cameras, particules, etc).

Q2: How can I rewrite this function and be able to use a filter on it?

Thanks!

 

Posted

Hello!

1. getHierarchySpatial... - returns the bound box of the spatial cell which containing these objects. its always bigger then original bound box - but i can not give an example where it can be usefull. may be for some render features or optimization? i am not sure...

2. this is implementation with mesh-only filter.

void get_hierarchy_bound_box(NodePtr node, WorldBoundBox &bound, const Mat4 &root_itransform, bool only_enabled_nodes)
{
	if (!node)
		return;
	if (only_enabled_nodes && !node->isEnabled())
		return;

	int type = node->getType();
	// step inside NodeReference
	if (type == Unigine::Node::NODE_REFERENCE)
		get_hierarchy_bound_box(Unigine::static_ptr_cast<Unigine::NodeReference>(node)->getReference(), bound, root_itransform, only_enabled_nodes);
	// check mesh only
	else if (type == Unigine::Node::OBJECT_MESH_STATIC ||
			 type == Unigine::Node::OBJECT_MESH_SKINNED ||
			 type == Unigine::Node::OBJECT_MESH_DYNAMIC)
		bound.expand(WorldBoundBox(node->getBoundBox(), root_itransform * node->getWorldTransform()));

	// recursivle call for all children
	for (int i = 0; i < node->getNumChildren(); i++)
		get_hierarchy_bound_box(node->getChild(i), bound, root_itransform, only_enabled_nodes);
}

WorldBoundBox getHierarchyBoundBox(const Unigine::NodePtr &node, bool only_enabled_nodes= false)
{
	WorldBoundBox bound;
	get_hierarchy_bound_box(node, bound, node->getIWorldTransform(), only_enabled_nodes);
	return bound;
}

void exapmple()
{
	Unigine::NodePtr node = Unigine::World::getNodeByName("test");

	Unigine::Math::WorldBoundBox bb = getHierarchyBoundBox(node);

	Unigine::Visualizer::renderBox(Unigine::Math::vec3(bb.getSize()), Unigine::Math::translate(node->getWorldTransform() * bb.getCenter()), Unigine::Math::vec4_red);
}

 

  • Like 1
Posted

Excellent, thanks for the code sample, I was struggling with the math. Just had to change a bit the transform for the visualizer to account for the node rotation, as in my code.

Anyway, about the spatial version, here is a top down snapshot showing the red spatial bounding box is not covering the area of the white boxes. Not sure if this is normal or not as I don't use physics, it just felt strange and wanted to report it as it may be a bug or not:

image.png.227d11c8450d534e68ac1881db6096ff.png

(blue box is with your code, so it works great, yeah!)

 

Posted

Hello Stephane,

It appears that the getHierarchySpatial method might be a legacy component that has remained in the codebase without a clearly defined purpose—at least from our current perspective. If it’s not impacting your workflow, please feel free to disregard it.

Thank you for your understanding!

×
×
  • Create New...