Created new helper class osg::CullStack to handle the accumulation of projection,

modelview and culling sets, to be used during travesal of the scene graph, such
as the cull traversal.
This commit is contained in:
Robert Osfield
2002-06-10 11:21:21 +00:00
parent d91b848a63
commit 348419219d
9 changed files with 500 additions and 452 deletions

View File

@@ -149,6 +149,10 @@ SOURCE=..\..\src\osg\CullFace.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\CullStack.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\CullingSet.cpp
# End Source File
# Begin Source File
@@ -433,6 +437,10 @@ SOURCE=..\..\Include\Osg\CullFace
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\CullStack
# End Source File
# Begin Source File
SOURCE=..\..\Include\Osg\CullingSet
# End Source File
# Begin Source File

260
include/osg/CullStack Normal file
View File

@@ -0,0 +1,260 @@
//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_CULLSTACK
#define OSG_CULLSTACK 1
#include <osg/CullingSet>
#include <osg/Viewport>
#include <osg/fast_back_stack>
#include <osg/Notify>
namespace osg {
/** A CullStack class which accumulates the current project, modelview matrices
and the CullingSet. */
class SG_EXPORT CullStack
{
public:
CullStack();
~CullStack();
typedef std::vector<ShadowVolumeOccluder> OccluderList;
enum CullingModeValues
{
NO_CULLING = 0x00,
VIEW_FRUSTUM_CULLING = 0x1,
SMALL_FEATURE_CULLING = 0x2,
SHADOW_OCCLUSION_CULLING = 0x4,
ENABLE_ALL_CULLING = 0xffffffff
};
typedef unsigned int CullingMode;
/** Sets the current CullingMode.*/
void setCullingMode(CullingMode mode) { _cullingMode = mode; }
/** Returns the current CullingMode.*/
CullingMode getCullingMode() const { return _cullingMode; }
void reset();
void pushViewport(osg::Viewport* viewport);
void popViewport();
void pushProjectionMatrix(osg::Matrix* matrix);
void popProjectionMatrix();
void pushModelViewMatrix(osg::Matrix* matrix);
void popModelViewMatrix();
void setSmallFeatureCullingPixelSize(float value) { _smallFeatureCullingPixelSize=value; }
float& getSmallFeatureCullingPixelSize() { return _smallFeatureCullingPixelSize; }
float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; }
/** Compute the pixel of an object at position v, with specified radius.*/
float pixelSize(const Vec3& v,float radius) const
{
return _modelviewCullingStack.back()->pixelSize(v,radius);
}
/** Compute the pixel of an bounding sphere.*/
float pixelSize(const BoundingSphere& bs) const
{
return pixelSize(bs.center(),bs.radius());
}
inline void disableOccluder(NodePath& nodePath)
{
_modelviewCullingStack.back()->disableOccluder(nodePath);
}
inline bool isCulled(const BoundingBox& bb)
{
return bb.isValid() && _modelviewCullingStack.back()->isCulled(bb);
}
inline bool isCulled(const BoundingSphere& bs)
{
return _modelviewCullingStack.back()->isCulled(bs);
}
inline bool isCulled(const osg::Node& node)
{
return node.isCullingActive() && _modelviewCullingStack.back()->isCulled(node.getBound());
}
inline void pushCurrentMask()
{
_modelviewCullingStack.back()->pushCurrentMask();
}
inline void popCurrentMask()
{
_modelviewCullingStack.back()->popCurrentMask();
}
inline osg::Viewport* getViewport();
inline osg::Matrix& getModelViewMatrix();
inline osg::Matrix& getProjectionMatrix();
inline const osg::Matrix getWindowMatrix();
inline const osg::Matrix& getMVPW();
inline const osg::Vec3& getEyeLocal() const { return _eyePointStack.back(); }
inline const osg::Vec3 getUpLocal() const
{
const osg::Matrix& matrix = *_modelviewStack.back();
return osg::Vec3(matrix(0,1),matrix(1,1),matrix(2,1));
}
inline const osg::Vec3 getLookVectorLocal() const
{
const osg::Matrix& matrix = *_modelviewStack.back();
return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2));
}
protected:
void pushCullingSet();
void popCullingSet();
CullingMode _cullingMode;
float _smallFeatureCullingPixelSize;
typedef fast_back_stack< ref_ptr<Matrix> > MatrixStack;
MatrixStack _projectionStack;
MatrixStack _modelviewStack;
MatrixStack _MVPW_Stack;
typedef fast_back_stack<ref_ptr<Viewport> > ViewportStack;
ViewportStack _viewportStack;
typedef fast_back_stack<Vec3> EyePointStack;
EyePointStack _eyePointStack;
typedef fast_back_stack<ref_ptr<CullingSet> > CullingStack;
CullingStack _clipspaceCullingStack;
CullingStack _projectionCullingStack;
CullingStack _modelviewCullingStack;
unsigned int _bbCornerNear;
unsigned int _bbCornerFar;
osg::Matrix _identity;
typedef std::vector< osg::ref_ptr<osg::Matrix> > MatrixList;
MatrixList _reuseMatrixList;
unsigned int _currentReuseMatrixIndex;
inline osg::Matrix* createOrReuseMatrix(const osg::Matrix& value);
};
inline osg::Viewport* CullStack::getViewport()
{
if (!_viewportStack.empty())
{
return _viewportStack.back().get();
}
else
{
return 0L;
}
}
inline osg::Matrix& CullStack::getModelViewMatrix()
{
if (!_modelviewStack.empty())
{
return *_modelviewStack.back();
}
else
{
return _identity;
}
}
inline osg::Matrix& CullStack::getProjectionMatrix()
{
if (!_projectionStack.empty())
{
return *_projectionStack.back();
}
else
{
return _identity;
}
}
inline const osg::Matrix CullStack::getWindowMatrix()
{
if (!_viewportStack.empty())
{
osg::Viewport* viewport = _viewportStack.back().get();
return viewport->computeWindowMatrix();
}
else
{
return _identity;
}
}
inline const osg::Matrix& CullStack::getMVPW()
{
if (!_MVPW_Stack.empty())
{
if (!_MVPW_Stack.back())
{
_MVPW_Stack.back() = createOrReuseMatrix(getModelViewMatrix());
(*_MVPW_Stack.back()) *= getProjectionMatrix();
(*_MVPW_Stack.back()) *= getWindowMatrix();
}
return *_MVPW_Stack.back();
}
else
{
return _identity;
}
}
inline Matrix* CullStack::createOrReuseMatrix(const osg::Matrix& value)
{
// skip of any already reused matrix.
while (_currentReuseMatrixIndex<_reuseMatrixList.size() &&
_reuseMatrixList[_currentReuseMatrixIndex]->referenceCount()>1)
{
notify(osg::NOTICE)<<"Warning:createOrReuseMatrix() skipping multiply refrenced entry."<< std::endl;
++_currentReuseMatrixIndex;
}
// if still within list, element must be singularly referenced
// there return it to be reused.
if (_currentReuseMatrixIndex<_reuseMatrixList.size())
{
Matrix* matrix = _reuseMatrixList[_currentReuseMatrixIndex++].get();
matrix->set(value);
return matrix;
}
// otherwise need to create new matrix.
osg::Matrix* matrix = osgNew Matrix(value);
_reuseMatrixList.push_back(matrix);
++_currentReuseMatrixIndex;
return matrix;
}
} // end of namespace
#endif

View File

@@ -21,12 +21,12 @@ class SG_EXPORT CullingSet : public Referenced
CullingSet();
CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector):
_mask(cs._mask),
_clippingVolume(cs._clippingVolume),
_frustum(cs._frustum),
_occluderList(cs._occluderList),
_pixelSizeVector(pixelSizeVector),
_smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
{
_clippingVolume.transformProvidingInverse(matrix);
_frustum.transformProvidingInverse(matrix);
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
@@ -37,7 +37,7 @@ class SG_EXPORT CullingSet : public Referenced
~CullingSet();
typedef std::vector<ShadowOccluderVolume> OccluderList;
typedef std::vector<ShadowVolumeOccluder> OccluderList;
typedef unsigned int Mask;
@@ -51,12 +51,12 @@ class SG_EXPORT CullingSet : public Referenced
void setCullingMask(Mask mask) { _mask = mask; }
void setFrustum(Polytope& cv) { _clippingVolume = cv; }
void setFrustum(Polytope& cv) { _frustum = cv; }
Polytope& getFrustum() { return _clippingVolume; }
const Polytope& getFrustum() const { return _clippingVolume; }
Polytope& getFrustum() { return _frustum; }
const Polytope& getFrustum() const { return _frustum; }
void addOccluder(ShadowOccluderVolume& cv) { _occluderList.push_back(cv); }
void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); }
void setPixelSizeVector(const Vec4& v) { _pixelSizeVector = v; }
@@ -99,7 +99,7 @@ class SG_EXPORT CullingSet : public Referenced
if (_mask&VIEW_FRUSTUM_CULLING)
{
// is it outside the view frustum...
if (!_clippingVolume.contains(bb)) return true;
if (!_frustum.contains(bb)) return true;
}
if (_mask&SMALL_FEATURE_CULLING)
@@ -128,7 +128,7 @@ class SG_EXPORT CullingSet : public Referenced
if (_mask&VIEW_FRUSTUM_CULLING)
{
// is it outside the view frustum...
if (!_clippingVolume.contains(bs)) return true;
if (!_frustum.contains(bs)) return true;
}
if (_mask&SMALL_FEATURE_CULLING)
@@ -155,7 +155,7 @@ class SG_EXPORT CullingSet : public Referenced
inline void pushCurrentMask()
{
_clippingVolume.pushCurrentMask();
_frustum.pushCurrentMask();
if (!_occluderList.empty())
{
@@ -170,7 +170,7 @@ class SG_EXPORT CullingSet : public Referenced
inline void popCurrentMask()
{
_clippingVolume.popCurrentMask();
_frustum.popCurrentMask();
if (!_occluderList.empty())
{
@@ -187,7 +187,7 @@ class SG_EXPORT CullingSet : public Referenced
protected:
Mask _mask;
Polytope _clippingVolume;
Polytope _frustum;
OccluderList _occluderList;
Vec4 _pixelSizeVector;
float _smallFeatureCullingPixelSize;

View File

@@ -2,8 +2,8 @@
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_SHADOWOCCLUDERVOLUME
#define OSG_SHADOWOCCLUDERVOLUME 1
#ifndef OSG_SHADOWVOLUMEOCCLUDER
#define OSG_SHADOWVOLUMEOCCLUDER 1
#include <osg/ref_ptr>
#include <osg/Polytope>
@@ -12,8 +12,8 @@
namespace osg {
/** ShadowOccluderVolume is a helper class for implementating shadow occlusion culling. */
class SG_EXPORT ShadowOccluderVolume
/** ShadowVolumeOccluder is a helper class for implementating shadow occlusion culling. */
class SG_EXPORT ShadowVolumeOccluder
{
public:
@@ -21,15 +21,21 @@ class SG_EXPORT ShadowOccluderVolume
typedef std::vector<Polytope> HoleList;
ShadowOccluderVolume(const ShadowOccluderVolume& soc):
ShadowVolumeOccluder(const ShadowVolumeOccluder& soc):
_quality(soc._quality),
_nodePath(soc._nodePath),
_occluderVolume(soc._occluderVolume),
_holeList(soc._holeList) {}
ShadowOccluderVolume(const ShadowOccluderVolume& soc,Matrix& MVP);
ShadowOccluderVolume(const ConvexPlanerOccluder& occluder,Matrix& MVP);
ShadowVolumeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MVP)
{
computeOccluder(nodePath,occluder,MVP);
}
/** compute the shadow volume occluder. */
void computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MVP);
inline void disableResultMasks();
inline void pushCurrentMask();
@@ -41,15 +47,8 @@ class SG_EXPORT ShadowOccluderVolume
inline NodePath& getNodePath() { return _nodePath; }
inline const NodePath& getNodePath() const { return _nodePath; }
float quality() { return _quality; }
/** Convert shadow occluder into local coords by multiplying the
* clip space occluder by the ModelViewProjectionMatrix.*/
void set(const ShadowOccluderVolume& soc,Matrix& MVP);
/** Initialize a ShadowOccluderVolume to a ConvexPlanerOccluder
* transformed into clipspace.*/
void set(const ConvexPlanerOccluder& occluder,Matrix& MVP);
/** return true if the specified bounding sphere is contaned entirely
* within this shadow occluder volume.*/
bool contains(const BoundingSphere& bound);
@@ -72,12 +71,13 @@ class SG_EXPORT ShadowOccluderVolume
protected:
float _quality;
NodePath _nodePath;
Polytope _occluderVolume;
HoleList _holeList;
};
inline void ShadowOccluderVolume::disableResultMasks()
inline void ShadowVolumeOccluder::disableResultMasks()
{
_occluderVolume.setResultMask(0);
for(HoleList::iterator itr=_holeList.begin();
@@ -88,7 +88,7 @@ inline void ShadowOccluderVolume::disableResultMasks()
}
}
inline void ShadowOccluderVolume::pushCurrentMask()
inline void ShadowVolumeOccluder::pushCurrentMask()
{
_occluderVolume.pushCurrentMask();
if (!_holeList.empty())
@@ -102,7 +102,7 @@ inline void ShadowOccluderVolume::pushCurrentMask()
}
}
inline void ShadowOccluderVolume::popCurrentMask()
inline void ShadowVolumeOccluder::popCurrentMask()
{
_occluderVolume.popCurrentMask();
if (!_holeList.empty())

View File

@@ -17,8 +17,7 @@
#include <osg/Notify>
#include <osg/Notify>
#include <osg/CullingSet>
#include <osg/fast_back_stack>
#include <osg/CullStack>
#include <osgUtil/RenderGraph>
#include <osgUtil/RenderStage>
@@ -38,27 +37,10 @@ namespace osgUtil {
* transparent bin in rendered in order from the furthest osg::Drawable
* from the eye to the one nearest the eye.
*/
class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStack
{
public:
enum
{
NO_CULLING = 0x00,
FRUSTUM_LEFT_CULLING = 0x01,
FRUSTUM_RIGHT_CULLING = 0x02,
FRUSTUM_BOTTOM_CULLING = 0x04,
FRUSTUM_TOP_CULLING = 0x08,
FRUSTUM_NEAR_CULLING = 0x10,
FRUSTUM_FAR_CULLING = 0x20,
VIEW_FRUSTUM_CULLING = 0x3F,
SMALL_FEATURE_CULLING = 0x40,
ENABLE_ALL_CULLING = 0x7F
};
typedef unsigned int CullingMode;
CullVisitor();
virtual ~CullVisitor();
@@ -136,25 +118,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
};
void setTransparencySortMode(TransparencySortMode tsm) { _tsm = tsm; }
/** Sets the current CullingMode.*/
void setCullingMode(CullingMode mode);
/** Returns the current CullingMode.*/
CullingMode getCullingMode() const;
void setSmallFeatureCullingPixelSize(float s) { _smallFeatureCullingPixelSize=s; }
float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; }
void pushViewport(osg::Viewport* viewport);
void popViewport();
void pushProjectionMatrix(osg::Matrix* matrix);
void popProjectionMatrix();
void pushModelViewMatrix(osg::Matrix* matrix);
void popModelViewMatrix();
/** Push state set on the current state group.
* If the state exists in a child state group of the current
* state group then move the current state group to that child.
@@ -216,46 +179,10 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
return _currentRenderBin;
}
inline osg::Viewport* getViewport();
inline osg::Matrix& getModelViewMatrix();
inline osg::Matrix& getProjectionMatrix();
inline const osg::Matrix getWindowMatrix();
inline const osg::Matrix& getMVPW();
inline const osg::Vec3& getEyeLocal() const
{
return _eyePointStack.back();
}
inline const float getCalculatedNearPlane() const { return _computed_znear; }
inline const float getCalculatedFarPlane() const { return _computed_zfar; }
inline float pixelSize(const osg::Vec3& v, float const radius)
{
return _modelviewCullingStack.back()->pixelSize(v,radius);
}
inline bool isCulled(const osg::Node& node)
{
return node.isCullingActive() && _modelviewCullingStack.back()->isCulled(node.getBound());
}
inline const bool isCulled(const osg::BoundingBox& bb)
{
return bb.isValid() && _modelviewCullingStack.back()->isCulled(bb);
}
inline void pushCurrentMask()
{
_modelviewCullingStack.back()->pushCurrentMask();
}
inline void popCurrentMask()
{
_modelviewCullingStack.back()->popCurrentMask();
}
void updateCalculatedNearFar(const osg::Matrix& matrix,const osg::Drawable& drawable) { updateCalculatedNearFar(matrix,drawable.getBound()); }
void updateCalculatedNearFar(const osg::Matrix& matrix,const osg::BoundingBox& bb);
void updateCalculatedNearFar(const osg::Vec3& pos);
@@ -269,10 +196,13 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
/** Add an attribute which is positioned related to the modelview matrix.*/
inline void addPositionedAttribute(osg::Matrix* matrix,const osg::StateAttribute* attr);
/** reimplement CullStack's popProjectionMatrix() adding clamping of the projection matrix to the computed near and far.*/
void popProjectionMatrix();
protected:
/** prevent unwanted copy construction.*/
CullVisitor(const CullVisitor&):osg::NodeVisitor() {}
CullVisitor(const CullVisitor&):osg::NodeVisitor(),osg::CullStack() {}
/** prevent unwanted copy operator.*/
CullVisitor& operator = (const CullVisitor&) { return *this; }
@@ -291,61 +221,11 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
else acceptNode->accept(*this);
}
inline const osg::Vec3 getUpLocal() const
{
const osg::Matrix& matrix = *_modelviewStack.back();
return osg::Vec3(matrix(0,1),matrix(1,1),matrix(2,1));
}
inline const osg::Vec3 getLookVectorLocal() const
{
const osg::Matrix& matrix = *_modelviewStack.back();
return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2));
}
/** create an impostor sprite by setting up a pre-rendering stage
* to generate the impostor texture. */
osg::ImpostorSprite* createImpostorSprite(osg::Impostor& node);
void pushCullingSet();
void popCullingSet();
typedef osg::fast_back_stack<osg::Polytope> PolytopeStack;
typedef osg::fast_back_stack< osg::ref_ptr<osg::Matrix> > MatrixStack;
MatrixStack _projectionStack;
MatrixStack _PW_Stack;
MatrixStack _modelviewStack;
MatrixStack _MVPW_Stack;
typedef osg::fast_back_stack<osg::ref_ptr<osg::Viewport> > ViewportStack;
ViewportStack _viewportStack;
typedef osg::fast_back_stack<osg::Vec3> EyePointStack;
EyePointStack _eyePointStack;
CullingMode _cullingMode;
typedef osg::fast_back_stack<osg::ref_ptr<osg::CullingSet> > CullingStack;
CullingStack _clipspaceCullingStack;
CullingStack _projectionCullingStack;
CullingStack _modelviewCullingStack;
unsigned int _bbCornerNear;
unsigned int _bbCornerFar;
osg::Matrix _identity;
osg::ref_ptr<RenderGraph> _rootRenderGraph;
RenderGraph* _currentRenderGraph;
@@ -354,8 +234,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
float _LODBias;
float _smallFeatureCullingPixelSize;
ComputeNearFarMode _computeNearFar;
float _computed_znear;
@@ -370,11 +248,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
float _impostorPixelErrorThreshold;
int _numFramesToKeepImpostorSprites;
typedef std::vector< osg::ref_ptr<osg::Matrix> > MatrixList;
MatrixList _reuseMatrixList;
unsigned int _currentReuseMatrixIndex;
inline osg::Matrix* createOrReuseMatrix(const osg::Matrix& value);
typedef std::vector< osg::ref_ptr<RenderLeaf> > RenderLeafList;
RenderLeafList _reuseRenderLeafList;
@@ -386,75 +259,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
};
inline osg::Viewport* CullVisitor::getViewport()
{
if (!_viewportStack.empty())
{
return _viewportStack.back().get();
}
else
{
return 0L;
}
}
inline osg::Matrix& CullVisitor::getModelViewMatrix()
{
if (!_modelviewStack.empty())
{
return *_modelviewStack.back();
}
else
{
return _identity;
}
}
inline osg::Matrix& CullVisitor::getProjectionMatrix()
{
if (!_projectionStack.empty())
{
return *_projectionStack.back();
}
else
{
return _identity;
}
}
inline const osg::Matrix CullVisitor::getWindowMatrix()
{
if (!_viewportStack.empty())
{
osg::Viewport* viewport = _viewportStack.back().get();
return viewport->computeWindowMatrix();
}
else
{
return _identity;
}
}
inline const osg::Matrix& CullVisitor::getMVPW()
{
if (!_MVPW_Stack.empty())
{
if (!_MVPW_Stack.back())
{
_MVPW_Stack.back() = createOrReuseMatrix(getModelViewMatrix());
(*_MVPW_Stack.back()) *= getProjectionMatrix();
(*_MVPW_Stack.back()) *= getWindowMatrix();
}
return *_MVPW_Stack.back();
}
else
{
return _identity;
}
}
inline void CullVisitor::addDrawable(osg::Drawable* drawable,osg::Matrix* matrix)
{
if (_currentRenderGraph->leaves_empty())
@@ -488,32 +292,6 @@ inline void CullVisitor::addPositionedAttribute(osg::Matrix* matrix,const osg::S
_currentRenderBin->_stage->addPositionedAttribute(matrix,attr);
}
inline osg::Matrix* CullVisitor::createOrReuseMatrix(const osg::Matrix& value)
{
// skip of any already reused matrix.
while (_currentReuseMatrixIndex<_reuseMatrixList.size() &&
_reuseMatrixList[_currentReuseMatrixIndex]->referenceCount()>1)
{
osg::notify(osg::NOTICE)<<"Warning:createOrReuseMatrix() skipping multiply refrenced entry."<< std::endl;
++_currentReuseMatrixIndex;
}
// if still within list, element must be singularly referenced
// there return it to be reused.
if (_currentReuseMatrixIndex<_reuseMatrixList.size())
{
osg::Matrix* matrix = _reuseMatrixList[_currentReuseMatrixIndex++].get();
matrix->set(value);
return matrix;
}
// otherwise need to create new matrix.
osg::Matrix* matrix = new osg::Matrix(value);
_reuseMatrixList.push_back(matrix);
++_currentReuseMatrixIndex;
return matrix;
}
inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable,osg::Matrix* projection,osg::Matrix* matrix, float depth)
{
// skip of any already reused renderleaf.
@@ -541,7 +319,6 @@ inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable,
}
}
#endif

187
src/osg/CullStack.cpp Normal file
View File

@@ -0,0 +1,187 @@
#include <osg/CullStack>
using namespace osg;
CullStack::CullStack()
{
_cullingMode = ENABLE_ALL_CULLING;
_smallFeatureCullingPixelSize = 3.0f;
}
CullStack::~CullStack()
{
reset();
}
void CullStack::reset()
{
//
// first unref all referenced objects and then empty the containers.
//
_projectionStack.clear();
_modelviewStack.clear();
_viewportStack.clear();
_eyePointStack.clear();
_clipspaceCullingStack.clear();
_projectionCullingStack.clear();
_modelviewCullingStack.clear();
osg::Vec3 lookVector(0.0,0.0,-1.0);
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
}
void CullStack::pushCullingSet()
{
_MVPW_Stack.push_back(0L);
if (_modelviewStack.empty())
{
_modelviewCullingStack.push_back(_projectionCullingStack.back());
}
else
{
const osg::Viewport& W = *_viewportStack.back();
const osg::Matrix& P = *_projectionStack.back();
const osg::Matrix& M = *_modelviewStack.back();
// pre adjust P00,P20,P23,P33 by multiplying them by the viewport window matrix.
// here we do it in short hand with the knowledge of how the window matrix is formed
// note P23,P33 are multiplied by an implicit 1 which would come from the window matrix.
// Robert Osfield, June 2002.
float P00 = P(0,0)*W.width()*0.5f;
float P20 = P(2,0)*W.width()*0.5f + P(2,3)*W.width()*0.5f;
osg::Vec3 scale(M(0,0)*P00 + M(0,2)*P20,
M(1,0)*P00 + M(1,2)*P20,
M(2,0)*P00 + M(2,2)*P20);
float P23 = P(2,3);
float P33 = P(3,3);
osg::Vec4 pixelSizeVector2(M(0,2)*P23,
M(1,2)*P23,
M(2,2)*P23,
M(3,2)*P23 + M(3,3)*P33);
pixelSizeVector2 /= scale.length();
//cout << "pixelSizeVector = "<<pixelSizeVector<<" pixelSizeVector2="<<pixelSizeVector2<<endl;
_modelviewCullingStack.push_back(osgNew osg::CullingSet(*_projectionCullingStack.back(),*_modelviewStack.back(),pixelSizeVector2));
}
}
void CullStack::popCullingSet()
{
_MVPW_Stack.pop_back();
_modelviewCullingStack.pop_back();
}
void CullStack::pushViewport(osg::Viewport* viewport)
{
_viewportStack.push_back(viewport);
_MVPW_Stack.push_back(0L);
}
void CullStack::popViewport()
{
_viewportStack.pop_back();
_MVPW_Stack.pop_back();
}
void CullStack::pushProjectionMatrix(Matrix* matrix)
{
_projectionStack.push_back(matrix);
osg::CullingSet* cullingSet = osgNew osg::CullingSet();
cullingSet->getFrustum().setToUnitFrustumWithoutNearFar();
cullingSet->getFrustum().transformProvidingInverse(*matrix);
cullingSet->setSmallFeatureCullingPixelSize(_smallFeatureCullingPixelSize);
_projectionCullingStack.push_back(cullingSet);
//_projectionCullingStack.push_back(osgNew osg::CullingSet(*_clipspaceCullingStack.back(),*matrix));
pushCullingSet();
}
void CullStack::popProjectionMatrix()
{
_projectionStack.pop_back();
_projectionCullingStack.pop_back();
popCullingSet();
}
void CullStack::pushModelViewMatrix(Matrix* matrix)
{
_modelviewStack.push_back(matrix);
pushCullingSet();
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
const float x_0 = (*matrix)(0,0);
const float x_1 = (*matrix)(1,0);
const float x_2 = (*matrix)(2,0);
const float x_scale = (*matrix)(3,0) / -(x_0*x_0+x_1*x_1+x_2*x_2);
const float y_0 = (*matrix)(0,1);
const float y_1 = (*matrix)(1,1);
const float y_2 = (*matrix)(2,1);
const float y_scale = (*matrix)(3,1) / -(y_0*y_0+y_1*y_1+y_2*y_2);
const float z_0 = (*matrix)(0,2);
const float z_1 = (*matrix)(1,2);
const float z_2 = (*matrix)(2,2);
const float z_scale = (*matrix)(3,2) / -(z_0*z_0+z_1*z_1+z_2*z_2);
_eyePointStack.push_back(osg::Vec3(x_0*x_scale + y_0*y_scale + z_0*z_scale,
x_1*x_scale + y_1*y_scale + z_1*z_scale,
x_2*x_scale + y_2*y_scale + z_2*z_scale));
osg::Vec3 lookVector = getLookVectorLocal();
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
}
void CullStack::popModelViewMatrix()
{
_modelviewStack.pop_back();
_eyePointStack.pop_back();
popCullingSet();
osg::Vec3 lookVector(0.0f,0.0f,-1.0f);
if (!_modelviewStack.empty())
{
lookVector = getLookVectorLocal();
}
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
}

View File

@@ -17,6 +17,7 @@ CXXFILES =\
CopyOp.cpp\
CullFace.cpp\
CullingSet.cpp\
CullStack.cpp\
Depth.cpp\
DisplaySettings.cpp\
Drawable.cpp\

View File

@@ -3,27 +3,11 @@
using namespace osg;
ShadowOccluderVolume::ShadowOccluderVolume(const ShadowOccluderVolume& soc,Matrix& MVP)
void ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MVP)
{
set(soc,MVP);
}
ShadowOccluderVolume::ShadowOccluderVolume(const ConvexPlanerOccluder& occluder,Matrix& MVP)
{
set(occluder,MVP);
}
void ShadowOccluderVolume::set(const ShadowOccluderVolume& soc,Matrix& MVP)
{
}
void ShadowOccluderVolume::set(const ConvexPlanerOccluder& occluder,Matrix& MVP)
{
}
bool ShadowOccluderVolume::contains(const BoundingSphere& bound)
bool ShadowVolumeOccluder::contains(const BoundingSphere& bound)
{
if (_occluderVolume.containsAllOf(bound))
{
@@ -38,7 +22,7 @@ bool ShadowOccluderVolume::contains(const BoundingSphere& bound)
return false;
}
bool ShadowOccluderVolume::contains(const BoundingBox& bound)
bool ShadowVolumeOccluder::contains(const BoundingBox& bound)
{
if (_occluderVolume.containsAllOf(bound))
{

View File

@@ -84,10 +84,6 @@ CullVisitor::CullVisitor()
_LODBias = 1.0f;
_cullingMode = ENABLE_ALL_CULLING;
//_tsm = LOOK_VECTOR_DISTANCE;
_tsm = OBJECT_EYE_POINT_DISTANCE;
@@ -102,8 +98,6 @@ CullVisitor::CullVisitor()
_numFramesToKeepImpostorSprites = 10;
_impostorSpriteManager = osgNew ImpostorSpriteManager;
_smallFeatureCullingPixelSize = 3.0f;
}
@@ -119,15 +113,8 @@ void CullVisitor::reset()
//
// first unref all referenced objects and then empty the containers.
//
_projectionStack.clear();
_modelviewStack.clear();
_viewportStack.clear();
_eyePointStack.clear();
_clipspaceCullingStack.clear();
_projectionCullingStack.clear();
_modelviewCullingStack.clear();
CullStack::reset();
// reset the calculated near far planes.
_computed_znear = FLT_MAX;
@@ -155,91 +142,6 @@ void CullVisitor::reset()
}
void CullVisitor::pushCullingSet()
{
_MVPW_Stack.push_back(0L);
// const osg::Matrix& mvpw = getMVPW();
// float scale = osg::Vec3(mvpw(0,0),mvpw(1,0),mvpw(2,0)).length();
// Vec4 pixelSizeVector(mvpw(0,3),mvpw(1,3),mvpw(2,3),mvpw(3,3));
// if (scale>0.0f) pixelSizeVector /= scale;
if (_modelviewStack.empty())
{
_modelviewCullingStack.push_back(_projectionCullingStack.back());
}
else
{
const osg::Viewport& W = *_viewportStack.back();
const osg::Matrix& P = *_projectionStack.back();
const osg::Matrix& M = *_modelviewStack.back();
// pre adjust P00,P20,P23,P33 by multiplying them by the viewport window matrix.
// here we do it in short hand with the knowledge of how the window matrix is formed
// note P23,P33 are multiplied by an implicit 1 which would come from the window matrix.
// Robert Osfield, June 2002.
float P00 = P(0,0)*W.width()*0.5f;
float P20 = P(2,0)*W.width()*0.5f + P(2,3)*W.width()*0.5f;
osg::Vec3 scale(M(0,0)*P00 + M(0,2)*P20,
M(1,0)*P00 + M(1,2)*P20,
M(2,0)*P00 + M(2,2)*P20);
float P23 = P(2,3);
float P33 = P(3,3);
osg::Vec4 pixelSizeVector2(M(0,2)*P23,
M(1,2)*P23,
M(2,2)*P23,
M(3,2)*P23 + M(3,3)*P33);
pixelSizeVector2 /= scale.length();
//cout << "pixelSizeVector = "<<pixelSizeVector<<" pixelSizeVector2="<<pixelSizeVector2<<endl;
_modelviewCullingStack.push_back(osgNew osg::CullingSet(*_projectionCullingStack.back(),*_modelviewStack.back(),pixelSizeVector2));
}
}
void CullVisitor::popCullingSet()
{
_MVPW_Stack.pop_back();
_modelviewCullingStack.pop_back();
}
void CullVisitor::pushViewport(osg::Viewport* viewport)
{
_viewportStack.push_back(viewport);
_MVPW_Stack.push_back(0L);
}
void CullVisitor::popViewport()
{
_viewportStack.pop_back();
_MVPW_Stack.pop_back();
}
void CullVisitor::pushProjectionMatrix(Matrix* matrix)
{
_projectionStack.push_back(matrix);
osg::CullingSet* cullingSet = osgNew osg::CullingSet();
cullingSet->getFrustum().setToUnitFrustumWithoutNearFar();
cullingSet->getFrustum().transformProvidingInverse(*matrix);
cullingSet->setSmallFeatureCullingPixelSize(_smallFeatureCullingPixelSize);
_projectionCullingStack.push_back(cullingSet);
//_projectionCullingStack.push_back(osgNew osg::CullingSet(*_clipspaceCullingStack.back(),*matrix));
pushCullingSet();
}
void CullVisitor::popProjectionMatrix()
{
@@ -269,67 +171,7 @@ void CullVisitor::popProjectionMatrix()
0.0f,0.0f,center*ratio,1.0f));
}
_projectionStack.pop_back();
_projectionCullingStack.pop_back();
popCullingSet();
}
void CullVisitor::pushModelViewMatrix(Matrix* matrix)
{
_modelviewStack.push_back(matrix);
pushCullingSet();
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
const float x_0 = (*matrix)(0,0);
const float x_1 = (*matrix)(1,0);
const float x_2 = (*matrix)(2,0);
const float x_scale = (*matrix)(3,0) / -(x_0*x_0+x_1*x_1+x_2*x_2);
const float y_0 = (*matrix)(0,1);
const float y_1 = (*matrix)(1,1);
const float y_2 = (*matrix)(2,1);
const float y_scale = (*matrix)(3,1) / -(y_0*y_0+y_1*y_1+y_2*y_2);
const float z_0 = (*matrix)(0,2);
const float z_1 = (*matrix)(1,2);
const float z_2 = (*matrix)(2,2);
const float z_scale = (*matrix)(3,2) / -(z_0*z_0+z_1*z_1+z_2*z_2);
_eyePointStack.push_back(osg::Vec3(x_0*x_scale + y_0*y_scale + z_0*z_scale,
x_1*x_scale + y_1*y_scale + z_1*z_scale,
x_2*x_scale + y_2*y_scale + z_2*z_scale));
osg::Vec3 lookVector = getLookVectorLocal();
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
}
void CullVisitor::popModelViewMatrix()
{
_modelviewStack.pop_back();
_eyePointStack.pop_back();
popCullingSet();
osg::Vec3 lookVector(0.0f,0.0f,-1.0f);
if (!_modelviewStack.empty())
{
lookVector = getLookVectorLocal();
}
_bbCornerFar = (lookVector.x()>=0?1:0) |
(lookVector.y()>=0?2:0) |
(lookVector.z()>=0?4:0);
_bbCornerNear = (~_bbCornerFar)&7;
CullStack::popProjectionMatrix();
}
inline float distance(const osg::Vec3& coord,const osg::Matrix& matrix)
@@ -379,17 +221,6 @@ void CullVisitor::updateCalculatedNearFar(const osg::Vec3& pos)
if (d>_computed_zfar) _computed_zfar = d;
}
void CullVisitor::setCullingMode(CullingMode mode)
{
_cullingMode=mode;
}
CullVisitor::CullingMode CullVisitor::getCullingMode() const
{
return _cullingMode;
}
void CullVisitor::apply(Node& node)
{
if (isCulled(node)) return;
@@ -715,7 +546,7 @@ void CullVisitor::apply(osg::OccluderNode& node)
{
// need to check if occlusion node is in the occluder
// list, if so disable the appropriate ShadowOccluderVolume
_modelviewCullingStack.back()->disableOccluder(_nodePath);
disableOccluder(_nodePath);
std::cout<<"We are in an Occlusion node"<<&node<<std::endl;