From a659d2eaeb9a91c845869890b752fda2a6df6a6f Mon Sep 17 00:00:00 2001
From: "glassmancody.info" <glassmancody.info@gmail.com>
Date: Tue, 4 Jul 2023 09:55:11 -0700
Subject: [PATCH] lua - fix bounding box once and for all

---
 apps/openmw/mwrender/renderingmanager.cpp     | 32 ++++++-------------
 .../sceneutil/cullsafeboundsvisitor.hpp       |  4 ++-
 2 files changed, 12 insertions(+), 24 deletions(-)

diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp
index 21cad8a51f..d8e0bd13c8 100644
--- a/apps/openmw/mwrender/renderingmanager.cpp
+++ b/apps/openmw/mwrender/renderingmanager.cpp
@@ -1536,36 +1536,22 @@ namespace MWRender
         // Hack even used by osg internally, osg's NodeVisitor won't accept const qualified nodes
         rootNode->addChild(const_cast<osg::Node*>(mResourceSystem->getSceneManager()->getTemplate(model).get()));
 
-        const SceneUtil::PositionAttitudeTransform* baseNode = ptr.getRefData().getBaseNode();
-        if (baseNode)
+        const float refScale = ptr.getCellRef().getScale();
+        rootNode->setScale({ refScale, refScale, refScale });
+        rootNode->setPosition(osg::Vec3(0, 0, 0));
+
+        osg::ref_ptr<Animation> animation = nullptr;
+
+        if (ptr.getClass().isNpc())
         {
-            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 });
+            rootNode->setNodeMask(Mask_Actor);
+            animation = new NpcAnimation(ptr, osg::ref_ptr<osg::Group>(rootNode), mResourceSystem);
         }
 
         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;
     }
 
diff --git a/components/sceneutil/cullsafeboundsvisitor.hpp b/components/sceneutil/cullsafeboundsvisitor.hpp
index 02fe21b6bd..b3a9789206 100644
--- a/components/sceneutil/cullsafeboundsvisitor.hpp
+++ b/components/sceneutil/cullsafeboundsvisitor.hpp
@@ -12,7 +12,7 @@
 
 namespace SceneUtil
 {
-    // Computes local bounding box of a node without dirtying itself or any of its children
+    // Computes bounding box of a node without dirtying it or any of its children
     struct CullSafeBoundsVisitor : osg::NodeVisitor
     {
         CullSafeBoundsVisitor(osg::NodeVisitor::TraversalMode traversalMode = TRAVERSE_ALL_CHILDREN)
@@ -39,6 +39,8 @@ namespace SceneUtil
             if (!mMatrixStack.empty())
                 matrix = mMatrixStack.back();
 
+            transform.computeLocalToWorldMatrix(matrix, this);
+
             mMatrixStack.push_back(matrix);
             traverse(transform);
             mMatrixStack.pop_back();