]> git.mxchange.org Git - simgear.git/commitdiff
Use osg's builtin mechanisms to traverse only in range nodes with the
authorfrohlich <frohlich>
Sat, 6 Jun 2009 07:24:26 +0000 (07:24 +0000)
committerTim Moore <timoore@redhat.com>
Thu, 11 Jun 2009 13:55:10 +0000 (15:55 +0200)
update visitor.

Modified Files:
simgear/scene/util/SGUpdateVisitor.hxx
  simgear/scene/tgdb/TileEntry.cxx
  simgear/scene/model/placementtrans.cxx

simgear/scene/model/placementtrans.cxx
simgear/scene/tgdb/TileEntry.cxx
simgear/scene/util/SGUpdateVisitor.hxx

index ed4527933024cbc35741d05e4193ed0e41e4f8bd..14d8491b1c1f3d39e9f737a1b5259f33cc2ff9ab 100644 (file)
 
 #include "placementtrans.hxx"
 
-#include <simgear/scene/util/SGUpdateVisitor.hxx>
-
-class SGPlacementTransform::UpdateCallback : public osg::NodeCallback {
-public:
-  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
-  {
-    // short circuit updates if the model we place with that branch
-    // out of sight.
-    // Note that the transform is still correct.
-    SGUpdateVisitor* updateVisitor = dynamic_cast<SGUpdateVisitor*>(nv);
-    if (updateVisitor) {
-      SGPlacementTransform* placementTransform;
-      placementTransform = static_cast<SGPlacementTransform*>(node);
-      double dist2 = distSqr(updateVisitor->getGlobalEyePos(),
-                             placementTransform->getGlobalPos());
-      if (updateVisitor->getSqrVisibility() < dist2)
-        return;
-    }
-    // note, callback is responsible for scenegraph traversal so
-    // should always include call traverse(node,nv) to ensure 
-    // that the rest of cullbacks and the scene graph are traversed.
-    traverse(node, nv);
-  }
-};
-
-
 SGPlacementTransform::SGPlacementTransform(void) :
   _placement_offset(0, 0, 0),
   _rotation(SGQuatd::unit())
 {
-  setUpdateCallback(new UpdateCallback);
 }
 
 SGPlacementTransform::SGPlacementTransform(const SGPlacementTransform& trans,
index 76416a266369a35714bc2c53a2d717b98d3c1dbb..772c6704d6da85f90f5fd0896716be9f1b05ae2d 100644 (file)
@@ -56,7 +56,6 @@
 #include <simgear/scene/tgdb/obj.hxx>
 #include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx>
 #include <simgear/scene/model/placementtrans.hxx>
-#include <simgear/scene/util/SGUpdateVisitor.hxx>
 
 #include "ReaderWriterSTG.hxx"
 #include "TileEntry.hxx"
@@ -71,24 +70,6 @@ osgDB::RegisterReaderWriterProxy<ReaderWriterSTG> g_readerWriterSTGProxy;
 ModelRegistryCallbackProxy<LoadOnlyCallback> g_stgCallbackProxy("stg");
 }
 
-// FIXME: investigate what huge update flood is clamped away here ...
-class FGTileUpdateCallback : public osg::NodeCallback {
-public:
-  virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
-  {
-    assert(dynamic_cast<SGUpdateVisitor*>(nv));
-    SGUpdateVisitor* updateVisitor = static_cast<SGUpdateVisitor*>(nv);
-
-    osg::Vec3 center = node->getBound().center();
-    double distance = dist(updateVisitor->getGlobalEyePos(),
-                           SGVec3d(center[0], center[1], center[2]));
-    if (updateVisitor->getVisibility() + node->getBound().radius() < distance)
-      return;
-
-    traverse(node, nv);
-  }
-};
-
 namespace
 {
 // Update the timestamp on a tile whenever it is in view.
@@ -143,7 +124,6 @@ TileEntry::TileEntry ( const SGBucket& b )
       is_inner_ring(false),
       tileFileName(b.gen_index_str())
 {
-    _node->setUpdateCallback(new FGTileUpdateCallback);
     _node->setCullCallback(new TileCullCallback);
     tileFileName += ".stg";
     _node->setName(tileFileName);
index 74d60e995169c474d38bc6b84940fb48687a7f8c..8f23ed7b221f555df4483e9f3c46b14e465526f8 100644 (file)
@@ -32,16 +32,14 @@ public:
   SGUpdateVisitor() :
     mVisibility(-1)
   {
-    // Need to traverse all children, else some LOD nodes do not get updated
-    // Note that the broad number of updates is not done due to
-    // the update callback in the global position node.
-    setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
+    setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
     setVisibility(10000);
   }
   void setViewData(const SGVec3d& globalEyePos,
                    const SGQuatd& globalViewOrientation)
   {
     mGlobalGeodEyePos = SGGeod::fromCart(globalEyePos);
+    _currentEyePos = globalEyePos.osg();
     mGlobalEyePos = globalEyePos;
     mGlobalViewOr = globalViewOrientation;
     mGlobalHorizLocalOr = SGQuatd::fromLonLat(mGlobalGeodEyePos);
@@ -134,8 +132,34 @@ public:
 
   double getSunAngleDeg() const
   { return mSunAngleDeg; }
+    
+  // To be able to traverse correctly only the active children, we need to
+  // track the model view matrices during update.
+  virtual void apply(osg::Transform& transform)
+  {
+    osg::Matrix matrix = _matrix;
+    transform.computeLocalToWorldMatrix(_matrix, this);
+    osgUtil::UpdateVisitor::apply(transform);
+    _matrix = matrix;
+  }
+  virtual void apply(osg::Camera& camera)
+  {
+    if (camera.getReferenceFrame() == osg::Camera::ABSOLUTE_RF) {
+      osg::Vec3d currentEyePos = _currentEyePos;
+      _currentEyePos = osg::Vec3d(0, 0, 0);
+      apply(static_cast<osg::Transform&>(camera));
+      _currentEyePos = currentEyePos;
+    } else {
+      apply(static_cast<osg::Transform&>(camera));
+    }
+  }
+  virtual float getDistanceToViewPoint(const osg::Vec3& pos, bool) const
+  { return (_currentEyePos - _matrix.preMult(osg::Vec3d(pos))).length(); }
 
 private:
+  osg::Matrix _matrix;
+  osg::Vec3d _currentEyePos;
+
   SGGeod mGlobalGeodEyePos;
   SGVec3d mGlobalEyePos;
   SGQuatd mGlobalViewOr;