Simplified the osgdepthpartion example to use the osgView::View::setUpDepthPartition(..) feature
This commit is contained in:
parent
9aa7010ded
commit
ccfac57f20
@ -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 ###
|
#### end var setup ###
|
||||||
SETUP_EXAMPLE(osgdepthpartition)
|
SETUP_EXAMPLE(osgdepthpartition)
|
||||||
|
@ -1,272 +0,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
|
|
@ -1,105 +0,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
|
|
@ -1,402 +0,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
|
|
@ -1,115 +0,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
|
|
@ -24,10 +24,10 @@
|
|||||||
#include <osg/PositionAttitudeTransform>
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
|
||||||
#include <osgGA/TrackballManipulator>
|
#include <osgGA/TrackballManipulator>
|
||||||
|
#include <osgGA/StateSetManipulator>
|
||||||
|
|
||||||
#include <osgViewer/Viewer>
|
#include <osgViewer/Viewer>
|
||||||
|
#include <osgViewer/ViewerEventHandlers>
|
||||||
#include "DepthPartitionNode.h"
|
|
||||||
|
|
||||||
const double r_earth = 6378.137;
|
const double r_earth = 6378.137;
|
||||||
const double r_sun = 695990.0;
|
const double r_sun = 695990.0;
|
||||||
@ -132,6 +132,12 @@ int main( int argc, char **argv )
|
|||||||
// construct the viewer.
|
// construct the viewer.
|
||||||
osgViewer::Viewer viewer;
|
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;
|
bool needToSetHomePosition = false;
|
||||||
|
|
||||||
// read the scene from the list of file specified commandline args.
|
// read the scene from the list of file specified commandline args.
|
||||||
@ -143,24 +149,33 @@ int main( int argc, char **argv )
|
|||||||
scene = createScene();
|
scene = createScene();
|
||||||
needToSetHomePosition = true;
|
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.
|
// pass the loaded scene graph to the viewer.
|
||||||
viewer.setSceneData(dpn.get());
|
viewer.setSceneData(scene.get());
|
||||||
|
|
||||||
viewer.setCameraManipulator(new osgGA::TrackballManipulator);
|
viewer.setCameraManipulator(new osgGA::TrackballManipulator);
|
||||||
|
|
||||||
if (needToSetHomePosition)
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
// depth partion node is only supports single window/single threaded at present.
|
|
||||||
viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
|
||||||
|
|
||||||
return viewer.run();
|
return viewer.run();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user