Index: /OpenSceneGraph/trunk/examples/osgdepthpartition/osgdepthpartition.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgdepthpartition/osgdepthpartition.cpp (revision 10021)
+++ /OpenSceneGraph/trunk/examples/osgdepthpartition/osgdepthpartition.cpp (revision 12503)
@@ -25,8 +25,8 @@
 
 #include <osgGA/TrackballManipulator>
+#include <osgGA/StateSetManipulator>
 
 #include <osgViewer/Viewer>
-
-#include "DepthPartitionNode.h"
+#include <osgViewer/ViewerEventHandlers>
 
 const double r_earth = 6378.137;
@@ -133,4 +133,10 @@
     osgViewer::Viewer viewer;
 
+    // add the state manipulator
+    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
+
+    // add stats
+    viewer.addEventHandler( new osgViewer::StatsHandler() );
+
     bool needToSetHomePosition = false;
 
@@ -144,12 +150,6 @@
         needToSetHomePosition = true;
     }
-    
-    // Create a DepthPartitionNode to manage partitioning of the scene
-    osg::ref_ptr<DepthPartitionNode> dpn = new DepthPartitionNode;
-    dpn->addChild(scene.get());
-    dpn->setActive(true); // Control whether the node analyzes the scene
-        
     // pass the loaded scene graph to the viewer.
-    viewer.setSceneData(dpn.get());
+    viewer.setSceneData(scene.get());
 
     viewer.setCameraManipulator(new osgGA::TrackballManipulator);
@@ -157,9 +157,24 @@
     if (needToSetHomePosition)
     {
-      viewer.getCameraManipulator()->setHomePosition(osg::Vec3d(0.0,-5.0*r_earth,0.0),osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,0.0,1.0));
+        viewer.getCameraManipulator()->setHomePosition(osg::Vec3d(0.0,-5.0*r_earth,0.0),osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,0.0,1.0));
     }
     
-    // depth partion node is only supports single window/single threaded at present.
-    viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
+    double zNear=1.0, zMid=10.0, zFar=1000.0;
+    if (arguments.read("--depth-partition",zNear, zMid, zFar))
+    {
+        // set up depth partitioning
+        osg::ref_ptr<osgViewer::DepthPartitionSettings> dps = new osgViewer::DepthPartitionSettings;
+        dps->_mode = osgViewer::DepthPartitionSettings::FIXED_RANGE;
+        dps->_zNear = zNear;
+        dps->_zMid = zMid;
+        dps->_zFar = zFar;
+        viewer.setUpDepthPartition(dps.get());
+    }
+    else
+    {
+        // set up depth partitioning with default settings
+        viewer.setUpDepthPartition();
+    }
+    
 
     return viewer.run();
Index: /OpenSceneGraph/trunk/examples/osgdepthpartition/CMakeLists.txt
===================================================================
--- /OpenSceneGraph/trunk/examples/osgdepthpartition/CMakeLists.txt (revision 7025)
+++ /OpenSceneGraph/trunk/examples/osgdepthpartition/CMakeLists.txt (revision 12503)
@@ -1,7 +1,4 @@
-#this file is automatically generated 
+SET(TARGET_SRC osgdepthpartition.cpp )
 
-
-SET(TARGET_SRC DepthPartitionNode.cpp DistanceAccumulator.cpp osgdepthpartition.cpp )
-SET(TARGET_H DepthPartitionNode.h DistanceAccumulator.h )
 #### end var setup  ###
 SETUP_EXAMPLE(osgdepthpartition)
Index: /enSceneGraph/trunk/examples/osgdepthpartition/DistanceAccumulator.h
===================================================================
--- /OpenSceneGraph/trunk/examples/osgdepthpartition/DistanceAccumulator.h (revision 6941)
+++  (revision )
@@ -1,115 +1,0 @@
-/* -*-c++-*- 
-*
-*  OpenSceneGraph example, osgdepthpartion.
-*
-*  Permission is hereby granted, free of charge, to any person obtaining a copy
-*  of this software and associated documentation files (the "Software"), to deal
-*  in the Software without restriction, including without limitation the rights
-*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-*  copies of the Software, and to permit persons to whom the Software is
-*  furnished to do so, subject to the following conditions:
-*
-*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-*  THE SOFTWARE.
-*/
-
-#ifndef _OF_DISTANCEACCUMULATOR_
-#define _OF_DISTANCEACCUMULATOR_
-
-#include <osg/Group>
-#include <osg/NodeVisitor>
-#include <osg/Polytope>
-#include <osg/fast_back_stack>
-
-#define CURRENT_CLASS DistanceAccumulator
-/**********************************************************
- * Ravi Mathur
- * OpenFrames API, class DistanceAccumulator
- * Class that traverses the scene and computes the distance to each
- * visible drawable, and splits up the scene if the drawables are
- * too far away (in the z direction) from each other. 
-**********************************************************/
-class CURRENT_CLASS : public osg::NodeVisitor
-{
-  public:
-	typedef std::pair<double, double> DistancePair;
-	typedef std::vector<DistancePair> PairList;
-
-	CURRENT_CLASS();
-
-	virtual void apply(osg::Node &node);
-	virtual void apply(osg::Projection &proj);
-	virtual void apply(osg::Transform &transform);
-	virtual void apply(osg::Geode &geode);
-
-	// Specify the modelview & projection matrices
-	void setMatrices(const osg::Matrix &modelview,
-	                 const osg::Matrix &projection);
-
-	// Reset visitor before a new traversal
-	virtual void reset();
-
-	// Create a (near,far) distance pair for each camera of the specified
-	// distance pair list and distance limits.
-	void computeCameraPairs();
-
-	// Get info on the cameras that should be used for scene rendering
-	PairList& getCameraPairs() { return _cameraPairs; }
-
-	// Get info on the computed distance pairs
-	PairList& getDistancePairs() { return _distancePairs; }
-
-	// Get info on the computed nearest/farthest distances
-	DistancePair& getLimits() { return _limits; }
-
-	// Set/get the desired near/far ratio
-	void setNearFarRatio(double ratio);
-	inline double getNearFarRatio() const { return _nearFarRatio; }
-
-	inline void setMaxDepth(unsigned int depth) { _maxDepth = depth; }
-	inline unsigned int getMaxDepth() const { return _maxDepth; }
-
-  protected:
-	virtual ~CURRENT_CLASS();
-
-	void pushLocalFrustum();
-	void pushDistancePair(double zNear, double zFar);
-	bool shouldContinueTraversal(osg::Node &node);
-
-	// Stack of matrices accumulated during traversal
-	osg::fast_back_stack<osg::Matrix> _viewMatrices;
-	osg::fast_back_stack<osg::Matrix> _projectionMatrices;
-
-	// Main modelview/projection matrices
-	osg::Matrix _modelview, _projection;
-
-	// The view frusta in local coordinate space
-	osg::fast_back_stack<osg::Polytope> _localFrusta;
-
-	// Bounding box corners that should be used for cull computation
-	typedef std::pair<unsigned int, unsigned int> bbCornerPair;
-	osg::fast_back_stack<bbCornerPair> _bbCorners;
-
-	// Nar/far planes that should be used for each camera
-	PairList _cameraPairs;
-
-	// Accumulated pairs of min/max distances
-	PairList _distancePairs;
-
-	// The closest & farthest distances found while traversing
-	DistancePair _limits;
-
-	// Ratio of nearest/farthest clip plane for each section of the scene
-	double _nearFarRatio;
-
-	// Maximum depth to traverse to
-	unsigned int _maxDepth, _currentDepth;
-};
-#undef CURRENT_CLASS
-
-#endif
Index: /enSceneGraph/trunk/examples/osgdepthpartition/DepthPartitionNode.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgdepthpartition/DepthPartitionNode.cpp (revision 6941)
+++  (revision )
@@ -1,272 +1,0 @@
-/* OpenSceneGraph example, osgdepthpartion.
-*
-*  Permission is hereby granted, free of charge, to any person obtaining a copy
-*  of this software and associated documentation files (the "Software"), to deal
-*  in the Software without restriction, including without limitation the rights
-*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-*  copies of the Software, and to permit persons to whom the Software is
-*  furnished to do so, subject to the following conditions:
-*
-*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-*  THE SOFTWARE.
-*/
-
-#include "DepthPartitionNode.h"
-#include <osgUtil/CullVisitor>
-
-using namespace osg;
-
-#define CURRENT_CLASS DepthPartitionNode
-
-CURRENT_CLASS::CURRENT_CLASS()
-{
-    _distAccumulator = new DistanceAccumulator;
-    init();
-}
-
-CURRENT_CLASS::CURRENT_CLASS(const CURRENT_CLASS& dpn, const osg::CopyOp& copyop)
-    : osg::Group(dpn, copyop),
-          _active(dpn._active),
-          _renderOrder(dpn._renderOrder),
-          _clearColorBuffer(dpn._clearColorBuffer)
-{
-    _distAccumulator = new DistanceAccumulator;
-    _numCameras = 0;
-}
-
-CURRENT_CLASS::~CURRENT_CLASS() {}
-
-void CURRENT_CLASS::init()
-{
-    _active = true;
-    _numCameras = 0;
-    setCullingActive(false);
-    _renderOrder = osg::Camera::POST_RENDER;
-    _clearColorBuffer = true;
-}
-
-void CURRENT_CLASS::setActive(bool active)
-{
-    if(_active == active) return;
-    _active = active;
-}
-
-void CURRENT_CLASS::setClearColorBuffer(bool clear)
-{
-    _clearColorBuffer = clear;
-
-    // Update the render order for the first Camera if it exists
-    if(!_cameraList.empty())
-    {
-      if(clear) 
-        _cameraList[0]->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-      else  
-        _cameraList[0]->setClearMask(GL_DEPTH_BUFFER_BIT);
-    }
-}
-
-void CURRENT_CLASS::setRenderOrder(osg::Camera::RenderOrder order)
-{
-    _renderOrder = order;
-
-    // Update the render order for existing Cameras
-    unsigned int numCameras = _cameraList.size();
-    for(unsigned int i = 0; i < numCameras; i++)
-    {
-      _cameraList[i]->setRenderOrder(_renderOrder);
-    }
-}
-
-void CURRENT_CLASS::traverse(osg::NodeVisitor &nv)
-{
-    // If the scene hasn't been defined then don't do anything
-    unsigned int numChildren = _children.size();
-    if(numChildren == 0) return;
-
-    // If the node is not active then don't analyze it
-    if(!_active)
-    {
-      // Traverse the graph as usual
-      Group::traverse(nv);
-      return;
-    }
-
-    // If the visitor is not a cull visitor, pass it directly onto the scene.
-    osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
-    if(!cv) 
-    { 
-      Group::traverse(nv);
-      return; 
-    }
-
-    // We are in the cull traversal, so first collect information on the
-    // current modelview and projection matrices and viewport.
-    osg::RefMatrix& modelview = *(cv->getModelViewMatrix());
-    osg::RefMatrix& projection = *(cv->getProjectionMatrix());
-    osg::Viewport* viewport = cv->getViewport();
-
-    // Prepare for scene traversal.
-    _distAccumulator->setMatrices(modelview, projection);
-    _distAccumulator->setNearFarRatio(cv->getNearFarRatio());
-    _distAccumulator->reset();
-
-    // Step 1: Traverse the children, collecting the near/far distances.
-    unsigned int i;
-    for(i = 0; i < numChildren; i++)
-    {
-      _children[i]->accept(*(_distAccumulator.get()));
-    }
-
-    // Step 2: Compute the near and far distances for every Camera that
-    // should be used to render the scene.
-    _distAccumulator->computeCameraPairs();
-
-    // Step 3: Create the Cameras, and add them as children.
-    DistanceAccumulator::PairList& camPairs = _distAccumulator->getCameraPairs();
-    _numCameras = camPairs.size(); // Get the number of cameras
-
-    // Create the Cameras, and add them as children.
-    if(_numCameras > 0)
-    {
-      osg::Camera *currCam;
-      DistanceAccumulator::DistancePair currPair;
-
-      for(i = 0; i < _numCameras; i++)
-      {
-        // Create the camera, and clamp it's projection matrix
-        currPair = camPairs[i];  // (near,far) pair for current camera
-        currCam = createOrReuseCamera(projection, currPair.first, 
-                                      currPair.second, i);
-
-        // Set the modelview matrix and viewport of the camera
-        currCam->setViewMatrix(modelview);
-        currCam->setViewport(viewport);
-
-        // Redirect the CullVisitor to the current camera
-        currCam->accept(nv);
-      }
-
-      // Set the clear color for the first camera
-      _cameraList[0]->setClearColor(cv->getRenderStage()->getClearColor());
-    }
-}
-
-bool CURRENT_CLASS::addChild(osg::Node *child)
-{
-    return insertChild(_children.size(), child);
-}
-
-bool CURRENT_CLASS::insertChild(unsigned int index, osg::Node *child)
-{
-    if(!Group::insertChild(index, child)) return false; // Insert child
-
-    // Insert child into each Camera
-    unsigned int totalCameras = _cameraList.size();
-    for(unsigned int i = 0; i < totalCameras; i++)
-    {
-      _cameraList[i]->insertChild(index, child);
-    }
-    return true;
-}
-
-
-bool CURRENT_CLASS::removeChildren(unsigned int pos, unsigned int numRemove)
-{
-    if(!Group::removeChildren(pos, numRemove)) return false; // Remove child
-
-    // Remove child from each Camera
-    unsigned int totalCameras = _cameraList.size();
-    for(unsigned int i = 0; i < totalCameras; i++)
-    {
-      _cameraList[i]->removeChildren(pos, numRemove);
-    }
-    return true;
-}
-
-bool CURRENT_CLASS::setChild(unsigned int i, osg::Node *node)
-{
-    if(!Group::setChild(i, node)) return false; // Set child
-
-    // Set child for each Camera
-    unsigned int totalCameras = _cameraList.size();
-    for(unsigned int j = 0; j < totalCameras; j++)
-    {
-      _cameraList[j]->setChild(i, node);
-    }
-    return true;
-}
-
-osg::Camera* CURRENT_CLASS::createOrReuseCamera(const osg::Matrix& proj, 
-                            double znear, double zfar, 
-                            const unsigned int &camNum)
-{
-    if(_cameraList.size() <= camNum) _cameraList.resize(camNum+1);
-    osg::Camera *camera = _cameraList[camNum].get();
-    
-    if(!camera) // Create a new Camera
-    {
-      camera = new osg::Camera;
-      camera->setCullingActive(false);
-      camera->setRenderOrder(_renderOrder);
-      camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
-
-      // We will compute the near/far planes ourselves
-      camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
-      camera->setCullingMode(osg::CullSettings::ENABLE_ALL_CULLING);
-
-      if(camNum == 0 && _clearColorBuffer)
-        camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-      else
-        camera->setClearMask(GL_DEPTH_BUFFER_BIT);
-
-      // Add our children to the new Camera's children
-      unsigned int numChildren = _children.size();
-      for(unsigned int i = 0; i < numChildren; i++)
-      {
-        camera->addChild(_children[i].get());
-      }
-
-      _cameraList[camNum] = camera;
-    }
-
-    osg::Matrixd &projection = camera->getProjectionMatrix();
-    projection = proj;
-
-    // Slightly inflate the near & far planes to avoid objects at the
-    // extremes being clipped out.
-    znear *= 0.999;
-    zfar *= 1.001;
-
-    // Clamp the projection matrix z values to the range (near, far)
-    double epsilon = 1.0e-6;
-    if(fabs(projection(0,3)) < epsilon &&
-       fabs(projection(1,3)) < epsilon &&
-       fabs(projection(2,3)) < epsilon ) // Projection is Orthographic
-    {
-      epsilon = -1.0/(zfar - znear); // Used as a temp variable
-      projection(2,2) = 2.0*epsilon;
-      projection(3,2) = (zfar + znear)*epsilon;
-    }
-    else // Projection is Perspective
-    {
-      double trans_near = (-znear*projection(2,2) + projection(3,2)) /
-                          (-znear*projection(2,3) + projection(3,3));
-      double trans_far = (-zfar*projection(2,2) + projection(3,2)) /
-                         (-zfar*projection(2,3) + projection(3,3));
-      double ratio = fabs(2.0/(trans_near - trans_far));
-      double center = -0.5*(trans_near + trans_far);
-
-      projection.postMult(osg::Matrixd(1.0, 0.0, 0.0, 0.0,
-                                       0.0, 1.0, 0.0, 0.0,
-                            0.0, 0.0, ratio, 0.0,
-                       0.0, 0.0, center*ratio, 1.0));
-    }
-
-    return camera;
-}
-#undef CURRENT_CLASS
Index: /enSceneGraph/trunk/examples/osgdepthpartition/DepthPartitionNode.h
===================================================================
--- /OpenSceneGraph/trunk/examples/osgdepthpartition/DepthPartitionNode.h (revision 6941)
+++  (revision )
@@ -1,105 +1,0 @@
-/* -*-c++-*- 
-*
-*  OpenSceneGraph example, osgdepthpartion.
-*
-*  Permission is hereby granted, free of charge, to any person obtaining a copy
-*  of this software and associated documentation files (the "Software"), to deal
-*  in the Software without restriction, including without limitation the rights
-*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-*  copies of the Software, and to permit persons to whom the Software is
-*  furnished to do so, subject to the following conditions:
-*
-*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-*  THE SOFTWARE.
-*/
-
-#ifndef _OF_DEPTHPARTITIONNODE_
-#define _OF_DEPTHPARTITIONNODE_
-
-#include "DistanceAccumulator.h"
-#include <osg/Camera>
-
-#define CURRENT_CLASS DepthPartitionNode
-/**********************************************************
- * Ravi Mathur
- * OpenFrames API, class DepthPartitionNode
- * A type of osg::Group that analyzes a scene, then partitions it into
- * several segments that can be rendered separately. Each segment
- * is small enough in the z-direction to avoid depth buffer problems
- * for very large scenes.
-**********************************************************/
-class CURRENT_CLASS : public osg::Group
-{
-  public:
-	CURRENT_CLASS();
-	CURRENT_CLASS(const CURRENT_CLASS& dpn, 
-	              const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
-
-	META_Node( OpenFrames, CURRENT_CLASS ); // Common Node functions
-
-	/** Set the active state. If not active, this node will simply add the
-	    specified scene as it's child, without analyzing it at all. */
-	void setActive(bool active);
-	inline bool getActive() const { return _active; }
-
-	/** Specify whether the color buffer should be cleared before the first
-	    Camera draws it's scene. */
-	void setClearColorBuffer(bool clear);
-	inline bool getClearColorBuffer() const { return _clearColorBuffer; }
-
-	/** Specify the render order for each Camera */
-	void setRenderOrder(osg::Camera::RenderOrder order);
-	inline osg::Camera::RenderOrder getRenderOrder() const
-	{ return _renderOrder; }
-
-	/** Set/get the maximum depth that the scene will be traversed to.
-	    Defaults to UINT_MAX. */
-	void setMaxTraversalDepth(unsigned int depth) 
-	{ _distAccumulator->setMaxDepth(depth); }
-
-	inline unsigned int getMaxTraversalDepth() const
-	{ return _distAccumulator->getMaxDepth(); }
-
-	/** Override update and cull traversals */
-	virtual void traverse(osg::NodeVisitor &nv);
-
-	/** Catch child management functions so the Cameras can be informed
-	    of added or removed children. */
-	virtual bool addChild(osg::Node *child);
-	virtual bool insertChild(unsigned int index, osg::Node *child);
-	virtual bool removeChildren(unsigned int pos, unsigned int numRemove = 1);
-	virtual bool setChild(unsigned int i, osg::Node *node);
-
-  protected:
-	typedef std::vector< osg::ref_ptr<osg::Camera> > CameraList;
-
-	~CURRENT_CLASS();
-
-	void init();
-
-	// Creates a new Camera object with default settings
-	osg::Camera* createOrReuseCamera(const osg::Matrix& proj, 
-                                double znear, double zfar, 
-                                const unsigned int &camNum);
-
-	bool _active; // Whether partitioning is active on the scene
-
-	// The NodeVisitor that computes cameras for the scene
-	osg::ref_ptr<DistanceAccumulator> _distAccumulator;
-
-	osg::Camera::RenderOrder _renderOrder;
-	bool _clearColorBuffer;
-
-	// Cameras that should be used to draw the scene.  These cameras
-	// will be reused on every frame in order to save time and memory.
-	CameraList _cameraList;
-	unsigned int _numCameras; // Number of Cameras actually being used
-};
-#undef CURRENT_CLASS
-
-#endif
Index: /enSceneGraph/trunk/examples/osgdepthpartition/DistanceAccumulator.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgdepthpartition/DistanceAccumulator.cpp (revision 10001)
+++  (revision )
@@ -1,402 +1,0 @@
-/* OpenSceneGraph example, osgdepthpartion.
-*
-*  Permission is hereby granted, free of charge, to any person obtaining a copy
-*  of this software and associated documentation files (the "Software"), to deal
-*  in the Software without restriction, including without limitation the rights
-*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-*  copies of the Software, and to permit persons to whom the Software is
-*  furnished to do so, subject to the following conditions:
-*
-*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-*  THE SOFTWARE.
-*/
-
-#include "DistanceAccumulator.h"
-#include <osg/Geode>
-#include <osg/Transform>
-#include <osg/Projection>
-#include <algorithm>
-#include <math.h>
-#include <limits.h>
-
-/** Function that sees whether one DistancePair should come before another in
-    an sorted list. Used to sort the vector of DistancePairs. */
-bool precedes(const DistanceAccumulator::DistancePair &a, 
-              const DistanceAccumulator::DistancePair &b)
-{
-    // This results in sorting in order of descending far distances
-    if(a.second > b.second) return true;
-    else return false;
-}
-
-/** Computes distance (in z direction) betwen a point and the viewer's eye,
-    given by a view matrix */
-double distance(const osg::Vec3 &coord, const osg::Matrix& matrix)
-{
-    // Here we are taking only the z coordinate of the point transformed
-    // by the matrix, ie coord*matrix. The negative sign is because we
-    // want to consider into the screen as INCREASING distance.
-    return -( coord[0]*matrix(0,2) + coord[1]*matrix(1,2) +
-              coord[2]*matrix(2,2) + matrix(3,2) );
-}
-
-#define CURRENT_CLASS DistanceAccumulator
-CURRENT_CLASS::CURRENT_CLASS()
-    : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), 
-      _nearFarRatio(0.0005), _maxDepth(UINT_MAX)
-{
-    setMatrices(osg::Matrix::identity(), osg::Matrix::identity());
-    reset();
-}
-
-CURRENT_CLASS::~CURRENT_CLASS() {}
-
-void CURRENT_CLASS::pushLocalFrustum()
-{
-    osg::Matrix& currMatrix = _viewMatrices.back();
-
-    // Compute the frustum in local space
-    osg::Polytope localFrustum;
-    localFrustum.setToUnitFrustum(false, false);
-    localFrustum.transformProvidingInverse(currMatrix*_projectionMatrices.back());
-    _localFrusta.push_back(localFrustum);
-
-    // Compute new bounding box corners
-    bbCornerPair corner;
-    corner.second = (currMatrix(0,2)<=0?1:0) |
-                    (currMatrix(1,2)<=0?2:0) |
-                    (currMatrix(2,2)<=0?4:0);
-    corner.first = (~corner.second)&7;
-    _bbCorners.push_back(corner);
-}
-
-void CURRENT_CLASS::pushDistancePair(double zNear, double zFar)
-{
-    if(zFar > 0.0) // Make sure some of drawable is visible
-    {
-      // Make sure near plane is in front of viewpoint.
-      if(zNear <= 0.0)
-      {
-        zNear = zFar*_nearFarRatio;
-        if(zNear >= 1.0) zNear = 1.0; // 1.0 limit chosen arbitrarily!
-      }
-
-      // Add distance pair for current drawable
-      _distancePairs.push_back(DistancePair(zNear, zFar));
-
-      // Override the current nearest/farthest planes if necessary
-      if(zNear < _limits.first) _limits.first = zNear;
-      if(zFar > _limits.second) _limits.second = zFar;
-    }
-}
-
-/** Return true if the node should be traversed, and false if the bounding sphere
-    of the node is small enough to be rendered by one Camera. If the latter
-    is true, then store the node's near & far plane distances. */
-bool CURRENT_CLASS::shouldContinueTraversal(osg::Node &node)
-{
-    // Allow traversal to continue if we haven't reached maximum depth.
-    bool keepTraversing = (_currentDepth < _maxDepth);
-
-    osg::BoundingSphere bs = node.getBound();
-    double zNear = 0.0, zFar = 0.0;
-
-    // Make sure bounding sphere is valid
-    if(bs.valid())
-    {
-      // Make sure bounding sphere is within the viewing volume
-      if(!_localFrusta.back().contains(bs)) keepTraversing = false;
-
-      else // Compute near and far planes for this node
-      {
-        // Since the view matrix could involve complex transformations,
-        // we need to determine a new BoundingSphere that would encompass
-        // the transformed BoundingSphere.
-        const osg::Matrix &l2w = _viewMatrices.back();
-
-        // Get the transformed x-axis of the BoundingSphere
-        osg::Vec3d newX = bs._center;
-        newX.x() += bs._radius; // Get X-edge of bounding sphere
-        newX = newX * l2w;
-
-        // Get the transformed y-axis of the BoundingSphere
-        osg::Vec3d newY = bs._center;
-        newY.y() += bs._radius; // Get Y-edge of bounding sphere
-        newY = newY * l2w;
-
-        // Get the transformed z-axis of the BoundingSphere
-        osg::Vec3d newZ = bs._center;
-        newZ.z() += bs._radius; // Get Z-edge of bounding sphere
-        newZ = newZ * l2w;
-
-        // Get the transformed center of the BoundingSphere
-        bs._center = bs._center * l2w;
-
-        // Compute lengths of transformed x, y, and z axes
-        double newXLen = (newX - bs._center).length();
-        double newYLen = (newY - bs._center).length();
-        double newZLen = (newZ - bs._center).length();
-
-        // The encompassing radius is the max of the transformed lengths
-        bs._radius = newXLen;
-        if(newYLen > bs._radius) bs._radius = newYLen;
-        if(newZLen > bs._radius) bs._radius = newZLen;
-
-        // Now we can compute the near & far planes, noting that for
-        // complex view transformations (ie. involving scales) the new
-        // BoundingSphere may be bigger than the original one.
-        // Note that the negative sign on the bounding sphere center is
-        // because we want distance to increase INTO the screen.
-        zNear = -bs._center.z() - bs._radius;
-        zFar = -bs._center.z() + bs._radius;
-
-        // If near/far ratio is big enough, then we don't need to keep
-        // traversing children of this node.
-        if(zNear >= zFar*_nearFarRatio) keepTraversing = false;
-      }
-    }
-
-    // If traversal should stop, then store this node's (near,far) pair
-    if(!keepTraversing) pushDistancePair(zNear, zFar);
-
-    return keepTraversing;
-}
-
-void CURRENT_CLASS::apply(osg::Node &node)
-{
-    if(shouldContinueTraversal(node))
-    {
-      // Traverse this node
-      ++_currentDepth;
-      traverse(node);
-      --_currentDepth;
-    }
-}
-
-void CURRENT_CLASS::apply(osg::Projection &proj)
-{
-    if(shouldContinueTraversal(proj))
-    {
-      // Push the new projection matrix view frustum
-      _projectionMatrices.push_back(proj.getMatrix());
-      pushLocalFrustum();
-
-      // Traverse the group
-      ++_currentDepth;
-      traverse(proj);
-      --_currentDepth;
-
-      // Reload original matrix and frustum
-      _localFrusta.pop_back();
-      _bbCorners.pop_back();
-      _projectionMatrices.pop_back();
-    }
-}
-
-void CURRENT_CLASS::apply(osg::Transform &transform)
-{
-    if(shouldContinueTraversal(transform))
-    {
-      // Compute transform for current node
-      osg::Matrix currMatrix = _viewMatrices.back();
-      bool pushMatrix = transform.computeLocalToWorldMatrix(currMatrix, this);
-
-      if(pushMatrix) 
-      {
-        // Store the new modelview matrix and view frustum
-        _viewMatrices.push_back(currMatrix);
-        pushLocalFrustum();
-      }
-
-      ++_currentDepth;
-      traverse(transform);
-      --_currentDepth;
-
-      if(pushMatrix) 
-      {
-        // Restore the old modelview matrix and view frustum
-        _localFrusta.pop_back();
-        _bbCorners.pop_back();
-        _viewMatrices.pop_back();
-      }
-    }
-}
-
-void CURRENT_CLASS::apply(osg::Geode &geode)
-{
-    // Contained drawables will only be individually considered if we are
-    // allowed to continue traversing.
-    if(shouldContinueTraversal(geode))
-    {
-      osg::Drawable *drawable;
-      double zNear, zFar;
-
-      // Handle each drawable in this geode
-      for(unsigned int i = 0; i < geode.getNumDrawables(); ++i)
-      {
-        drawable = geode.getDrawable(i);
-
-        const osg::BoundingBox &bb = drawable->getBound();
-        if(bb.valid())
-        {
-          // Make sure drawable will be visible in the scene
-          if(!_localFrusta.back().contains(bb)) continue;
-
-          // Compute near/far distances for current drawable
-          zNear = distance(bb.corner(_bbCorners.back().first), 
-                               _viewMatrices.back());
-          zFar = distance(bb.corner(_bbCorners.back().second), 
-                          _viewMatrices.back());
-          if(zNear > zFar) std::swap(zNear, zFar);
-          pushDistancePair(zNear, zFar);
-        }
-      }
-    }
-}
-
-void CURRENT_CLASS::setMatrices(const osg::Matrix &modelview,
-                                const osg::Matrix &projection)
-{
-    _modelview = modelview;
-    _projection = projection;
-}
-
-void CURRENT_CLASS::reset()
-{
-    // Clear vectors & values
-    _distancePairs.clear();
-    _cameraPairs.clear();
-    _limits.first = DBL_MAX;
-    _limits.second = 0.0;
-    _currentDepth = 0;
-
-    // Initial transform matrix is the modelview matrix
-    _viewMatrices.clear();
-    _viewMatrices.push_back(_modelview);
-
-    // Set the initial projection matrix
-    _projectionMatrices.clear();
-    _projectionMatrices.push_back(_projection);
-
-    // Create a frustum without near/far planes, for cull computations
-    _localFrusta.clear();
-    _bbCorners.clear();
-    pushLocalFrustum();
-}
-
-void CURRENT_CLASS::computeCameraPairs()
-{
-    // Nothing in the scene, so no cameras needed
-    if(_distancePairs.empty()) return;
-
-    // Entire scene can be handled by just one camera
-    if(_limits.first >= _limits.second*_nearFarRatio)
-    {
-      _cameraPairs.push_back(_limits);
-      return;
-    }
-
-    PairList::iterator i,j;
-
-    // Sort the list of distance pairs by descending far distance
-    std::sort(_distancePairs.begin(), _distancePairs.end(), precedes);
-
-    // Combine overlapping distance pairs. The resulting set of distance
-    // pairs (called combined pairs) will not overlap.
-    PairList combinedPairs;
-    DistancePair currPair = _distancePairs.front();
-    for(i = _distancePairs.begin(); i != _distancePairs.end(); ++i)
-    {
-      // Current distance pair does not overlap current combined pair, so
-      // save the current combined pair and start a new one.
-      if(i->second < 0.99*currPair.first)
-      {
-        combinedPairs.push_back(currPair);
-        currPair = *i;
-      }
-
-      // Current distance pair overlaps current combined pair, so expand
-      // current combined pair to encompass distance pair.
-      else
-        currPair.first = std::min(i->first, currPair.first);
-    }
-    combinedPairs.push_back(currPair); // Add last pair
-
-    // Compute the (near,far) distance pairs for each camera.
-    // Each of these distance pairs is called a "view segment".
-    double currNearLimit, numSegs, new_ratio;
-    double ratio_invlog = 1.0/log(_nearFarRatio);
-    unsigned int temp;
-    for(i = combinedPairs.begin(); i != combinedPairs.end(); ++i)
-    {
-      currPair = *i; // Save current view segment
-
-      // Compute the fractional number of view segments needed to span
-      // the current combined distance pair.
-      currNearLimit = currPair.second*_nearFarRatio;
-      if(currPair.first >= currNearLimit) numSegs = 1.0;
-      else 
-      {
-        numSegs = log(currPair.first/currPair.second)*ratio_invlog;
-
-        // Compute the near plane of the last view segment
-        //currNearLimit *= pow(_nearFarRatio, -floor(-numSegs) - 1);
-        for(temp = (unsigned int)(-floor(-numSegs)); temp > 1; temp--)
-        {
-          currNearLimit *= _nearFarRatio;
-        }
-      }
-
-      // See if the closest view segment can absorb other combined pairs
-      for(j = i+1; j != combinedPairs.end(); ++j)
-      {
-        // No other distance pairs can be included
-        if(j->first < currNearLimit) break;
-      }
-
-      // If we did absorb another combined distance pair, recompute the
-      // number of required view segments.
-      if(i != j-1)
-      {
-        i = j-1;
-        currPair.first = i->first;
-        if(currPair.first >= currPair.second*_nearFarRatio) numSegs = 1.0;
-        else numSegs = log(currPair.first/currPair.second)*ratio_invlog;
-      }
-
-      /* Compute an integer number of segments by rounding the fractional
-         number of segments according to how many segments there are.
-         In general, the more segments there are, the more likely that the 
-         integer number of segments will be rounded down.
-         The purpose of this is to try to minimize the number of view segments
-         that are used to render any section of the scene without violating
-         the specified _nearFarRatio by too much. */
-      if(numSegs < 10.0) numSegs = floor(numSegs + 1.0 - 0.1*floor(numSegs));
-      else numSegs = floor(numSegs);
-
-
-      // Compute the near/far ratio that will be used for each view segment
-      // in this section of the scene.
-      new_ratio = pow(currPair.first/currPair.second, 1.0/numSegs);
-
-      // Add numSegs new view segments to the camera pairs list
-      for(temp = (unsigned int)numSegs; temp > 0; temp--)
-      {
-        currPair.first = currPair.second*new_ratio;
-        _cameraPairs.push_back(currPair);
-        currPair.second = currPair.first;
-      }
-    }
-}
-
-void CURRENT_CLASS::setNearFarRatio(double ratio)
-{
-    if(ratio <= 0.0 || ratio >= 1.0) return;
-    _nearFarRatio = ratio;
-}
-#undef CURRENT_CLASS
