]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/model/BoundingVolumeBuildVisitor.hxx
Merge branch 'timoore/aptsign' into next
[simgear.git] / simgear / scene / model / BoundingVolumeBuildVisitor.hxx
index ef4439218ce0a3f64034df574d909b3bfd3a9fc7..9155bcece2920c62405ee3af31fd675afacd1d55 100644 (file)
@@ -23,7 +23,6 @@
 #include <osg/Drawable>
 #include <osg/Geode>
 #include <osg/Group>
-#include <osg/MatrixTransform>
 #include <osg/PagedLOD>
 #include <osg/Transform>
 #include <osg/TriangleFunctor>
@@ -375,8 +374,9 @@ public:
     //     virtual void end() = 0;
     // };
 
-    BoundingVolumeBuildVisitor() :
-        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
+    BoundingVolumeBuildVisitor(bool dumpIntoLeafs) :
+        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN),
+        _dumpIntoLeafs(dumpIntoLeafs)
     {
         setTraversalMask(SG_NODEMASK_TERRAIN_BIT);
     }
@@ -384,10 +384,10 @@ public:
     {
     }
 
-    const SGMaterial* pushMaterial(osg::StateSet* stateSet)
+    const SGMaterial* pushMaterial(osg::Geode* geode)
     {
         const SGMaterial* oldMaterial = _primitiveFunctor.getCurrentMaterial();
-        const SGMaterial* material = SGMaterialLib::findMaterial(stateSet);
+        const SGMaterial* material = SGMaterialLib::findMaterial(geode);
         if (material)
             _primitiveFunctor.setCurrentMaterial(material);
         return oldMaterial;
@@ -395,75 +395,101 @@ public:
 
     void fillWith(osg::Drawable* drawable)
     {
-        const SGMaterial* oldMaterial = pushMaterial(drawable->getStateSet());
         drawable->accept(_primitiveFunctor);
-        _primitiveFunctor.setCurrentMaterial(oldMaterial);
     }
 
     virtual void apply(osg::Geode& geode)
     {
-        const SGMaterial* oldMaterial = pushMaterial(geode.getStateSet());
+        if (hasBoundingVolumeTree(geode))
+            return;
+
+        const SGMaterial* oldMaterial = pushMaterial(&geode);
 
-        if (!hasBoundingVolumeTree(geode))
+        bool flushHere = getNodePath().size() <= 1 || _dumpIntoLeafs;
+        if (flushHere) {
+            // push the current active primitive list
+            PFunctor previousPrimitives;
+            _primitiveFunctor.swap(previousPrimitives);
+
+            const SGMaterial* mat = previousPrimitives.getCurrentMaterial();
+            _primitiveFunctor.setCurrentMaterial(mat);
+
+            // walk the children
             for(unsigned i = 0; i < geode.getNumDrawables(); ++i)
                 fillWith(geode.getDrawable(i));
 
-        // Flush the bounding volume tree if we reached the topmost group
-        if (getNodePath().size() <= 1)
+            // Flush the bounding volume tree if we reached the topmost group
             addBoundingVolumeTreeToNode(geode);
+
+            // pop the current active primitive list
+            _primitiveFunctor.swap(previousPrimitives);
+        } else {
+            for(unsigned i = 0; i < geode.getNumDrawables(); ++i)
+                fillWith(geode.getDrawable(i));
+        }
+
         _primitiveFunctor.setCurrentMaterial(oldMaterial);
     }
 
     virtual void apply(osg::Group& group)
-    {
-        // Note that we do not need to push the already collected list of
-        // primitives, since we are now in the topmost node ...
-
-        const SGMaterial* oldMaterial = pushMaterial(group.getStateSet());
+    { traverseAndCollect(group); }
 
-        if (!hasBoundingVolumeTree(group))
-            traverse(group);
+    virtual void apply(osg::Transform& transform)
+    { traverseAndDump(transform); }
 
-        // Flush the bounding volume tree if we reached the topmost group
-        if (getNodePath().size() <= 1)
-            addBoundingVolumeTreeToNode(group);
+    virtual void apply(osg::PagedLOD&)
+    {
+        // Do nothing. In this case we get called by the loading process anyway
+    }
 
-        _primitiveFunctor.setCurrentMaterial(oldMaterial);
+    virtual void apply(osg::Camera& camera)
+    {
+        if (camera.getRenderOrder() != osg::Camera::NESTED_RENDER)
+            return;
+        traverseAndDump(camera);
     }
 
-    virtual void apply(osg::Transform& transform)
+    void traverseAndDump(osg::Node& node)
     {
+        if (hasBoundingVolumeTree(node))
+            return;
+
         // push the current active primitive list
         PFunctor previousPrimitives;
         _primitiveFunctor.swap(previousPrimitives);
 
-        const SGMaterial* oldMaterial = pushMaterial(transform.getStateSet());
+        const SGMaterial* mat = previousPrimitives.getCurrentMaterial();
+        _primitiveFunctor.setCurrentMaterial(mat);
 
         // walk the children
-        if (!hasBoundingVolumeTree(transform))
-            traverse(transform);
+        traverse(node);
 
         // We know whenever we see a transform, we need to flush the
         // collected bounding volume tree since these transforms are not
         // handled by the plain leafs.
-        addBoundingVolumeTreeToNode(transform);
-
-        _primitiveFunctor.setCurrentMaterial(oldMaterial);
+        addBoundingVolumeTreeToNode(node);
 
         // pop the current active primitive list
         _primitiveFunctor.swap(previousPrimitives);
     }
 
-    virtual void apply(osg::PagedLOD&)
+    void traverseAndCollect(osg::Node& node)
     {
-        // Do nothing. In this case we get called by the loading process anyway
-    }
+        // Already been here??
+        if (hasBoundingVolumeTree(node))
+            return;
 
-    virtual void apply(osg::Camera& camera)
-    {
-        if (camera.getRenderOrder() != osg::Camera::NESTED_RENDER)
+        // Force a flush of the bvtree if we are in the topmost node.
+        if (getNodePath().size() <= 1) {
+            traverseAndDump(node);
             return;
-        apply(static_cast<osg::Transform&>(camera));
+        }
+
+        // Note that we do not need to push the already collected list of
+        // primitives, since we are now in the topmost node ...
+
+        // walk the children
+        traverse(node);
     }
 
     void addBoundingVolumeTreeToNode(osg::Node& node)
@@ -493,6 +519,7 @@ public:
 
 private:
     PFunctor _primitiveFunctor;
+    bool _dumpIntoLeafs;
 };
 
 }