Added computation of occluders volume scaled relative to the frustum volume,
all volumes computed in eye coords.
This commit is contained in:
@@ -31,6 +31,9 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C
|
||||
virtual void apply(osg::OccluderNode& node);
|
||||
|
||||
|
||||
void setMinimumShadowOccluderVolume(float vol) { _minimumShadowOccluderVolume = vol; }
|
||||
float getMinimumShadowOccluderVolume() const { return _minimumShadowOccluderVolume; }
|
||||
|
||||
void setCreateDrawablesOnOccludeNodes(bool flag) { _createDrawables=flag; }
|
||||
bool getCreateDrawablesOnOccludeNodes() const { return _createDrawables; }
|
||||
|
||||
@@ -47,15 +50,6 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C
|
||||
/** prevent unwanted copy operator.*/
|
||||
CollectOccludersVisitor& operator = (const CollectOccludersVisitor&) { return *this; }
|
||||
|
||||
bool _createDrawables;
|
||||
ShadowVolumeOccluderList _collectedOccluderList;
|
||||
|
||||
inline void handle_callbacks_and_traverse(osg::Node& node)
|
||||
{
|
||||
osg::NodeCallback* callback = node.getAppCallback();
|
||||
if (callback) (*callback)(&node,this);
|
||||
else if (node.getNumChildrenRequiringAppTraversal()>0) traverse(node);
|
||||
}
|
||||
inline void handle_cull_callbacks_and_traverse(osg::Node& node)
|
||||
{
|
||||
/*osg::NodeCallback* callback = node.getCullCallback();
|
||||
@@ -69,6 +63,11 @@ class SG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::C
|
||||
if (callback) (*callback)(&node,this);
|
||||
else*/ if (node.getNumChildrenWithOccluderNodes()>0) acceptNode->accept(*this);
|
||||
}
|
||||
|
||||
float _minimumShadowOccluderVolume;
|
||||
bool _createDrawables;
|
||||
ShadowVolumeOccluderList _collectedOccluderList;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,11 +28,15 @@ class SG_EXPORT CullStack
|
||||
|
||||
enum CullingModeValues
|
||||
{
|
||||
NO_CULLING = 0x00,
|
||||
NO_CULLING = 0x0,
|
||||
VIEW_FRUSTUM_CULLING = 0x1,
|
||||
SMALL_FEATURE_CULLING = 0x2,
|
||||
SHADOW_OCCLUSION_CULLING = 0x4,
|
||||
ENABLE_ALL_CULLING = 0xffffffff
|
||||
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;
|
||||
@@ -58,6 +62,9 @@ class SG_EXPORT CullStack
|
||||
void pushModelViewMatrix(osg::Matrix* matrix);
|
||||
void popModelViewMatrix();
|
||||
|
||||
inline float getFrustumVolume() { if (_frustumVolume<0.0f) computeFrustumVolume(); return _frustumVolume; }
|
||||
|
||||
|
||||
void setLODBias(const float bias) { _LODBias = bias; }
|
||||
const float getLODBias() const { return _LODBias; }
|
||||
|
||||
@@ -174,6 +181,9 @@ class SG_EXPORT CullStack
|
||||
CullingStack _projectionCullingStack;
|
||||
CullingStack _modelviewCullingStack;
|
||||
|
||||
void computeFrustumVolume();
|
||||
float _frustumVolume;
|
||||
|
||||
unsigned int _bbCornerNear;
|
||||
unsigned int _bbCornerFar;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class SG_EXPORT CullingSet : public Referenced
|
||||
void setFrustum(Polytope& cv) { _frustum = cv; }
|
||||
|
||||
Polytope& getFrustum() { return _frustum; }
|
||||
const Polytope& getFrustum() const { return _frustum; }
|
||||
const Polytope& getFrustum() const { return _frustum; }
|
||||
|
||||
void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); }
|
||||
|
||||
|
||||
@@ -108,6 +108,24 @@ inline T RadiansToDegrees(T angle) { return angle*(T)180.0/(T)PI; }
|
||||
inline bool isNaN(double v) { return isnan(v); }
|
||||
#endif
|
||||
|
||||
|
||||
/** compute the volume of tetrahedron */
|
||||
template<typename T>
|
||||
inline float computeVolume(const T& a,const T& b,const T& c,const T& d)
|
||||
{
|
||||
return fabs(((b-c)^(a-b))*(d-b));
|
||||
}
|
||||
|
||||
/** compute the volume of prism */
|
||||
template<typename T>
|
||||
inline float computeVolume(const T& f1,const T& f2,const T& f3,
|
||||
const T& b1,const T& b2,const T& b3)
|
||||
{
|
||||
return computeVolume(f1,f2,f3,b1)+
|
||||
computeVolume(b1,b2,b3,f2)+
|
||||
computeVolume(b1,b3,f2,f3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // __OSG_MATH
|
||||
|
||||
@@ -44,25 +44,15 @@ class SG_EXPORT Polytope
|
||||
}
|
||||
|
||||
/** Create a Polytope with is cube, centered at 0,0,0, with sides of 2 units.*/
|
||||
void setToUnitFrustum()
|
||||
{
|
||||
_planeList.erase(_planeList.begin(),_planeList.end());
|
||||
_planeList.push_back(Plane(1.0f,0.0f,0.0f,1.0f)); // left plane.
|
||||
_planeList.push_back(Plane(-1.0f,0.0f,0.0f,1.0f)); // right plane.
|
||||
_planeList.push_back(Plane(0.0f,1.0f,0.0f,1.0f)); // bottom plane.
|
||||
_planeList.push_back(Plane(0.0f,-1.0f,0.0f,1.0f)); // top plane.
|
||||
_planeList.push_back(Plane(0.0f,0.0f,-1.0f,1.0f)); // near plane
|
||||
_planeList.push_back(Plane(0.0f,0.0f,1.0f,1.0f)); // far plane
|
||||
setupMask();
|
||||
}
|
||||
|
||||
void setToUnitFrustumWithoutNearFar()
|
||||
void setToUnitFrustum(bool withNear=true, bool withFar=true)
|
||||
{
|
||||
_planeList.erase(_planeList.begin(),_planeList.end());
|
||||
_planeList.push_back(Plane(1.0f,0.0f,0.0f,1.0f)); // left plane.
|
||||
_planeList.push_back(Plane(-1.0f,0.0f,0.0f,1.0f)); // right plane.
|
||||
_planeList.push_back(Plane(0.0f,1.0f,0.0f,1.0f)); // bottom plane.
|
||||
_planeList.push_back(Plane(0.0f,-1.0f,0.0f,1.0f)); // top plane.
|
||||
if (withNear) _planeList.push_back(Plane(0.0f,0.0f,-1.0f,1.0f)); // near plane
|
||||
if (withFar) _planeList.push_back(Plane(0.0f,0.0f,1.0f,1.0f)); // far plane
|
||||
setupMask();
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ class SG_EXPORT ShadowVolumeOccluder
|
||||
inline NodePath& getNodePath() { return _nodePath; }
|
||||
inline const NodePath& getNodePath() const { return _nodePath; }
|
||||
|
||||
float volume() { return _volume; }
|
||||
float getVolume() const { return _volume; }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,13 @@ CollectOccludersVisitor::CollectOccludersVisitor()
|
||||
{
|
||||
// overide the default node visitor mode.
|
||||
setTraversalMode(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
|
||||
|
||||
/*setCullingMode(VIEW_FRUSTUM_CULLING|
|
||||
NEAR_PLANE_CULLING|
|
||||
FAR_PLANE_CULLING|
|
||||
SMALL_FEATURE_CULLING);*/
|
||||
|
||||
_minimumShadowOccluderVolume = 0.01;
|
||||
_createDrawables = false;
|
||||
|
||||
}
|
||||
@@ -122,11 +128,17 @@ void CollectOccludersVisitor::apply(osg::OccluderNode& node)
|
||||
ShadowVolumeOccluder svo;
|
||||
if (svo.computeOccluder(_nodePath, *node.getOccluder(), *this,_createDrawables))
|
||||
{
|
||||
// need to test occluder against view frustum.
|
||||
// std::cout << " adding in Occluder"<<std::endl;
|
||||
_occluderList.push_back(svo);
|
||||
|
||||
|
||||
|
||||
if (svo.getVolume()>_minimumShadowOccluderVolume)
|
||||
{
|
||||
// need to test occluder against view frustum.
|
||||
std::cout << " adding in Occluder"<<std::endl;
|
||||
_occluderList.push_back(svo);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << " rejecting Occluder as its volume is too small "<<svo.getVolume()<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ CullStack::CullStack()
|
||||
_cullingMode = ENABLE_ALL_CULLING;
|
||||
_LODBias = 1.0f;
|
||||
_smallFeatureCullingPixelSize = 3.0f;
|
||||
_frustumVolume=-1.0f;
|
||||
|
||||
}
|
||||
|
||||
@@ -71,16 +72,16 @@ void CullStack::pushCullingSet()
|
||||
|
||||
float P23 = P(2,3);
|
||||
float P33 = P(3,3);
|
||||
osg::Vec4 pixelSizeVector2(M(0,2)*P23,
|
||||
osg::Vec4 pixelSizeVector(M(0,2)*P23,
|
||||
M(1,2)*P23,
|
||||
M(2,2)*P23,
|
||||
M(3,2)*P23 + M(3,3)*P33);
|
||||
|
||||
pixelSizeVector2 /= scale.length();
|
||||
pixelSizeVector /= scale.length();
|
||||
|
||||
//cout << "pixelSizeVector = "<<pixelSizeVector<<" pixelSizeVector2="<<pixelSizeVector2<<endl;
|
||||
|
||||
_modelviewCullingStack.push_back(osgNew osg::CullingSet(*_projectionCullingStack.back(),*_modelviewStack.back(),pixelSizeVector2));
|
||||
_modelviewCullingStack.push_back(osgNew osg::CullingSet(*_projectionCullingStack.back(),*_modelviewStack.back(),pixelSizeVector));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -109,8 +110,9 @@ void CullStack::pushProjectionMatrix(Matrix* matrix)
|
||||
_projectionStack.push_back(matrix);
|
||||
|
||||
osg::CullingSet* cullingSet = osgNew osg::CullingSet();
|
||||
|
||||
// set up view frustum.
|
||||
cullingSet->getFrustum().setToUnitFrustumWithoutNearFar();
|
||||
cullingSet->getFrustum().setToUnitFrustum(_cullingMode&NEAR_PLANE_CULLING,_cullingMode&FAR_PLANE_CULLING);
|
||||
cullingSet->getFrustum().transformProvidingInverse(*matrix);
|
||||
|
||||
// set the small feature culling.
|
||||
@@ -132,6 +134,8 @@ void CullStack::pushProjectionMatrix(Matrix* matrix)
|
||||
|
||||
_projectionCullingStack.push_back(cullingSet);
|
||||
|
||||
// need to recompute frustum volume.
|
||||
_frustumVolume = -1.0f;
|
||||
|
||||
pushCullingSet();
|
||||
}
|
||||
@@ -143,6 +147,9 @@ void CullStack::popProjectionMatrix()
|
||||
|
||||
_projectionCullingStack.pop_back();
|
||||
|
||||
// need to recompute frustum volume.
|
||||
_frustumVolume = -1.0f;
|
||||
|
||||
popCullingSet();
|
||||
}
|
||||
|
||||
@@ -201,3 +208,23 @@ void CullStack::popModelViewMatrix()
|
||||
|
||||
_bbCornerNear = (~_bbCornerFar)&7;
|
||||
}
|
||||
|
||||
void CullStack::computeFrustumVolume()
|
||||
{
|
||||
osg::Matrix invP;
|
||||
invP.invert(getProjectionMatrix());
|
||||
|
||||
osg::Vec3 f1(-1,-1,-1); f1 = f1*invP;
|
||||
osg::Vec3 f2(-1, 1,-1); f2 = f2*invP;
|
||||
osg::Vec3 f3( 1, 1,-1); f3 = f3*invP;
|
||||
osg::Vec3 f4( 1,-1,-1); f4 = f4*invP;
|
||||
|
||||
osg::Vec3 b1(-1,-1,1); b1 = b1*invP;
|
||||
osg::Vec3 b2(-1, 1,1); b2 = b2*invP;
|
||||
osg::Vec3 b3( 1, 1,1); b3 = b3*invP;
|
||||
osg::Vec3 b4( 1,-1,1); b4 = b4*invP;
|
||||
|
||||
_frustumVolume = computeVolume(f1,f2,f3,b1,b2,b3)+
|
||||
computeVolume(f2,f3,f4,b1,b3,b4);
|
||||
|
||||
}
|
||||
|
||||
@@ -30,3 +30,4 @@ void CullingSet::disableOccluder(NodePath& nodePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,20 +139,20 @@ Plane computeFrontPlane(const PointList& front)
|
||||
}
|
||||
|
||||
|
||||
// compute the volume of tetrahedron
|
||||
inline float computeVolume(const osg::Vec3& a,const osg::Vec3& b,const osg::Vec3& c,const osg::Vec3& d)
|
||||
{
|
||||
return fabs(((b-c)^(a-b))*(d-b));
|
||||
}
|
||||
|
||||
// compute the volume of prism.
|
||||
inline float computeVolume(const osg::Vec3& f1,const osg::Vec3& f2,const osg::Vec3& f3,
|
||||
const osg::Vec3& b1,const osg::Vec3& b2,const osg::Vec3& b3)
|
||||
{
|
||||
return computeVolume(f1,f2,f3,b1)+
|
||||
computeVolume(b1,b2,b3,f2)+
|
||||
computeVolume(b1,b3,f2,f3);
|
||||
}
|
||||
// // compute the volume of tetrahedron
|
||||
// inline float computeVolume(const osg::Vec3& a,const osg::Vec3& b,const osg::Vec3& c,const osg::Vec3& d)
|
||||
// {
|
||||
// return fabs(((b-c)^(a-b))*(d-b));
|
||||
// }
|
||||
//
|
||||
// // compute the volume of prism.
|
||||
// inline float computeVolume(const osg::Vec3& f1,const osg::Vec3& f2,const osg::Vec3& f3,
|
||||
// const osg::Vec3& b1,const osg::Vec3& b2,const osg::Vec3& b3)
|
||||
// {
|
||||
// return computeVolume(f1,f2,f3,b1)+
|
||||
// computeVolume(b1,b2,b3,f2)+
|
||||
// computeVolume(b1,b3,f2,f3);
|
||||
// }
|
||||
|
||||
// compute the volume between the front and back polygons of the occluder/hole.
|
||||
float computeVolume(const PointList& front, const PointList& back)
|
||||
@@ -265,8 +265,7 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex
|
||||
Matrix invP;
|
||||
invP.invert(P);
|
||||
|
||||
float volumeview = computeVolumeOfView(invP);
|
||||
cout << "volumeview "<<volumeview<<endl;
|
||||
float volumeview = cullStack.getFrustumVolume();
|
||||
|
||||
|
||||
// compute the transformation matrix which takes form local coords into clip space.
|
||||
@@ -390,7 +389,7 @@ bool ShadowVolumeOccluder::computeOccluder(const NodePath& nodePath,const Convex
|
||||
|
||||
}
|
||||
|
||||
std::cout << "final volume = "<<_volume<<std::endl;
|
||||
//std::cout << "final volume = "<<_volume<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user