Amerio.Stephane Posted June 8, 2025 Posted June 8, 2025 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): 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!
cash-metall Posted June 9, 2025 Posted June 9, 2025 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); } 1
Amerio.Stephane Posted June 9, 2025 Author Posted June 9, 2025 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: (blue box is with your code, so it works great, yeah!)
bmyagkov Posted June 9, 2025 Posted June 9, 2025 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!
Recommended Posts