void MergeBounds(Ogre::SceneNode* node, Ogre::SceneNode* rootNode, const Ogre::Matrix4& parentTransform, Ogre::AxisAlignedBox& aabb) { // Get this nodes current transform Ogre::Matrix4 currentTransform = parentTransform; if (node != rootNode) { Ogre::Matrix4 localTransform(node->getOrientation()); localTransform.setTrans(node->getPosition()); currentTransform = currentTransform * localTransform; } // Merge this nodes objects Ogre::SceneNode::ObjectIterator object = node->getAttachedObjectIterator(); while (object.hasMoreElements()) { Ogre::AxisAlignedBox localAABB = object.getNext()->getBoundingBox(); localAABB.transform(currentTransform); aabb.merge(localAABB); } // Iterate through all children and call this function on them Ogre::SceneNode::ChildNodeIterator child = node->getChildIterator(); while (child.hasMoreElements()) { MergeBounds(static_cast<Ogre::SceneNode*>(child.getNext()), rootNode, currentTransform, aabb); } }
Ogre::AxisAlignedBox Renderer::CalculateBounds(Ogre::SceneNode* node) { // As not all scene managers guarantee a hierarchal AABB, calculate this // ourselves using a recursive function Ogre::AxisAlignedBox aabb = Ogre::AxisAlignedBox::BOX_NULL; MergeBounds(node, node, Ogre::Matrix4::IDENTITY, aabb); return aabb; }
Ogre::AxisAlignedBox Animation::getWorldBounds() { Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; std::for_each(mObjectRoot->mEntities.begin(), mObjectRoot->mEntities.end(), MergeBounds(&bounds)); return bounds; }