From: frohlich Date: Sat, 6 Jun 2009 07:24:26 +0000 (+0000) Subject: Use osg's builtin mechanisms to traverse only in range nodes with the X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=81a657edec93a1bbe79a98251d275e3bed2ebaa8;p=simgear.git Use osg's builtin mechanisms to traverse only in range nodes with the update visitor. Modified Files: simgear/scene/util/SGUpdateVisitor.hxx simgear/scene/tgdb/TileEntry.cxx simgear/scene/model/placementtrans.cxx --- diff --git a/simgear/scene/model/placementtrans.cxx b/simgear/scene/model/placementtrans.cxx index ed452793..14d8491b 100644 --- a/simgear/scene/model/placementtrans.cxx +++ b/simgear/scene/model/placementtrans.cxx @@ -36,37 +36,10 @@ #include "placementtrans.hxx" -#include - -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(nv); - if (updateVisitor) { - SGPlacementTransform* placementTransform; - placementTransform = static_cast(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, diff --git a/simgear/scene/tgdb/TileEntry.cxx b/simgear/scene/tgdb/TileEntry.cxx index 76416a26..772c6704 100644 --- a/simgear/scene/tgdb/TileEntry.cxx +++ b/simgear/scene/tgdb/TileEntry.cxx @@ -56,7 +56,6 @@ #include #include #include -#include #include "ReaderWriterSTG.hxx" #include "TileEntry.hxx" @@ -71,24 +70,6 @@ osgDB::RegisterReaderWriterProxy g_readerWriterSTGProxy; ModelRegistryCallbackProxy 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(nv)); - SGUpdateVisitor* updateVisitor = static_cast(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); diff --git a/simgear/scene/util/SGUpdateVisitor.hxx b/simgear/scene/util/SGUpdateVisitor.hxx index 74d60e99..8f23ed7b 100644 --- a/simgear/scene/util/SGUpdateVisitor.hxx +++ b/simgear/scene/util/SGUpdateVisitor.hxx @@ -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(camera)); + _currentEyePos = currentEyePos; + } else { + apply(static_cast(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;