OpenSceneGraph/include/osg/CullStack
Robert Osfield 12226e4371 Converted the instances of const built in types being returned from methods
and passed as paramters into straight forward non const built in types,
i.e. const bool foogbar(const int) becomes bool foobar(int).
2002-09-02 12:31:35 +00:00

302 lines
9.4 KiB
Plaintext

//C++ header - Open Scene Graph - Copyright (C) 1998-2002 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 = 0x0,
VIEW_FRUSTUM_CULLING = 0x1,
NEAR_PLANE_CULLING = 0x2,
FAR_PLANE_CULLING = 0x4,
SMALL_FEATURE_CULLING = 0x8,
SHADOW_OCCLUSION_CULLING = 0x10,
ENABLE_ALL_CULLING = VIEW_FRUSTUM_CULLING|
SMALL_FEATURE_CULLING|
SHADOW_OCCLUSION_CULLING
};
typedef unsigned int CullingMode;
void reset();
void setOccluderList(const ShadowVolumeOccluderList& svol) { _occluderList = svol; }
ShadowVolumeOccluderList& getOccluderList() { return _occluderList; }
const ShadowVolumeOccluderList& getOccluderList() const { return _occluderList; }
void pushViewport(osg::Viewport* viewport);
void popViewport();
void pushProjectionMatrix(osg::Matrix* matrix);
void popProjectionMatrix();
void pushModelViewMatrix(osg::Matrix* matrix);
void popModelViewMatrix();
inline float getFrustumVolume() { if (_frustumVolume<0.0f) computeFrustumVolume(); return _frustumVolume; }
/** Sets the current CullingMode.*/
void setCullingMode(CullingMode mode) { _cullingMode = mode; }
/** Returns the current CullingMode.*/
CullingMode getCullingMode() const { return _cullingMode; }
void setLODBias(float bias) { _LODBias = bias; }
float getLODBias() const { return _LODBias; }
void setSmallFeatureCullingPixelSize(float value) { _smallFeatureCullingPixelSize=value; }
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 disableAndPushOccludersCurrentMask(NodePath& nodePath)
{
_modelviewCullingStack.back()->disableAndPushOccludersCurrentMask(nodePath);
}
inline void popOccludersCurrentMask(NodePath& nodePath)
{
_modelviewCullingStack.back()->popOccludersCurrentMask(nodePath);
}
inline bool isCulled(const std::vector<Vec3>& vertices)
{
return _modelviewCullingStack.back()->isCulled(vertices);
}
inline bool isCulled(const BoundingBox& bb)
{
return bb.valid() && _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();
}
typedef fast_back_stack<ref_ptr<CullingSet> > CullingStack;
CullingStack& getClipSpaceCullingStack() { return _clipspaceCullingStack; }
CullingStack& getProjectionCullingStack() { return _projectionCullingStack; }
CullingStack& getModelViewCullingStack() { return _modelviewCullingStack; }
CullingSet& getCurrentCullingSet() { return *_modelviewCullingStack.back(); }
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 _LODBias;
float _smallFeatureCullingPixelSize;
// base set of shadow volume occluder to use in culling.
ShadowVolumeOccluderList _occluderList;
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;
CullingStack _clipspaceCullingStack;
CullingStack _projectionCullingStack;
CullingStack _modelviewCullingStack;
void computeFrustumVolume();
float _frustumVolume;
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