From 06676fd6230c06fff6ffca2a30f7e077e425e042 Mon Sep 17 00:00:00 2001 From: "glassmancody.info" Date: Fri, 19 May 2023 14:29:01 -0700 Subject: [PATCH] lua - fix bounding box in active grid --- apps/openmw/mwlua/objectbindings.cpp | 11 +++--- apps/openmw/mwrender/renderingmanager.cpp | 44 +++++++++++++++++++++++ apps/openmw/mwrender/renderingmanager.hpp | 3 ++ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwlua/objectbindings.cpp b/apps/openmw/mwlua/objectbindings.cpp index c00cf6535d..177bdc77b6 100644 --- a/apps/openmw/mwlua/objectbindings.cpp +++ b/apps/openmw/mwlua/objectbindings.cpp @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" @@ -13,6 +11,7 @@ #include "../mwworld/player.hpp" #include "../mwworld/scene.hpp" +#include "../mwrender/renderingmanager.hpp" #include "../mwrender/vismask.hpp" #include "../mwmechanics/creaturestats.hpp" @@ -157,11 +156,9 @@ namespace MWLua objectT["rotation"] = sol::readonly_property( [](const ObjectT& o) -> osg::Vec3f { return o.ptr().getRefData().getPosition().asRotationVec3(); }); objectT["getBoundingBox"] = [](const ObjectT& o) { - const MWWorld::Ptr& ptr = o.ptr(); - SceneUtil::CullSafeBoundsVisitor computeBounds; - computeBounds.setTraversalMask(~(MWRender::Mask_ParticleSystem | MWRender::Mask_Effect)); - ptr.getRefData().getBaseNode()->accept(computeBounds); - osg::BoundingBox bb = computeBounds.mBoundingBox; + MWRender::RenderingManager* renderingManager + = MWBase::Environment::get().getWorld()->getRenderingManager(); + osg::BoundingBox bb = renderingManager->getCullSafeBoundingBox(o.ptr()); return LuaUtil::Box{ bb.center(), bb._max - bb.center() }; }; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index d2b4ee1bc2..3987ee587d 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -33,6 +33,7 @@ #include +#include #include #include #include @@ -1495,6 +1496,49 @@ namespace MWRender return halfExtents; } + osg::BoundingBox RenderingManager::getCullSafeBoundingBox(const MWWorld::Ptr& ptr) const + { + const std::string model = ptr.getClass().getModel(ptr); + if (model.empty()) + return {}; + + osg::ref_ptr rootNode = new SceneUtil::PositionAttitudeTransform; + // Hack even used by osg internally, osg's NodeVisitor won't accept const qualified nodes + rootNode->addChild(const_cast(mResourceSystem->getSceneManager()->getTemplate(model).get())); + + const SceneUtil::PositionAttitudeTransform* baseNode = ptr.getRefData().getBaseNode(); + if (baseNode) + { + rootNode->setPosition(baseNode->getPosition()); + rootNode->setAttitude(baseNode->getAttitude()); + rootNode->setScale(baseNode->getScale()); + } + else + { + rootNode->setPosition(ptr.getRefData().getPosition().asVec3()); + osg::Vec3f rot = ptr.getRefData().getPosition().asRotationVec3(); + rootNode->setAttitude(osg::Quat(rot[2], osg::Vec3f(0, 0, -1)) * osg::Quat(rot[1], osg::Vec3f(0, -1, 0)) + * osg::Quat(rot[0], osg::Vec3f(-1, 0, 0))); + const float refScale = ptr.getCellRef().getScale(); + rootNode->setScale({ refScale, refScale, refScale }); + } + + SceneUtil::CullSafeBoundsVisitor computeBounds; + computeBounds.setTraversalMask(~(MWRender::Mask_ParticleSystem | MWRender::Mask_Effect)); + rootNode->accept(computeBounds); + + const osg::Vec3f& scale = rootNode->getScale(); + + computeBounds.mBoundingBox.xMin() *= scale.x(); + computeBounds.mBoundingBox.xMax() *= scale.x(); + computeBounds.mBoundingBox.yMin() *= scale.y(); + computeBounds.mBoundingBox.yMax() *= scale.y(); + computeBounds.mBoundingBox.zMin() *= scale.z(); + computeBounds.mBoundingBox.zMax() *= scale.z(); + + return computeBounds.mBoundingBox; + } + void RenderingManager::resetFieldOfView() { if (mFieldOfViewOverridden == true) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index b038e76b16..ad6a53e8aa 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -244,6 +244,9 @@ namespace MWRender osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const; + // Return local bounding box. Safe to be called in parallel with cull thread. + osg::BoundingBox getCullSafeBoundingBox(const MWWorld::Ptr& ptr) const; + void exportSceneGraph( const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format);