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
This commit is contained in:
frohlich
2009-06-06 07:24:26 +00:00
committed by Tim Moore
parent 9d0bad29c0
commit 81a657edec
3 changed files with 28 additions and 51 deletions

View File

@@ -36,37 +36,10 @@
#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,

View 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);

View 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;