Moved osg::clampProjectionMatrix() template from CullVisitor.cpp into include/osg/CullSettings to make it easier to implement custom clampProjectionMatrix callbacks
This commit is contained in:
parent
ecedf3232c
commit
d2c2ef3ec9
@ -270,6 +270,88 @@ class OSG_EXPORT CullSettings
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class matrix_type, class value_type>
|
||||||
|
bool clampProjectionMatrix(matrix_type& projection, double& znear, double& zfar, value_type nearFarRatio)
|
||||||
|
{
|
||||||
|
double epsilon = 1e-6;
|
||||||
|
if (zfar<znear-epsilon)
|
||||||
|
{
|
||||||
|
if (zfar != -FLT_MAX || znear != FLT_MAX)
|
||||||
|
{
|
||||||
|
OSG_INFO<<"_clampProjectionMatrix not applied, invalid depth range, znear = "<<znear<<" zfar = "<<zfar<<std::endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zfar<znear+epsilon)
|
||||||
|
{
|
||||||
|
// znear and zfar are too close together and could cause divide by zero problems
|
||||||
|
// late on in the clamping code, so move the znear and zfar apart.
|
||||||
|
double average = (znear+zfar)*0.5;
|
||||||
|
znear = average-epsilon;
|
||||||
|
zfar = average+epsilon;
|
||||||
|
// OSG_INFO << "_clampProjectionMatrix widening znear and zfar to "<<znear<<" "<<zfar<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fabs(projection(0,3))<epsilon && fabs(projection(1,3))<epsilon && fabs(projection(2,3))<epsilon )
|
||||||
|
{
|
||||||
|
// OSG_INFO << "Orthographic matrix before clamping"<<projection<<std::endl;
|
||||||
|
|
||||||
|
value_type delta_span = (zfar-znear)*0.02;
|
||||||
|
if (delta_span<1.0) delta_span = 1.0;
|
||||||
|
value_type desired_znear = znear - delta_span;
|
||||||
|
value_type desired_zfar = zfar + delta_span;
|
||||||
|
|
||||||
|
// assign the clamped values back to the computed values.
|
||||||
|
znear = desired_znear;
|
||||||
|
zfar = desired_zfar;
|
||||||
|
|
||||||
|
projection(2,2)=-2.0f/(desired_zfar-desired_znear);
|
||||||
|
projection(3,2)=-(desired_zfar+desired_znear)/(desired_zfar-desired_znear);
|
||||||
|
|
||||||
|
// OSG_INFO << "Orthographic matrix after clamping "<<projection<<std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
// OSG_INFO << "Persepective matrix before clamping"<<projection<<std::endl;
|
||||||
|
|
||||||
|
//std::cout << "_computed_znear"<<_computed_znear<<std::endl;
|
||||||
|
//std::cout << "_computed_zfar"<<_computed_zfar<<std::endl;
|
||||||
|
|
||||||
|
value_type zfarPushRatio = 1.02;
|
||||||
|
value_type znearPullRatio = 0.98;
|
||||||
|
|
||||||
|
//znearPullRatio = 0.99;
|
||||||
|
|
||||||
|
value_type desired_znear = znear * znearPullRatio;
|
||||||
|
value_type desired_zfar = zfar * zfarPushRatio;
|
||||||
|
|
||||||
|
// near plane clamping.
|
||||||
|
double min_near_plane = zfar*nearFarRatio;
|
||||||
|
if (desired_znear<min_near_plane) desired_znear=min_near_plane;
|
||||||
|
|
||||||
|
// assign the clamped values back to the computed values.
|
||||||
|
znear = desired_znear;
|
||||||
|
zfar = desired_zfar;
|
||||||
|
|
||||||
|
value_type trans_near_plane = (-desired_znear*projection(2,2)+projection(3,2))/(-desired_znear*projection(2,3)+projection(3,3));
|
||||||
|
value_type trans_far_plane = (-desired_zfar*projection(2,2)+projection(3,2))/(-desired_zfar*projection(2,3)+projection(3,3));
|
||||||
|
|
||||||
|
value_type ratio = fabs(2.0/(trans_near_plane-trans_far_plane));
|
||||||
|
value_type center = -(trans_near_plane+trans_far_plane)/2.0;
|
||||||
|
|
||||||
|
projection.postMult(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
|
||||||
|
0.0f,1.0f,0.0f,0.0f,
|
||||||
|
0.0f,0.0f,ratio,0.0f,
|
||||||
|
0.0f,0.0f,center*ratio,1.0f));
|
||||||
|
|
||||||
|
// OSG_INFO << "Persepective matrix after clamping"<<projection<<std::endl;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,96 +252,16 @@ void CullVisitor::popProjectionMatrix()
|
|||||||
CullStack::popProjectionMatrix();
|
CullStack::popProjectionMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class matrix_type, class value_type>
|
|
||||||
bool _clampProjectionMatrix(matrix_type& projection, double& znear, double& zfar, value_type nearFarRatio)
|
|
||||||
{
|
|
||||||
double epsilon = 1e-6;
|
|
||||||
if (zfar<znear-epsilon)
|
|
||||||
{
|
|
||||||
if (zfar != -FLT_MAX || znear != FLT_MAX)
|
|
||||||
{
|
|
||||||
OSG_INFO<<"_clampProjectionMatrix not applied, invalid depth range, znear = "<<znear<<" zfar = "<<zfar<<std::endl;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zfar<znear+epsilon)
|
|
||||||
{
|
|
||||||
// znear and zfar are too close together and could cause divide by zero problems
|
|
||||||
// late on in the clamping code, so move the znear and zfar apart.
|
|
||||||
double average = (znear+zfar)*0.5;
|
|
||||||
znear = average-epsilon;
|
|
||||||
zfar = average+epsilon;
|
|
||||||
// OSG_INFO << "_clampProjectionMatrix widening znear and zfar to "<<znear<<" "<<zfar<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fabs(projection(0,3))<epsilon && fabs(projection(1,3))<epsilon && fabs(projection(2,3))<epsilon )
|
|
||||||
{
|
|
||||||
// OSG_INFO << "Orthographic matrix before clamping"<<projection<<std::endl;
|
|
||||||
|
|
||||||
value_type delta_span = (zfar-znear)*0.02;
|
|
||||||
if (delta_span<1.0) delta_span = 1.0;
|
|
||||||
value_type desired_znear = znear - delta_span;
|
|
||||||
value_type desired_zfar = zfar + delta_span;
|
|
||||||
|
|
||||||
// assign the clamped values back to the computed values.
|
|
||||||
znear = desired_znear;
|
|
||||||
zfar = desired_zfar;
|
|
||||||
|
|
||||||
projection(2,2)=-2.0f/(desired_zfar-desired_znear);
|
|
||||||
projection(3,2)=-(desired_zfar+desired_znear)/(desired_zfar-desired_znear);
|
|
||||||
|
|
||||||
// OSG_INFO << "Orthographic matrix after clamping "<<projection<<std::endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
// OSG_INFO << "Persepective matrix before clamping"<<projection<<std::endl;
|
|
||||||
|
|
||||||
//std::cout << "_computed_znear"<<_computed_znear<<std::endl;
|
|
||||||
//std::cout << "_computed_zfar"<<_computed_zfar<<std::endl;
|
|
||||||
|
|
||||||
value_type zfarPushRatio = 1.02;
|
|
||||||
value_type znearPullRatio = 0.98;
|
|
||||||
|
|
||||||
//znearPullRatio = 0.99;
|
|
||||||
|
|
||||||
value_type desired_znear = znear * znearPullRatio;
|
|
||||||
value_type desired_zfar = zfar * zfarPushRatio;
|
|
||||||
|
|
||||||
// near plane clamping.
|
|
||||||
double min_near_plane = zfar*nearFarRatio;
|
|
||||||
if (desired_znear<min_near_plane) desired_znear=min_near_plane;
|
|
||||||
|
|
||||||
// assign the clamped values back to the computed values.
|
|
||||||
znear = desired_znear;
|
|
||||||
zfar = desired_zfar;
|
|
||||||
|
|
||||||
value_type trans_near_plane = (-desired_znear*projection(2,2)+projection(3,2))/(-desired_znear*projection(2,3)+projection(3,3));
|
|
||||||
value_type trans_far_plane = (-desired_zfar*projection(2,2)+projection(3,2))/(-desired_zfar*projection(2,3)+projection(3,3));
|
|
||||||
|
|
||||||
value_type ratio = fabs(2.0/(trans_near_plane-trans_far_plane));
|
|
||||||
value_type center = -(trans_near_plane+trans_far_plane)/2.0;
|
|
||||||
|
|
||||||
projection.postMult(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
|
|
||||||
0.0f,1.0f,0.0f,0.0f,
|
|
||||||
0.0f,0.0f,ratio,0.0f,
|
|
||||||
0.0f,0.0f,center*ratio,1.0f));
|
|
||||||
|
|
||||||
// OSG_INFO << "Persepective matrix after clamping"<<projection<<std::endl;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CullVisitor::clampProjectionMatrixImplementation(osg::Matrixf& projection, double& znear, double& zfar) const
|
bool CullVisitor::clampProjectionMatrixImplementation(osg::Matrixf& projection, double& znear, double& zfar) const
|
||||||
{
|
{
|
||||||
return _clampProjectionMatrix( projection, znear, zfar, _nearFarRatio );
|
return osg::clampProjectionMatrix( projection, znear, zfar, _nearFarRatio );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CullVisitor::clampProjectionMatrixImplementation(osg::Matrixd& projection, double& znear, double& zfar) const
|
bool CullVisitor::clampProjectionMatrixImplementation(osg::Matrixd& projection, double& znear, double& zfar) const
|
||||||
{
|
{
|
||||||
return _clampProjectionMatrix( projection, znear, zfar, _nearFarRatio );
|
return osg::clampProjectionMatrix( projection, znear, zfar, _nearFarRatio );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Comparator>
|
template<typename Comparator>
|
||||||
|
Loading…
Reference in New Issue
Block a user