From 9c5f8b8719fbe9e89c929df46383c2a91aae43f9 Mon Sep 17 00:00:00 2001
From: elsid <elsid.mail@gmail.com>
Date: Sat, 30 Oct 2021 04:34:06 +0200
Subject: [PATCH] Store holder only in parent RecastMeshObject

---
 .../detournavigator/recastmeshobject.cpp      | 37 +++++++-------
 .../detournavigator/recastmeshobject.hpp      | 49 ++++++++++---------
 2 files changed, 46 insertions(+), 40 deletions(-)

diff --git a/components/detournavigator/recastmeshobject.cpp b/components/detournavigator/recastmeshobject.cpp
index 8b4bc2fd6f..31aa13a208 100644
--- a/components/detournavigator/recastmeshobject.cpp
+++ b/components/detournavigator/recastmeshobject.cpp
@@ -11,7 +11,7 @@ namespace DetourNavigator
     namespace
     {
         bool updateCompoundObject(const btCompoundShape& shape, const AreaType areaType,
-            std::vector<RecastMeshObject>& children)
+            std::vector<ChildRecastMeshObject>& children)
         {
             assert(static_cast<std::size_t>(shape.getNumChildShapes()) == children.size());
             bool result = false;
@@ -23,39 +23,33 @@ namespace DetourNavigator
             return result;
         }
 
-        std::vector<RecastMeshObject> makeChildrenObjects(const osg::ref_ptr<const osg::Referenced>& holder,
-                                                          const btCompoundShape& shape, const AreaType areaType)
+        std::vector<ChildRecastMeshObject> makeChildrenObjects(const btCompoundShape& shape, const AreaType areaType)
         {
-            std::vector<RecastMeshObject> result;
+            std::vector<ChildRecastMeshObject> result;
             for (int i = 0, num = shape.getNumChildShapes(); i < num; ++i)
-            {
-                const CollisionShape collisionShape {holder, *shape.getChildShape(i)};
-                result.emplace_back(collisionShape, shape.getChildTransform(i), areaType);
-            }
+                result.emplace_back(*shape.getChildShape(i), shape.getChildTransform(i), areaType);
             return result;
         }
 
-        std::vector<RecastMeshObject> makeChildrenObjects(const osg::ref_ptr<const osg::Referenced>& holder,
-                                                          const btCollisionShape& shape, const AreaType areaType)
+        std::vector<ChildRecastMeshObject> makeChildrenObjects(const btCollisionShape& shape, const AreaType areaType)
         {
             if (shape.isCompound())
-                return makeChildrenObjects(holder, static_cast<const btCompoundShape&>(shape), areaType);
-            return std::vector<RecastMeshObject>();
+                return makeChildrenObjects(static_cast<const btCompoundShape&>(shape), areaType);
+            return {};
         }
     }
 
-    RecastMeshObject::RecastMeshObject(const CollisionShape& shape, const btTransform& transform,
+    ChildRecastMeshObject::ChildRecastMeshObject(const btCollisionShape& shape, const btTransform& transform,
             const AreaType areaType)
-        : mHolder(shape.getHolder())
-        , mShape(shape.getShape())
+        : mShape(shape)
         , mTransform(transform)
         , mAreaType(areaType)
-        , mLocalScaling(mShape.get().getLocalScaling())
-        , mChildren(makeChildrenObjects(mHolder, mShape.get(), mAreaType))
+        , mLocalScaling(shape.getLocalScaling())
+        , mChildren(makeChildrenObjects(shape, mAreaType))
     {
     }
 
-    bool RecastMeshObject::update(const btTransform& transform, const AreaType areaType)
+    bool ChildRecastMeshObject::update(const btTransform& transform, const AreaType areaType)
     {
         bool result = false;
         if (!(mTransform == transform))
@@ -78,4 +72,11 @@ namespace DetourNavigator
                     || result;
         return result;
     }
+
+    RecastMeshObject::RecastMeshObject(const CollisionShape& shape, const btTransform& transform,
+            const AreaType areaType)
+        : mHolder(shape.getHolder())
+        , mImpl(shape.getShape(), transform, areaType)
+    {
+    }
 }
diff --git a/components/detournavigator/recastmeshobject.hpp b/components/detournavigator/recastmeshobject.hpp
index 0c50c2f346..e833ee37e3 100644
--- a/components/detournavigator/recastmeshobject.hpp
+++ b/components/detournavigator/recastmeshobject.hpp
@@ -32,40 +32,45 @@ namespace DetourNavigator
         std::reference_wrapper<const btCollisionShape> mShape;
     };
 
+    class ChildRecastMeshObject
+    {
+        public:
+            ChildRecastMeshObject(const btCollisionShape& shape, const btTransform& transform, const AreaType areaType);
+
+            bool update(const btTransform& transform, const AreaType areaType);
+
+            const btCollisionShape& getShape() const { return mShape; }
+
+            const btTransform& getTransform() const { return mTransform; }
+
+            AreaType getAreaType() const { return mAreaType; }
+
+        private:
+            std::reference_wrapper<const btCollisionShape> mShape;
+            btTransform mTransform;
+            AreaType mAreaType;
+            btVector3 mLocalScaling;
+            std::vector<ChildRecastMeshObject> mChildren;
+    };
+
     class RecastMeshObject
     {
         public:
             RecastMeshObject(const CollisionShape& shape, const btTransform& transform, const AreaType areaType);
 
-            bool update(const btTransform& transform, const AreaType areaType);
+            bool update(const btTransform& transform, const AreaType areaType) { return mImpl.update(transform, areaType); }
 
-            const osg::ref_ptr<const osg::Referenced>& getHolder() const
-            {
-                return mHolder;
-            }
+            const osg::ref_ptr<const osg::Referenced>& getHolder() const { return mHolder; }
 
-            const btCollisionShape& getShape() const
-            {
-                return mShape;
-            }
+            const btCollisionShape& getShape() const { return mImpl.getShape(); }
 
-            const btTransform& getTransform() const
-            {
-                return mTransform;
-            }
+            const btTransform& getTransform() const { return mImpl.getTransform(); }
 
-            AreaType getAreaType() const
-            {
-                return mAreaType;
-            }
+            AreaType getAreaType() const { return mImpl.getAreaType(); }
 
         private:
             osg::ref_ptr<const osg::Referenced> mHolder;
-            std::reference_wrapper<const btCollisionShape> mShape;
-            btTransform mTransform;
-            AreaType mAreaType;
-            btVector3 mLocalScaling;
-            std::vector<RecastMeshObject> mChildren;
+            ChildRecastMeshObject mImpl;
     };
 }