/*
====================
idGameLocal::CalcFov
Calculates the horizontal and vertical field of view based on a horizontal field of view and custom aspect ratio
====================
*/
void idGameLocal::CalcFov( float base_fov, float &fov_x, float &fov_y ) const {
float x;
float y;
float ratio_x;
float ratio_y;
float ratio_fov;
// first, calculate the vertical fov based on a 640x480 view
x = 640.0f / tan( base_fov / 360.0f * idMath::PI );
y = atan2( 480.0f, x );
fov_y = y * 360.0f / idMath::PI;
// FIXME: somehow, this is happening occasionally
assert( fov_y > 0 );
if ( fov_y <= 0 ) {
Error( "idGameLocal::CalcFov: bad result" );
}
// if r_fovRatio != 0, use it directly:
ratio_fov = cv_r_fovRatio.GetFloat();
if (ratio_fov > 0.01)
{
ratio_x = ratio_fov;
ratio_y = 1.0f;
}
else
{
// old code, use r_aspectRatio
switch( r_aspectRatio.GetInteger() ) {
default :
case 0 :
// 4:3
fov_x = base_fov;
return;
break;
case 1 :
// 16:9
case 4 :
// TV 16:9
ratio_x = 16.0f;
ratio_y = 9.0f;
break;
case 2 :
// 16:10
ratio_x = 16.0f;
ratio_y = 10.0f;
break;
case 3 :
// 5:4
ratio_x = 5.0f;
ratio_y = 4.0f;
break;
}
}
// Printf( "Using FOV ratio %0.3f:%0.0f\n", ratio_x, ratio_y );
y = ratio_y / tan( fov_y / 360.0f * idMath::PI );
fov_x = atan2( ratio_x, y ) * 360.0f / idMath::PI;
if ( fov_x < base_fov ) {
fov_x = base_fov;
x = ratio_x / tan( fov_x / 360.0f * idMath::PI );
fov_y = atan2( ratio_y, x ) * 360.0f / idMath::PI;
}
// FIXME: somehow, this is happening occasionally
assert( ( fov_x > 0 ) && ( fov_y > 0 ) );
if ( ( fov_y <= 0 ) || ( fov_x <= 0 ) ) {
Error( "idGameLocal::CalcFov: bad result" );
}
}