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:
187
src/osg/CullStack.cpp
Normal file
187
src/osg/CullStack.cpp
Normal 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;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ CXXFILES =\
|
||||
CopyOp.cpp\
|
||||
CullFace.cpp\
|
||||
CullingSet.cpp\
|
||||
CullStack.cpp\
|
||||
Depth.cpp\
|
||||
DisplaySettings.cpp\
|
||||
Drawable.cpp\
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user