#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),
_scenery_center(0, 0, 0),
0, 0, 1, 0,
0, 0, 0, 1)
{
+ setUpdateCallback(new UpdateCallback);
}
SGPlacementTransform::~SGPlacementTransform(void)
SGPlacementTransform(void);
virtual ~SGPlacementTransform(void);
-public:
-
void setTransform(const SGVec3d& off)
{ _placement_offset = off; dirtyBound(); }
void setTransform(const SGVec3d& off, const SGMatrixd& rot)
void setSceneryCenter(const SGVec3d& center)
{ _scenery_center = center; dirtyBound(); }
+ const SGVec3d& getGlobalPos() const
+ { return _placement_offset; }
+
virtual bool computeLocalToWorldMatrix(osg::Matrix&,osg::NodeVisitor*) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix&,osg::NodeVisitor*) const;
private:
+ class UpdateCallback;
+
//////////////////////////////////////////////////////////////////
// private data //
//////////////////////////////////////////////////////////////////