void MinimalShadowMap::ViewData::clampProjection ( osg::Matrixd & projection, float new_near, float new_far ) { double r, l, t, b, n, f; bool perspective = projection.getFrustum( l, r, b, t, n, f ); if( !perspective && !projection.getOrtho( l, r, b, t, n, f ) ) { // What to do here ? osg::notify( osg::WARN ) << "MinimalShadowMap::clampProjectionFarPlane failed - non standard matrix" << std::endl; } else if( n < new_near || new_far < f ) { if( n < new_near && new_near < f ) { if( perspective ) { l *= new_near / n; r *= new_near / n; b *= new_near / n; t *= new_near / n; } n = new_near; } if( n < new_far && new_far < f ) { f = new_far; } if( perspective ) projection.makeFrustum( l, r, b, t, n, f ); else projection.makeOrtho( l, r, b, t, n, f ); } }
void MxCore::updateFovy( osg::Matrixd& proj ) const { if( _ortho ) { osg::notify( osg::WARN ) << "MxCore::updateFovy: Ortho is not yet implemented. TBD." << std::endl; } else { double left, right, bottom, top, near, far; proj.getFrustum( left, right, bottom, top, near, far ); const double fovBottom = atan( bottom / near ); const double fovTop = atan( top / near ); const double fovyRatio = getFovyRadians() / ( osg::absolute< double >( fovBottom ) + osg::absolute< double >( fovTop ) ); const double newBottom = tan( fovBottom * fovyRatio ) * near; const double newTop = tan( fovTop * fovyRatio ) * near; const double xScale = newTop / top; left *= xScale; right *= xScale; proj = osg::Matrixd::frustum( left, right, newBottom, newTop, near, far ); } }
void MinimalShadowMap::ViewData::extendProjection ( osg::Matrixd & projection, osg::Viewport * viewport, const osg::Vec2& margin ) { double l,r,b,t,n,f; //osg::Matrix projection = camera.getProjectionMatrix(); bool frustum = projection.getFrustum( l,r,b,t,n,f ); if( !frustum && !projection.getOrtho( l,r,b,t,n,f ) ) { osg::notify( osg::WARN ) << " Awkward projection matrix. ComputeExtendedProjection failed" << std::endl; return; } osg::Matrix window = viewport->computeWindowMatrix(); osg::Vec3 vMin( viewport->x() - margin.x(), viewport->y() - margin.y(), 0.0 ); osg::Vec3 vMax( viewport->width() + margin.x() * 2 + vMin.x(), viewport->height() + margin.y() * 2 + vMin.y(), 0.0 ); osg::Matrix inversePW = osg::Matrix::inverse( projection * window ); vMin = vMin * inversePW; vMax = vMax * inversePW; l = vMin.x(); r = vMax.x(); b = vMin.y(); t = vMax.y(); if( frustum ) projection.makeFrustum( l,r,b,t,n,f ); else projection.makeOrtho( l,r,b,t,n,f ); }
void MinimalShadowMap::ViewData::trimProjection ( osg::Matrixd & projectionMatrix, osg::BoundingBox bb, unsigned int trimMask ) { #if 1 if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return; double l = -1, r = 1, b = -1, t = 1, n = 1, f = -1; #if 0 // make sure bounding box does not extend beyond unit frustum clip range for( int i = 0; i < 3; i ++ ) { if( bb._min[i] < -1 ) bb._min[i] = -1; if( bb._max[i] > 1 ) bb._max[i] = 1; } #endif if( trimMask & 1 ) l = bb._min[0]; if( trimMask & 2 ) r = bb._max[0]; if( trimMask & 4 ) b = bb._min[1]; if( trimMask & 8 ) t = bb._max[1]; if( trimMask & 16 ) n = -bb._min[2]; if( trimMask & 32 ) f = -bb._max[2]; projectionMatrix.postMult( osg::Matrix::ortho( l,r,b,t,n,f ) ); #else if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return; double l, r, t, b, n, f; bool ortho = projectionMatrix.getOrtho( l, r, b, t, n, f ); if( !ortho && !projectionMatrix.getFrustum( l, r, b, t, n, f ) ) return; // rotated or skewed or other crooked projection - give up // make sure bounding box does not extend beyond unit frustum clip range for( int i = 0; i < 3; i ++ ) { if( bb._min[i] < -1 ) bb._min[i] = -1; if( bb._max[i] > 1 ) bb._max[i] = 1; } osg::Matrix projectionToView = osg::Matrix::inverse( projectionMatrix ); osg::Vec3 min = osg::Vec3( bb._min[0], bb._min[1], bb._min[2] ) * projectionToView; osg::Vec3 max = osg::Vec3( bb._max[0], bb._max[1], bb._max[2] ) * projectionToView; if( trimMask & 16 ) { // trim near if( !ortho ) { // recalc frustum corners on new near plane l *= -min[2] / n; r *= -min[2] / n; b *= -min[2] / n; t *= -min[2] / n; } n = -min[2]; } if( trimMask & 32 ) // trim far f = -max[2]; if( !ortho ) { min[0] *= -n / min[2]; min[1] *= -n / min[2]; max[0] *= -n / max[2]; max[1] *= -n / max[2]; } if( l < r ) { // check for inverted X range if( l < min[0] && ( trimMask & 1 ) ) l = min[0]; if( r > max[0] && ( trimMask & 2 ) ) r = max[0]; } else { if( l > min[0] && ( trimMask & 1 ) ) l = min[0]; if( r < max[0] && ( trimMask & 2 ) ) r = max[0]; } if( b < t ) { // check for inverted Y range if( b < min[1] && ( trimMask & 4 ) ) b = min[1]; if( t > max[1] && ( trimMask & 8 ) ) t = max[1]; } else { if( b > min[1] && ( trimMask & 4 ) ) b = min[1]; if( t < max[1] && ( trimMask & 8 ) ) t = max[1]; } if( ortho ) projectionMatrix.makeOrtho( l, r, b, t, n, f ); else projectionMatrix.makeFrustum( l, r, b, t, n, f ); #endif }