diff --git a/include/osgShadow/MinimalShadowMap b/include/osgShadow/MinimalShadowMap index 3612fd133..52d915784 100644 --- a/include/osgShadow/MinimalShadowMap +++ b/include/osgShadow/MinimalShadowMap @@ -95,13 +95,14 @@ class OSGSHADOW_EXPORT MinimalShadowMap : public StandardShadowMap osg::Matrix _modellingSpaceToWorld; float _maxFarPlane; float _minLightMargin; - ShadowReceivingCoarseBoundAccuracy _shadowReceivingCoarseBoundAccuracy; + ShadowReceivingCoarseBoundAccuracy _shadowReceivingCoarseBoundAccuracy; struct OSGSHADOW_EXPORT ViewData: public BaseClass::ViewData { osg::Matrix *_modellingSpaceToWorldPtr; float *_maxFarPlanePtr; float *_minLightMarginPtr; + int _frameShadowCastingCameraPasses; ConvexPolyhedron _sceneReceivingShadowPolytope; std::vector< osg::Vec3d > _sceneReceivingShadowPolytopePoints; diff --git a/include/osgShadow/ProjectionShadowMap b/include/osgShadow/ProjectionShadowMap index 4ca928195..44d807c9b 100644 --- a/include/osgShadow/ProjectionShadowMap +++ b/include/osgShadow/ProjectionShadowMap @@ -65,9 +65,12 @@ class OSGSHADOW_EXPORT ProjectionShadowMap : public MinimalBoundsBaseClass virtual void frameShadowCastingCamera ( const osg::Camera* cameraMain, osg::Camera* cameraShadow, int pass = 1 ) { - // Force dependent name lookup - ShadowProjectionAlgorithmClass::operator() - ( &this->_sceneReceivingShadowPolytope, cameraMain, cameraShadow ); + if( pass == BaseClass::ViewData::_frameShadowCastingCameraPasses - 1 ) + { + // Force dependent name lookup + ShadowProjectionAlgorithmClass::operator() + ( &this->_sceneReceivingShadowPolytope, cameraMain, cameraShadow ); + } // DebugBoundingBox( computeScenePolytopeBounds(), "ProjectionShadowMap" ); BaseClass::ViewData::frameShadowCastingCamera( cameraMain, cameraShadow, pass ); diff --git a/src/osgShadow/ConvexPolyhedron.cpp b/src/osgShadow/ConvexPolyhedron.cpp index 217d2a46c..7f995d024 100644 --- a/src/osgShadow/ConvexPolyhedron.cpp +++ b/src/osgShadow/ConvexPolyhedron.cpp @@ -31,7 +31,16 @@ using namespace osgShadow; #if defined( DEBUG ) || defined( _DEBUG ) || defined( _DEBUG_ ) - #define MAKE_CHECKS 1 +// ConvexPolyhedron may produce tons of warnings when it becomes non convex. +// Unfortuantely this condition often happens in daily routine of shadow usage +// due precision errors mixed with repeating frustum cuts performed by MinimalShadowClasses. +// However, in most of above cases this condition is not fatal +// because polyhedron becomes concave by very small margin (mesuring deep the hole). +// Unfortunately warnings are produced even for such small margin cases and can +// easily flood the console. +// So I leave MAKE_CHECKS commented out. Its really useful only for a guy who debugs +// larger concaveness issues which means most developers will want to keep it commented. +// #define MAKE_CHECKS 1 #endif #if MAKE_CHECKS diff --git a/src/osgShadow/DebugShadowMap.cpp b/src/osgShadow/DebugShadowMap.cpp index a6e0785f3..37f73878d 100644 --- a/src/osgShadow/DebugShadowMap.cpp +++ b/src/osgShadow/DebugShadowMap.cpp @@ -391,8 +391,25 @@ void DebugShadowMap::ViewData::init( ThisClass *st, osgUtil::CullVisitor *cv ) _hudSize = st->_hudSize; _hudOrigin = st->_hudOrigin; - _viewportSize = st->_viewportSize; + _viewportOrigin = st->_viewportOrigin; + _viewportSize = st->_viewportSize; + + osg::Viewport * vp = cv->getViewport(); + if( vp ) + { + // view can be a slave that covers only a fraction of the screen + // so adjust debug hud location to proper viewport location + _viewportOrigin[0] += vp->x(); + _viewportOrigin[1] += vp->y(); + + if( _viewportSize[0] > vp->width() - _viewportOrigin[0] ) + _viewportSize[0] = vp->width() - _viewportOrigin[0]; + + if( _viewportSize[1] > vp->height() - _viewportOrigin[1] ) + _viewportSize[1] = vp->height() - _viewportOrigin[1]; + } + _orthoSize = st->_orthoSize; _orthoOrigin = st->_orthoOrigin; diff --git a/src/osgShadow/MinimalCullBoundsShadowMap.cpp b/src/osgShadow/MinimalCullBoundsShadowMap.cpp index 2a93705c4..c00769bf3 100644 --- a/src/osgShadow/MinimalCullBoundsShadowMap.cpp +++ b/src/osgShadow/MinimalCullBoundsShadowMap.cpp @@ -41,6 +41,7 @@ void MinimalCullBoundsShadowMap::ViewData::init ( ThisClass *st, osgUtil::CullVisitor *cv ) { BaseClass::ViewData::init( st, cv ); + _frameShadowCastingCameraPasses = 2; } void MinimalCullBoundsShadowMap::ViewData::aimShadowCastingCamera diff --git a/src/osgShadow/MinimalDrawBoundsShadowMap.cpp b/src/osgShadow/MinimalDrawBoundsShadowMap.cpp index c1a49ee79..4589d6c44 100644 --- a/src/osgShadow/MinimalDrawBoundsShadowMap.cpp +++ b/src/osgShadow/MinimalDrawBoundsShadowMap.cpp @@ -271,6 +271,7 @@ void MinimalDrawBoundsShadowMap::ViewData::init { BaseClass::ViewData::init( st, cv ); + _frameShadowCastingCameraPasses = 2; _camera->setCullCallback ( new CameraCullCallback( this, _camera->getCullCallback() ) ); diff --git a/src/osgShadow/MinimalShadowMap.cpp b/src/osgShadow/MinimalShadowMap.cpp index 5f31ba65c..4170563bb 100644 --- a/src/osgShadow/MinimalShadowMap.cpp +++ b/src/osgShadow/MinimalShadowMap.cpp @@ -168,7 +168,7 @@ void MinimalShadowMap::ViewData::aimShadowCastingCamera osg::Matrix mvp = _camera->getViewMatrix() * _camera->getProjectionMatrix(); cutScenePolytope( osg::Matrix::inverse( mvp ), mvp ); - MinimalShadowMap::ViewData::frameShadowCastingCamera + frameShadowCastingCamera ( _cv->getRenderStage()->getCamera(), _camera.get(), 0 ); } @@ -207,7 +207,7 @@ void MinimalShadowMap::ViewData::frameShadowCastingCamera // space (-1..1), it may get "twisted" by precisely adjusted shadow cam // projection in second pass. - if ( pass == 0 ) + if ( pass == 0 && _frameShadowCastingCameraPasses > 1 ) { // Make sure extruded polytope does not extend beyond light frustum osg::Polytope lightFrustum; lightFrustum.setToUnitFrustum(); @@ -304,6 +304,8 @@ void MinimalShadowMap::ViewData::init( ThisClass *st, osgUtil::CullVisitor *cv ) _modellingSpaceToWorldPtr = &st->_modellingSpaceToWorld; _minLightMarginPtr = &st->_minLightMargin; _maxFarPlanePtr = &st->_maxFarPlane; + + _frameShadowCastingCameraPasses = 1; } void MinimalShadowMap::ViewData::cutScenePolytope