diff --git a/include/osg/CollectOccludersVisitor b/include/osg/CollectOccludersVisitor index 6b308d225..29455edbd 100644 --- a/include/osg/CollectOccludersVisitor +++ b/include/osg/CollectOccludersVisitor @@ -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; + }; } diff --git a/include/osg/CullStack b/include/osg/CullStack index ad815ccb0..1ea08d5af 100644 --- a/include/osg/CullStack +++ b/include/osg/CullStack @@ -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; diff --git a/include/osg/CullingSet b/include/osg/CullingSet index 2b4f592db..bbc220f3e 100644 --- a/include/osg/CullingSet +++ b/include/osg/CullingSet @@ -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); } diff --git a/include/osg/Math b/include/osg/Math index 8bf99607e..a5ea3a3a3 100644 --- a/include/osg/Math +++ b/include/osg/Math @@ -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 +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 +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 diff --git a/include/osg/Polytope b/include/osg/Polytope index 0df4af41f..e601c901e 100644 --- a/include/osg/Polytope +++ b/include/osg/Polytope @@ -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(); } diff --git a/include/osg/ShadowVolumeOccluder b/include/osg/ShadowVolumeOccluder index d8210954e..33266c7e5 100644 --- a/include/osg/ShadowVolumeOccluder +++ b/include/osg/ShadowVolumeOccluder @@ -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; } diff --git a/src/osg/CollectOccludersVisitor.cpp b/src/osg/CollectOccludersVisitor.cpp index 00ab54ae8..45926afd1 100644 --- a/src/osg/CollectOccludersVisitor.cpp +++ b/src/osg/CollectOccludersVisitor.cpp @@ -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"<_minimumShadowOccluderVolume) + { + // need to test occluder against view frustum. + std::cout << " adding in Occluder"<