Skip to content

Instantly share code, notes, and snippets.

@DanielGibson
Last active December 17, 2015 10:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielGibson/5595590 to your computer and use it in GitHub Desktop.
Save DanielGibson/5595590 to your computer and use it in GitHub Desktop.
idGameLocal::CalcFov from dhewm3/neo/game/Game_local.cpp - modified with additional assertions and debug-prints and some comments on how [https://github.com/dhewm/dhewm3/issues/70] shouldn't happen (my guess is that renderSystem->GetScreenWidth() and/or renderSystem->GetScreenHeight() return 0 or a negative value)
void idGameLocal::CalcFov( float base_fov, float &fov_x, float &fov_y ) const {
float x;
float y;
float ratio_x;
float ratio_y;
assert(base_fov > 0);
// first, calculate the vertical fov based on a 640x480 view
// XXX: will be positive because tan() is positive if the given value is positive as asserted above
x = 640.0f / tan( base_fov / 360.0f * idMath::PI );
y = atan2( 480.0f, x ); // XXX: == arctan(480/x) with x > 0 => will be > 0
fov_y = y * 360.0f / idMath::PI;
// FIXME: somehow, this is happening occasionally
assert( fov_y > 0 ); // XXX: this *really* shouldn't be able to happen
if ( fov_y <= 0 ) {
Error( "idGameLocal::CalcFov: bad result" );
}
switch( r_aspectRatio.GetInteger() ) {
default :
case -1 :
// auto mode => use aspect ratio from resolution, assuming screen's pixels are squares
ratio_x = renderSystem->GetScreenWidth();
ratio_y = renderSystem->GetScreenHeight();
if(!(ratio_x > 0 && ratio_y > 0))
Printf("## ratio_x = %f, ratio_y = %f\n", ratio_x, ratio_y);
break;
case 0 :
// 4:3
fov_x = base_fov;
return;
break;
case 1 :
// 16:9
ratio_x = 16.0f;
ratio_y = 9.0f;
break;
case 2 :
// 16:10
ratio_x = 16.0f;
ratio_y = 10.0f;
break;
}
assert(ratio_x > 0 && ratio_y > 0);
y = ratio_y / tan( fov_y / 360.0f * idMath::PI ); // XXX: will be > 0, because ratio_y > 0 and fov_y > 0
// XXX: atan2(ratio_x, y) == arctan(ratio_x / y) => will be > 0 because ratio_x and y are > 0
fov_x = atan2( ratio_x, y ) * 360.0f / idMath::PI; // XXX: thus fov_x will be > 0
if ( fov_x < base_fov ) {
fov_x = base_fov;
x = ratio_x / tan( fov_x / 360.0f * idMath::PI ); // XXX: will be > 0 because everything is > 0
fov_y = atan2( ratio_y, x ) * 360.0f / idMath::PI; // XXX: as x and ratio_y are > 0, this should be > 0
}
// FIXME: somehow, this is happening occasionally
assert( ( fov_x > 0 ) && ( fov_y > 0 ) ); // XXX: so this can't happen :-P
if ( ( fov_y <= 0 ) || ( fov_x <= 0 ) ) {
Error( "idGameLocal::CalcFov: bad result" );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment