diff --git a/docs/api-changes/0.55.md b/docs/api-changes/0.55.md new file mode 100644 index 0000000000..2d355710df --- /dev/null +++ b/docs/api-changes/0.55.md @@ -0,0 +1,6 @@ +# API Breaking changes for the 0.55 development cycle + +## 0.55.2+ + +- **Deprecation:** The `M_PI`, `M_SQRT2` and `M_ROOT3` definitions are deprecated in favor of constants from `common/Math/Constant.h`. +- **Deprecation:** The `DegToRad()` and `RadToDeg()` macros are deprecated in favor of `Math::DegToRad()` and `Math::RadToDeg()`. diff --git a/src/common/Math.h b/src/common/Math.h index 2185fc0706..8eca3839a4 100644 --- a/src/common/Math.h +++ b/src/common/Math.h @@ -33,6 +33,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include "math/Constants.h" + namespace Math { // This is designed to return min if value is NaN. That's not guaranteed to work when @@ -64,8 +66,40 @@ namespace Math { volatile uint64_t bits = Util::bit_cast(x); return ~bits & 0x7ff0000000000000; } + + inline float DegToRad( float angle ) + { + return angle * divpi_180_f; + } + + inline float RadToDeg( float angle ) + { + return angle * div180_pi_f; + } + + inline double DegToRad( double angle ) + { + return angle * divpi_180_d; + } + + inline double RadToDeg( double angle ) + { + return angle * div180_pi_d; + } } #include "math/Vector.h" +template +DEPRECATED A DEG2RAD( const A a ) +{ + return Math::DegToRad( a ); +} + +template +DEPRECATED A RAD2DEG( const A a ) +{ + return Math::RadToDeg ( a ); +} + #endif //COMMON_MATH_H_ diff --git a/src/common/math/Constants.h b/src/common/math/Constants.h new file mode 100644 index 0000000000..d4da4f13ff --- /dev/null +++ b/src/common/math/Constants.h @@ -0,0 +1,65 @@ +// Generated with tools/math-constants/math-constants.py +// Do not modify! + +#ifndef COMMON_MATH_CONSTANTS_H_ +#define COMMON_MATH_CONSTANTS_H_ + +namespace Math { + // Type Name Value Operation std::numbers GNU GLM + constexpr float phi_f = 1.61803399e+0f; // φ phif golden_ratio + constexpr float egamma_f = 1.56746826e+0f; // Γe egammaf + constexpr float ln2_f = 6.93147181e-1f; // ln(2) ln2f M_LN2f ln_two + constexpr float ln10_f = 2.30258509e+0f; // ln(10) ln10f M_LN10f ln_ten + constexpr float log2e_f = 1.44269504e+0f; // log2(e) log2ef M_LOG2Ef + constexpr float log10e_f = 4.34294482e-1f; // log10(e) log10ef M_LOG10Ef + constexpr float pi_f = 3.14159265e+0f; // π pif M_PIf + constexpr float mul2_pi_f = 6.28318531e+0f; // 2π two_pi + constexpr float inv_pi_f = 3.18309886e-1f; // 1÷π inv_pif M_1_PIf one_over_pi + constexpr float inv_mul2_pi_f = 1.59154943e-1f; // 1÷2π one_over_two_pi + constexpr float div2_pi_f = 6.36619772e-1f; // 2÷π M_2_PIf two_over_pi + constexpr float div180_pi_f = 57.2957795e+0f; // 180÷π + constexpr float divpi_2_f = 1.57079633e+0f; // π÷2 M_PI_2f half_pi + constexpr float divpi_4_f = 7.85398163e-1f; // π÷4 M_PI_4f quarter_pi + constexpr float divpi_90_f = 3.49065850e-2f; // π÷90 + constexpr float divpi_180_f = 1.74532925e-2f; // π÷180 + constexpr float divpi_360_f = 8.72664626e-3f; // π÷360 + constexpr float sqrtpi_f = 1.77245385e+0f; // √π sqrtpif root_pi + constexpr float sqrt2_f = 1.41421356e+0f; // √2 sqrt2f M_SQRT2f root_two + constexpr float sqrt3_f = 1.73205081e+0f; // √3 sqrt3f root_three + constexpr float inv_sqrtpi_f = 1.77245385e+0f; // 1÷√π inv_sqrtpif + constexpr float inv_sqrt2_f = 7.07106781e-1f; // 1÷√2 inv_sqrt2f M_SQRT1_2f one_over_root_two + constexpr float inv_sqrt3_f = 5.77350269e-1f; // 1÷√3 inv_sqrt3f + constexpr float div2_sqrtpi_f = 1.12837917e+0f; // 2÷√π M_2_SQRTPIf two_over_root_pi + constexpr float inv_3_f = 3.33333333e-1f; // 1÷3 third + constexpr float div2_3_f = 6.66666667e-1f; // 2÷3 two_third + + // Type Name Value Operation std::numbers GNU GLM + constexpr double phi_d = 1.6180339887498948482e+0; // φ phi golden_ratio + constexpr double egamma_d = 1.5674682557740530749e+0; // Γe egamma + constexpr double ln2_d = 6.9314718055994530942e-1; // ln(2) ln2 M_LN2 ln_two + constexpr double ln10_d = 2.3025850929940456840e+0; // ln(10) ln10 M_LN10 ln_ten + constexpr double log2e_d = 1.4426950408889634074e+0; // log2(e) log2e M_LOG2E + constexpr double log10e_d = 4.3429448190325182765e-1; // log10(e) log10e M_LOG10E + constexpr double pi_d = 3.1415926535897932385e+0; // π pi M_PI + constexpr double mul2_pi_d = 6.2831853071795864769e+0; // 2π two_pi + constexpr double inv_pi_d = 3.1830988618379067154e-1; // 1÷π inv_pi M_1_PI one_over_pi + constexpr double inv_mul2_pi_d = 1.5915494309189533577e-1; // 1÷2π one_over_two_pi + constexpr double div2_pi_d = 6.3661977236758134308e-1; // 2÷π M_2_PI two_over_pi + constexpr double div180_pi_d = 57.295779513082320877e+0; // 180÷π + constexpr double divpi_2_d = 1.5707963267948966192e+0; // π÷2 M_PI_2 half_pi + constexpr double divpi_4_d = 7.8539816339744830962e-1; // π÷4 M_PI_4 quarter_pi + constexpr double divpi_90_d = 3.4906585039886591538e-2; // π÷90 + constexpr double divpi_180_d = 1.7453292519943295769e-2; // π÷180 + constexpr double divpi_360_d = 8.7266462599716478846e-3; // π÷360 + constexpr double sqrtpi_d = 1.7724538509055160273e+0; // √π sqrtpi root_pi + constexpr double sqrt2_d = 1.4142135623730950488e+0; // √2 sqrt2 M_SQRT2 root_two + constexpr double sqrt3_d = 1.7320508075688772935e+0; // √3 sqrt3 root_three + constexpr double inv_sqrtpi_d = 1.7724538509055160273e+0; // 1÷√π inv_sqrtpi + constexpr double inv_sqrt2_d = 7.0710678118654752440e-1; // 1÷√2 inv_sqrt2 M_SQRT1_2 one_over_root_two + constexpr double inv_sqrt3_d = 5.7735026918962576451e-1; // 1÷√3 inv_sqrt3 + constexpr double div2_sqrtpi_d = 1.1283791670955125739e+0; // 2÷√π M_2_SQRTPI two_over_root_pi + constexpr double inv_3_d = 3.3333333333333333333e-1; // 1÷3 third + constexpr double div2_3_d = 6.6666666666666666667e-1; // 2÷3 two_third +} + +#endif // COMMON_MATH_CONSTANTS_H_ diff --git a/src/engine/audio/Audio.cpp b/src/engine/audio/Audio.cpp index f6a7d42412..bfeb6e70eb 100644 --- a/src/engine/audio/Audio.cpp +++ b/src/engine/audio/Audio.cpp @@ -669,7 +669,7 @@ namespace Audio { const float PERCEPTUAL_C = 0.866224835960518f; const float PERCEPTUAL_D = 0.187108105667604f; - return std::pow(10.0f, (perceptual - PERCEPTUAL_D) / 3.0f) - PERCEPTUAL_C; + return std::pow(10.0f, (perceptual - PERCEPTUAL_D) * Math::inv_3_f) - PERCEPTUAL_C; } float SliderToAmplitude(float slider) { diff --git a/src/engine/client/cl_scrn.cpp b/src/engine/client/cl_scrn.cpp index 4b4035315d..a671b1109d 100644 --- a/src/engine/client/cl_scrn.cpp +++ b/src/engine/client/cl_scrn.cpp @@ -113,7 +113,7 @@ void SCR_DrawConsoleFontUnichar( float x, float y, int ch ) { glyphInfo_t *glyph = Glyph( ch ); float yadj = glyph->top; - float xadj = ( SCR_ConsoleFontUnicharWidth( ch ) - glyph->xSkip ) / 2.0; + float xadj = ( SCR_ConsoleFontUnicharWidth( ch ) - glyph->xSkip ) * 0.5f; re.DrawStretchPic( x + xadj, y - yadj, glyph->imageWidth, glyph->imageHeight, glyph->s, glyph->t, diff --git a/src/engine/qcommon/q_math.cpp b/src/engine/qcommon/q_math.cpp index f3af5b8e6e..214ec6c87d 100644 --- a/src/engine/qcommon/q_math.cpp +++ b/src/engine/qcommon/q_math.cpp @@ -394,7 +394,7 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float sind, cosd, expr; vec3_t dxp; - degrees = DEG2RAD( degrees ); + degrees = Math::DegToRad( degrees ); sind = sinf( degrees ); cosd = cosf( degrees ); expr = ( 1 - cosd ) * DotProduct( dir, point ); @@ -452,7 +452,7 @@ void vectoangles( const vec3_t value1, vec3_t angles ) { if ( value1[ 0 ] ) { - yaw = RAD2DEG( atan2f( value1[ 1 ], value1[ 0 ] ) ); + yaw = Math::RadToDeg( atan2f( value1[ 1 ], value1[ 0 ] ) ); } else if ( value1[ 1 ] > 0 ) @@ -471,7 +471,7 @@ void vectoangles( const vec3_t value1, vec3_t angles ) } forward = sqrtf( value1[ 0 ] * value1[ 0 ] + value1[ 1 ] * value1[ 1 ] ); - pitch = RAD2DEG( atan2f( value1[ 2 ], forward ) ); + pitch = Math::RadToDeg( atan2f( value1[ 2 ], forward ) ); if ( pitch < 0 ) { @@ -705,7 +705,7 @@ float AngleBetweenVectors( const vec3_t a, const vec3_t b ) // this results in: // // angle = acos( (a * b) / (|a| * |b|) ) - return RAD2DEG( acosf( DotProduct( a, b ) / ( alen * blen ) ) ); + return Math::RadToDeg( acosf( DotProduct( a, b ) / ( alen * blen ) ) ); } //============================================================ @@ -1011,15 +1011,15 @@ void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up // static to help MS compiler fp bugs - angle = DEG2RAD( angles[ YAW ] ); + angle = Math::DegToRad( angles[ YAW ] ); sy = sinf( angle ); cy = cosf( angle ); - angle = DEG2RAD( angles[ PITCH ] ); + angle = Math::DegToRad( angles[ PITCH ] ); sp = sinf( angle ); cp = cosf( angle ); - angle = DEG2RAD( angles[ ROLL ] ); + angle = Math::DegToRad( angles[ ROLL ] ); sr = sinf( angle ); cr = cosf( angle ); @@ -1355,7 +1355,7 @@ void AxisToAngles( /*const*/ vec3_t axis[ 3 ], vec3_t angles ) { if ( axis[ 0 ][ 0 ] ) { - yaw = RAD2DEG( atan2f( axis[ 0 ][ 1 ], axis[ 0 ][ 0 ] ) ); + yaw = Math::RadToDeg( atan2f( axis[ 0 ][ 1 ], axis[ 0 ][ 0 ] ) ); } else if ( axis[ 0 ][ 1 ] > 0 ) @@ -1374,14 +1374,14 @@ void AxisToAngles( /*const*/ vec3_t axis[ 3 ], vec3_t angles ) } length1 = sqrtf( axis[ 0 ][ 0 ] * axis[ 0 ][ 0 ] + axis[ 0 ][ 1 ] * axis[ 0 ][ 1 ] ); - pitch = RAD2DEG( atan2f( axis[ 0 ][ 2 ], length1 ) ); + pitch = Math::RadToDeg( atan2f( axis[ 0 ][ 2 ], length1 ) ); if ( pitch < 0 ) { pitch += 360; } - roll = RAD2DEG( atan2f( axis[ 1 ][ 2 ], axis[ 2 ][ 2 ] ) ); + roll = Math::RadToDeg( atan2f( axis[ 1 ][ 2 ], axis[ 2 ][ 2 ] ) ); if ( roll < 0 ) { @@ -1577,7 +1577,7 @@ bool MatrixInverse( matrix_t matrix ) } void MatrixSetupXRotation( matrix_t m, vec_t degrees ) { - vec_t a = DEG2RAD( degrees ); + vec_t a = Math::DegToRad( degrees ); m[ 0 ] = 1; m[ 4 ] = 0; @@ -1598,7 +1598,7 @@ void MatrixSetupXRotation( matrix_t m, vec_t degrees ) } void MatrixSetupYRotation( matrix_t m, vec_t degrees ) { - vec_t a = DEG2RAD( degrees ); + vec_t a = Math::DegToRad( degrees ); m[ 0 ] = cosf( a ); m[ 4 ] = 0; @@ -1619,7 +1619,7 @@ void MatrixSetupYRotation( matrix_t m, vec_t degrees ) } void MatrixSetupZRotation( matrix_t m, vec_t degrees ) { - vec_t a = DEG2RAD( degrees ); + vec_t a = Math::DegToRad( degrees ); m[ 0 ] = cosf( a ); m[ 4 ] = -sinf( a ); @@ -1774,7 +1774,7 @@ void MatrixMultiplyRotation( matrix_t m, vec_t pitch, vec_t yaw, vec_t roll ) void MatrixMultiplyZRotation( matrix_t m, vec_t degrees ) { matrix_t tmp; - float angle = DEG2RAD( degrees ); + float angle = Math::DegToRad( degrees ); float s = sinf( angle ); float c = cosf( angle ); @@ -1857,15 +1857,15 @@ void MatrixToAngles( const matrix_t m, vec3_t angles ) if ( cp > 8192 * FLT_EPSILON ) { - angles[ PITCH ] = RAD2DEG( theta ); - angles[ YAW ] = RAD2DEG( atan2f( m[ 1 ], m[ 0 ] ) ); - angles[ ROLL ] = RAD2DEG( atan2f( m[ 6 ], m[ 10 ] ) ); + angles[ PITCH ] = Math::RadToDeg( theta ); + angles[ YAW ] = Math::RadToDeg( atan2f( m[ 1 ], m[ 0 ] ) ); + angles[ ROLL ] = Math::RadToDeg( atan2f( m[ 6 ], m[ 10 ] ) ); } else { - angles[ PITCH ] = RAD2DEG( theta ); - angles[ YAW ] = RAD2DEG( -atan2f( m[ 4 ], m[ 5 ] ) ); + angles[ PITCH ] = Math::RadToDeg( theta ); + angles[ YAW ] = Math::RadToDeg( -atan2f( m[ 4 ], m[ 5 ] ) ); angles[ ROLL ] = 0; } @@ -1878,16 +1878,16 @@ void MatrixToAngles( const matrix_t m, vec3_t angles ) if ( fabsf( ca ) > 0.005f ) // Gimbal lock? { - angles[ PITCH ] = RAD2DEG( atan2f( m[ 6 ] / ca, m[ 10 ] / ca ) ); - angles[ YAW ] = RAD2DEG( a ); - angles[ ROLL ] = RAD2DEG( atan2f( m[ 1 ] / ca, m[ 0 ] / ca ) ); + angles[ PITCH ] = Math::RadToDeg( atan2f( m[ 6 ] / ca, m[ 10 ] / ca ) ); + angles[ YAW ] = Math::RadToDeg( a ); + angles[ ROLL ] = Math::RadToDeg( atan2f( m[ 1 ] / ca, m[ 0 ] / ca ) ); } else { // Gimbal lock has occurred - angles[ PITCH ] = RAD2DEG( atan2f( -m[ 9 ], m[ 5 ] ) ); - angles[ YAW ] = RAD2DEG( a ); + angles[ PITCH ] = Math::RadToDeg( atan2f( -m[ 9 ], m[ 5 ] ) ); + angles[ YAW ] = Math::RadToDeg( a ); angles[ ROLL ] = 0; } @@ -1900,14 +1900,14 @@ void MatrixFromAngles( matrix_t m, vec_t pitch, vec_t yaw, vec_t roll ) static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - sp = sinf( DEG2RAD( pitch ) ); - cp = cosf( DEG2RAD( pitch ) ); + sp = sinf( Math::DegToRad( pitch ) ); + cp = cosf( Math::DegToRad( pitch ) ); - sy = sinf( DEG2RAD( yaw ) ); - cy = cosf( DEG2RAD( yaw ) ); + sy = sinf( Math::DegToRad( yaw ) ); + cy = cosf( Math::DegToRad( yaw ) ); - sr = sinf( DEG2RAD( roll ) ); - cr = cosf( DEG2RAD( roll ) ); + sr = sinf( Math::DegToRad( roll ) ); + cr = cosf( Math::DegToRad( roll ) ); m[ 0 ] = cp * cy; m[ 4 ] = ( sr * sp * cy + cr * -sy ); @@ -2467,7 +2467,7 @@ void MatrixPerspectiveProjectionFovYAspectLH( matrix_t m, vec_t fov, vec_t aspec { vec_t width, height; - width = tanf( DEG2RAD( fov * 0.5f ) ); + width = tanf( Math::DegToRad( fov * 0.5f ) ); height = width / aspect; m[ 0 ] = 1 / width; @@ -2491,8 +2491,8 @@ void MatrixPerspectiveProjectionFovXYLH( matrix_t m, vec_t fovX, vec_t fovY, vec { vec_t width, height; - width = tanf( DEG2RAD( fovX * 0.5f ) ); - height = tanf( DEG2RAD( fovY * 0.5f ) ); + width = tanf( Math::DegToRad( fovX * 0.5f ) ); + height = tanf( Math::DegToRad( fovY * 0.5f ) ); m[ 0 ] = 1 / width; m[ 4 ] = 0; @@ -2516,8 +2516,8 @@ void MatrixPerspectiveProjectionFovXYRH( matrix_t m, vec_t fovX, vec_t fovY, vec { vec_t width, height; - width = tanf( DEG2RAD( fovX * 0.5f ) ); - height = tanf( DEG2RAD( fovY * 0.5f ) ); + width = tanf( Math::DegToRad( fovX * 0.5f ) ); + height = tanf( Math::DegToRad( fovY * 0.5f ) ); m[ 0 ] = 1 / width; m[ 4 ] = 0; @@ -2542,8 +2542,8 @@ void MatrixPerspectiveProjectionFovXYInfiniteRH( matrix_t m, vec_t fovX, vec_t f { vec_t width, height; - width = tanf( DEG2RAD( fovX * 0.5f ) ); - height = tanf( DEG2RAD( fovY * 0.5f ) ); + width = tanf( Math::DegToRad( fovX * 0.5f ) ); + height = tanf( Math::DegToRad( fovY * 0.5f ) ); m[ 0 ] = 1 / width; m[ 4 ] = 0; @@ -2839,14 +2839,14 @@ void QuatFromAngles( quat_t q, vec_t pitch, vec_t yaw, vec_t roll ) static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs - sp = sinf(DEG2RAD(pitch) * 0.5); - cp = cosf(DEG2RAD(pitch) * 0.5); + sp = sinf(Math::DegToRad(pitch) * 0.5); + cp = cosf(Math::DegToRad(pitch) * 0.5); - sy = sinf(DEG2RAD(yaw) * 0.5); - cy = cosf(DEG2RAD(yaw) * 0.5); + sy = sinf(Math::DegToRad(yaw) * 0.5); + cy = cosf(Math::DegToRad(yaw) * 0.5); - sr = sinf(DEG2RAD(roll) * 0.5); - cr = cosf(DEG2RAD(roll) * 0.5); + sr = sinf(Math::DegToRad(roll) * 0.5); + cr = cosf(Math::DegToRad(roll) * 0.5); q[0] = sr * cp * cy - cr * sp * sy; // x q[1] = cr * sp * cy + sr * cp * sy; // y @@ -3011,7 +3011,7 @@ void QuatToAngles( const quat_t q, vec3_t angles ) if ( test > 0.4995 ) { - angles[YAW] = RAD2DEG(-2 * atan2f(q[0], q[3])); + angles[YAW] = Math::RadToDeg(-2 * atan2f(q[0], q[3])); angles[PITCH] = 90; angles[ROLL] = 0; return; @@ -3019,21 +3019,21 @@ void QuatToAngles( const quat_t q, vec3_t angles ) if ( test < -0.4995 ) { - angles[YAW] = RAD2DEG(2 * atan2f(q[0], q[3])); + angles[YAW] = Math::RadToDeg(2 * atan2f(q[0], q[3])); angles[PITCH] = -90; angles[ROLL] = 0; return; } // original for normalized quaternions: - // angles[PITCH] = RAD2DEG(asinf( 2.0f * (q[3] * q[1] - q[2] * q[0]))); - // angles[YAW] = RAD2DEG(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), 1.0f - 2.0f * (q2[1] + q2[2]))); - // angles[ROLL] = RAD2DEG(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), 1.0f - 2.0f * (q2[0] + q2[1]))); + // angles[PITCH] = Math::RadToDeg(asinf( 2.0f * (q[3] * q[1] - q[2] * q[0]))); + // angles[YAW] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), 1.0f - 2.0f * (q2[1] + q2[2]))); + // angles[ROLL] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), 1.0f - 2.0f * (q2[0] + q2[1]))); // optimized to work with both normalized and unnormalized quaternions: - angles[PITCH] = RAD2DEG(asinf(2.0f * test)); - angles[YAW] = RAD2DEG(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), q2[0] - q2[1] - q2[2] + q2[3])); - angles[ROLL] = RAD2DEG(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), -q2[0] - q2[1] + q2[2] + q2[3])); + angles[PITCH] = Math::RadToDeg(asinf(2.0f * test)); + angles[YAW] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[2] + q[0] * q[1]), q2[0] - q2[1] - q2[2] + q2[3])); + angles[ROLL] = Math::RadToDeg(atan2f(2.0f * (q[3] * q[0] + q[1] * q[2]), -q2[0] - q2[1] + q2[2] + q2[3])); } void QuatMultiply( const quat_t qa, const quat_t qb, quat_t qc ) diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index e5e6a2b1f4..902975dddf 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -274,15 +274,15 @@ void Com_Free_Aligned( void *ptr ); using fixed16_t = int; #ifndef M_PI -#define M_PI 3.14159265358979323846f // matches value in gcc v2 math.h +DEPRECATED static const float M_PI = 3.14159265358979323846f // matches value in gcc v2 math.h #endif #ifndef M_SQRT2 -#define M_SQRT2 1.414213562f +DEPRECATED static const float M_SQRT2 = 1.414213562f; #endif #ifndef M_ROOT3 -#define M_ROOT3 1.732050808f +DEPRECATED static const float M_ROOT3 = 1.732050808f; #endif #ifndef LINE_DISTANCE_EPSILON @@ -326,9 +326,6 @@ void Com_Free_Aligned( void *ptr ); // FIXME/KILLME: not implemented! #define S_SKIPNOTIFY "[skipnotify]" -#define DEG2RAD( a ) ( ( ( a ) * M_PI ) / 180.0f ) -#define RAD2DEG( a ) ( ( ( a ) * 180.0f ) / M_PI ) - struct cplane_t; extern const vec3_t vec3_origin; diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 3b7570fcbf..c7e8a5f61e 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -2223,11 +2223,11 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) const float id = ( float ) material.id / ( materialPacks[0].materials.size() + 2 ) + 1; - color[0] = std::min( id, 1 / 3.0f ) * 3.0 * colors[int( material.id * 6.0 + color[0] = std::min( id, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / materialPacks[0].materials.size() )][0]; - color[1] = Math::Clamp( id - 1 / 3.0, 0.0, 1 / 3.0 ) * 3.0 * colors[int( material.id * 6.0 + color[1] = Math::Clamp( id - Math::inv_3_f, 0.0f, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / materialPacks[0].materials.size() )][1]; - color[2] = Math::Clamp( id - 2 / 3.0, 0.0, 1 / 3.0 ) * 3.0 * colors[int( material.id * 6.0 + color[2] = Math::Clamp( id - Math::div2_3_f, 0.0f, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / materialPacks[0].materials.size() )][2]; break; @@ -2241,11 +2241,11 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) const float id = ( float ) ( material.id + 1 ) / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() + 2 ); - color[0] = std::min( id, 1 / 3.0f ) * 3.0 * colors[int( material.id * 6.0 + color[0] = std::min( id, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() ) )][0]; - color[1] = Math::Clamp( id - 1 / 3.0, 0.0, 1 / 3.0 ) * 3.0 * colors[int( material.id * 6.0 + color[1] = Math::Clamp( id - Math::inv_3_f, 0.0f, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() ) )][1]; - color[2] = Math::Clamp( id - 2 / 3.0, 0.0, 1 / 3.0 ) * 3.0 * colors[int( material.id * 6.0 + color[2] = Math::Clamp( id - Math::div2_3_f, 0.0f, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() ) )][2]; break; @@ -2259,11 +2259,11 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) const float id = ( float ) ( material.id + 1 ) / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() + 2 ) + 1; - color[0] = std::min( id, 1 / 3.0f ) * 3.0 * colors[int( material.id * 6.0 + color[0] = std::min( id, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() ) )][0]; - color[1] = Math::Clamp( id - 1 / 3.0, 0.0, 1 / 3.0 ) * 3.0 * colors[int( material.id * 6.0 + color[1] = Math::Clamp( id - Math::inv_3_f, 0.0f, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() ) )][1]; - color[2] = Math::Clamp( id - 2 / 3.0, 0.0, 1 / 3.0 ) * 3.0 * colors[int( material.id * 6.0 + color[2] = Math::Clamp( id - Math::div2_3_f, 0.0f, Math::inv_3_f ) * 3.0f * colors[int( material.id * 6.0f / ( materialPacks[1].materials.size() + materialPacks[2].materials.size() ) )][2]; break; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 7425f0854a..05258c152c 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -599,7 +599,7 @@ static std::string GenEngineConstants() { AddDefine( str, "r_SpecularScale", r_specularScale->value ); AddDefine( str, "r_zNear", r_znear->value ); - AddDefine( str, "M_PI", static_cast< float >( M_PI ) ); + AddDefine( str, "M_PI", Math::pi_f ); AddDefine( str, "MAX_SHADOWMAPS", MAX_SHADOWMAPS ); AddDefine( str, "MAX_REF_LIGHTS", MAX_REF_LIGHTS ); AddDefine( str, "NUM_LIGHT_LAYERS", glConfig2.realtimeLightLayers ); diff --git a/src/engine/renderer/glsl_source/skybox_fp.glsl b/src/engine/renderer/glsl_source/skybox_fp.glsl index 13f0fa2477..5c9529b78a 100644 --- a/src/engine/renderer/glsl_source/skybox_fp.glsl +++ b/src/engine/renderer/glsl_source/skybox_fp.glsl @@ -43,7 +43,7 @@ DECLARE_OUTPUT(vec4) // Parametric cloud function used by quake 3 skybox code float ComputeCloudParametric( vec3 skyVec, float radiusWorld, float cloudHeight ) { - return (1.0 / 2.0 * dot( skyVec, skyVec ) ) * ( -2.0 * skyVec.z * radiusWorld + return (0.5 * dot( skyVec, skyVec ) ) * ( -2.0 * skyVec.z * radiusWorld + 2.0 * sqrt( skyVec.z * skyVec.z * radiusWorld * radiusWorld + 2.0 * skyVec.x * skyVec.x * radiusWorld * cloudHeight + skyVec.x * skyVec.x * cloudHeight * cloudHeight + 2.0 * skyVec.y * skyVec.y * radiusWorld * cloudHeight diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index dd94ae68fd..cf17d73c30 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -2860,8 +2860,8 @@ void RB_RenderPostDepthLightTile() GL_Scissor( 0, 0, w, h ); gl_depthtile1Shader->BindProgram( 0 ); - zParams[ 0 ] = 2.0f * tanf( DEG2RAD( backEnd.refdef.fov_x * 0.5f) ) / glConfig.vidWidth; - zParams[ 1 ] = 2.0f * tanf( DEG2RAD( backEnd.refdef.fov_y * 0.5f) ) / glConfig.vidHeight; + zParams[ 0 ] = 2.0f * tanf( Math::DegToRad( backEnd.refdef.fov_x * 0.5f) ) / glConfig.vidWidth; + zParams[ 1 ] = 2.0f * tanf( Math::DegToRad( backEnd.refdef.fov_y * 0.5f) ) / glConfig.vidHeight; zParams[ 2 ] = backEnd.viewParms.zFar; gl_depthtile1Shader->SetUniform_zFar( zParams ); @@ -2901,8 +2901,8 @@ void RB_RenderPostDepthLightTile() GL_PopMatrix(); vec3_t projToViewParams; - projToViewParams[0] = tanf(DEG2RAD(backEnd.refdef.fov_x * 0.5f)) * backEnd.viewParms.zFar; - projToViewParams[1] = tanf(DEG2RAD(backEnd.refdef.fov_y * 0.5f)) * backEnd.viewParms.zFar; + projToViewParams[0] = tanf(Math::DegToRad(backEnd.refdef.fov_x * 0.5f)) * backEnd.viewParms.zFar; + projToViewParams[1] = tanf(Math::DegToRad(backEnd.refdef.fov_y * 0.5f)) * backEnd.viewParms.zFar; projToViewParams[2] = backEnd.viewParms.zFar; // render lights @@ -3224,8 +3224,8 @@ void RB_RenderSSAO() gl_ssaoShader->BindProgram( 0 ); vec3_t zParams; - zParams[ 0 ] = 2.0f * tanf( DEG2RAD( backEnd.refdef.fov_x * 0.5f ) ) / glConfig.vidWidth; - zParams[ 1 ] = 2.0f * tanf( DEG2RAD( backEnd.refdef.fov_y * 0.5f ) ) / glConfig.vidHeight; + zParams[ 0 ] = 2.0f * tanf( Math::DegToRad( backEnd.refdef.fov_x * 0.5f ) ) / glConfig.vidWidth; + zParams[ 1 ] = 2.0f * tanf( Math::DegToRad( backEnd.refdef.fov_y * 0.5f ) ) / glConfig.vidHeight; zParams[ 2 ] = backEnd.viewParms.zFar; gl_ssaoShader->SetUniform_zFar( zParams ); @@ -5182,8 +5182,8 @@ const RenderCommand *RotatedPicCommand::ExecuteSelf( ) const mx = x + ( w / 2 ); my = y + ( h / 2 ); - cosA = cosf( DEG2RAD( angle ) ); - sinA = sinf( DEG2RAD( angle ) ); + cosA = cosf( Math::DegToRad( angle ) ); + sinA = sinf( Math::DegToRad( angle ) ); cw = cosA * ( w / 2 ); ch = cosA * ( h / 2 ); sw = sinA * ( w / 2 ); diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index e8a56f282f..dda51a82fa 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4139,8 +4139,8 @@ void R_LoadLightGrid( lump_t *l ) // Lat = 0 at (1,0,0) to 360 (-1,0,0), encoded in 8-bit sine table format // Lng = 0 at (0,0,1) to 180 (0,0,-1), encoded in 8-bit sine table format - lat = DEG2RAD( in->latLong[ 1 ] * ( 360.0f / 255.0f ) ); - lng = DEG2RAD( in->latLong[ 0 ] * ( 360.0f / 255.0f ) ); + lat = Math::DegToRad( in->latLong[ 1 ] * ( 360.0f / 255.0f ) ); + lng = Math::DegToRad( in->latLong[ 0 ] * ( 360.0f / 255.0f ) ); direction[ 0 ] = cosf( lat ) * sinf( lng ); direction[ 1 ] = sinf( lat ) * sinf( lng ); diff --git a/src/engine/renderer/tr_image.cpp b/src/engine/renderer/tr_image.cpp index 3d5730e486..9b1b553019 100644 --- a/src/engine/renderer/tr_image.cpp +++ b/src/engine/renderer/tr_image.cpp @@ -2495,7 +2495,7 @@ static void R_CreateRandomNormalsImage() float r, angle; r = random(); - angle = 2.0f * M_PI * r; // / 360.0f; + angle = Math::mul2_pi_f * r; // / 360.0f; VectorSet( n, cosf( angle ), sinf( angle ), r ); VectorNormalize( n ); diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 73b1f619b6..6610e2dab6 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -1388,7 +1388,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p // init function tables for ( i = 0; i < FUNCTABLE_SIZE; i++ ) { - tr.sinTable[ i ] = sinf( DEG2RAD( i * 360.0f / ( ( float )( FUNCTABLE_SIZE - 1 ) ) ) ); + tr.sinTable[ i ] = sinf( Math::DegToRad( i * 360.0f / ( ( float )( FUNCTABLE_SIZE - 1 ) ) ) ); tr.squareTable[ i ] = ( i < FUNCTABLE_SIZE / 2 ) ? 1.0f : -1.0f; tr.sawToothTable[ i ] = ( float ) i / FUNCTABLE_SIZE; tr.inverseSawToothTable[ i ] = 1.0f - tr.sawToothTable[ i ]; diff --git a/src/engine/renderer/tr_light.cpp b/src/engine/renderer/tr_light.cpp index c134b3ea5f..668643f13e 100644 --- a/src/engine/renderer/tr_light.cpp +++ b/src/engine/renderer/tr_light.cpp @@ -1380,10 +1380,10 @@ byte R_CalcLightCubeSideBits( trRefLight_t *light, vec3_t worldBounds[ 2 ] ) zNear = 1.0f; zFar = light->sphereRadius; - xMax = zNear * tanf( fovX * M_PI / 360.0f ); + xMax = zNear * tanf( fovX * Math::divpi_360_f ); xMin = -xMax; - yMax = zNear * tanf( fovY * M_PI / 360.0f ); + yMax = zNear * tanf( fovY * Math::divpi_360_f ); yMin = -yMax; MatrixPerspectiveProjection( projectionMatrix, xMin, xMax, yMin, yMax, zNear, zFar ); diff --git a/src/engine/renderer/tr_main.cpp b/src/engine/renderer/tr_main.cpp index 1c9e785dbd..ee336f943b 100644 --- a/src/engine/renderer/tr_main.cpp +++ b/src/engine/renderer/tr_main.cpp @@ -985,7 +985,7 @@ static void R_SetupFrustum() } else { - ang = DEG2RAD( tr.viewParms.fovX * 0.5f ); + ang = Math::DegToRad( tr.viewParms.fovX * 0.5f ); xs = sinf( ang ); xc = cosf( ang ); @@ -995,7 +995,7 @@ static void R_SetupFrustum() VectorScale( tr.viewParms.orientation.axis[ 0 ], xs, tr.viewParms.frustums[ 0 ][ 1 ].normal ); VectorMA( tr.viewParms.frustums[ 0 ][ 1 ].normal, -xc, tr.viewParms.orientation.axis[ 1 ], tr.viewParms.frustums[ 0 ][ 1 ].normal ); - ang = DEG2RAD( tr.viewParms.fovY * 0.5f ); + ang = Math::DegToRad( tr.viewParms.fovY * 0.5f ); xs = sinf( ang ); xc = cosf( ang ); diff --git a/src/engine/renderer/tr_model_md3.cpp b/src/engine/renderer/tr_model_md3.cpp index 47620cf1a2..e62685eef2 100644 --- a/src/engine/renderer/tr_model_md3.cpp +++ b/src/engine/renderer/tr_model_md3.cpp @@ -218,8 +218,8 @@ bool R_LoadMD3( model_t *mod, int lod, const void *buffer, const char *modName ) v->xyz[ 1 ] = LittleShort( md3xyz->xyz[ 1 ] ) * MD3_XYZ_SCALE; v->xyz[ 2 ] = LittleShort( md3xyz->xyz[ 2 ] ) * MD3_XYZ_SCALE; - lat = (latLng >> 8) * (2.0f * M_PI / 255.0f); - lng = (latLng & 255) * (2.0f * M_PI / 255.0f); + lat = (latLng >> 8) * (Math::mul2_pi_f / 255.0f); + lng = (latLng & 255) * (Math::mul2_pi_f / 255.0f); n->normal[ 0 ] = cosf ( lat ) * sinf ( lng ); n->normal[ 1 ] = sinf ( lat ) * sinf ( lng ); n->normal[ 2 ] = cosf ( lng ); diff --git a/src/engine/renderer/tr_shade_calc.cpp b/src/engine/renderer/tr_shade_calc.cpp index 05e936c39e..ec8b557b13 100644 --- a/src/engine/renderer/tr_shade_calc.cpp +++ b/src/engine/renderer/tr_shade_calc.cpp @@ -495,7 +495,7 @@ static void AutospriteDeform( uint32_t numVertexes ) VectorCopy( backEnd.viewParms.orientation.axis[ 2 ], upDir ); } - float scale = 1.0 / M_SQRT2; + float scale = Math::inv_sqrt2_f; if ( backEnd.currentEntity->e.nonNormalizedAxes ) { diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index e6b91c1960..8ee9042899 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -4120,7 +4120,7 @@ static bool ParseShader( const char *_text ) continue; } - a = DEG2RAD( atof( token ) ); + a = Math::DegToRad( atof( token ) ); token = COM_ParseExt2( text, false ); @@ -4130,7 +4130,7 @@ static bool ParseShader( const char *_text ) continue; } - b = DEG2RAD( atof( token ) ); + b = Math::DegToRad( atof( token ) ); tr.sunDirection[ 0 ] = cosf( a ) * cosf( b ); tr.sunDirection[ 1 ] = sinf( a ) * cosf( b ); diff --git a/src/engine/renderer/tr_video.cpp b/src/engine/renderer/tr_video.cpp index ab8adb1e3b..d891fcc29a 100644 --- a/src/engine/renderer/tr_video.cpp +++ b/src/engine/renderer/tr_video.cpp @@ -339,10 +339,10 @@ static void blitVQQuad32fs( roqVideo_t &video, const std::vector &file ) static void ROQ_GenYUVTables() { - float t_ub = ( 1.77200f / 2.0f ) * ( float )( 1 << 6 ) + 0.5f; - float t_vr = ( 1.40200f / 2.0f ) * ( float )( 1 << 6 ) + 0.5f; - float t_ug = ( 0.34414f / 2.0f ) * ( float )( 1 << 6 ) + 0.5f; - float t_vg = ( 0.71414f / 2.0f ) * ( float )( 1 << 6 ) + 0.5f; + float t_ub = ( 1.77200f * 0.5f ) * ( float )( 1 << 6 ) + 0.5f; + float t_vr = ( 1.40200f * 0.5f ) * ( float )( 1 << 6 ) + 0.5f; + float t_ug = ( 0.34414f * 0.5f ) * ( float )( 1 << 6 ) + 0.5f; + float t_vg = ( 0.71414f * 0.5f ) * ( float )( 1 << 6 ) + 0.5f; for ( int i = 0; i < 256; i++ ) { diff --git a/tools/math-constants/math-constants.py b/tools/math-constants/math-constants.py new file mode 100755 index 0000000000..c67a6243ea --- /dev/null +++ b/tools/math-constants/math-constants.py @@ -0,0 +1,455 @@ +#! /usr/bin/env python3 + +import os +from mpmath import * + +script_realpath = os.path.realpath(__file__) +root_dir = os.path.dirname(os.path.dirname(os.path.dirname(script_realpath))) +script_path = os.path.relpath(script_realpath, root_dir) +file_path = "src/common/math/Constants.h" +file_realpath = os.path.join(root_dir, file_path) +file_handle = open(file_realpath, "w") + +header = "// Generated with {}\n".format(script_path) +header += "// Do not modify!" + +header_id = "COMMON_MATH_CONSTANTS_H_" + +write_float = True +write_double = True +write_long_double = False + +# GLM constants not defined there: +# zero, one, three_over_two_pi, four_over_pi, root_half_pi, root_two_pi, +# root_ln_four, e, euler, root_five, ln_ln_two. + +constants = [] + +class _phi: + name = "phi" + gnu = "" + std = "phi" + glm = "golden_ratio" + operation = "φ" + def compute(): return mp.phi + +constants.append(_phi) + +class _egamma: + name = "egamma" + gnu = "" + std = "egamma" + glm = "" + operation = "Γe" + def compute(): return gamma(e) + +constants.append(_egamma) + +class _ln2: + name = "ln2" + gnu = "M_LN2" + std = "ln2" + glm = "ln_two" + operation = "ln(2)" + def compute(): return ln(2) + +constants.append(_ln2) + +class _ln10: + name = "ln10" + gnu = "M_LN10" + std = "ln10" + glm = "ln_ten" + operation = "ln(10)" + def compute(): return ln(10) + +constants.append(_ln10) + +class _log2e: + name = "log2e" + gnu = "M_LOG2E" + std = "log2e" + glm = "" + operation = "log2(e)" + def compute(): return log(mp.e, 2) + +constants.append(_log2e) + +class _log10e: + name = "log10e" + gnu = "M_LOG10E" + std = "log10e" + glm = "" + operation = "log10(e)" + def compute(): return log(mp.e, 10) + +constants.append(_log10e) + +class _pi: + name = "pi" + gnu = "M_PI" + std = "pi" + glm = "" + operation = "π" + def compute(): return mp.pi + +constants.append(_pi) + +class _mul2_pi: + name = "mul2_pi" + gnu = "" + std = "" + glm = "two_pi" + operation = "2π" + def compute(): return fmul(2, mp.pi) + +constants.append(_mul2_pi) + +class _inv_pi: + name = "inv_pi" + gnu = "M_1_PI" + std = "inv_pi" + glm = "one_over_pi" + operation = "1÷π" + def compute(): return fdiv(1, mp.pi) + +constants.append(_inv_pi) + +class _inv_mul2_pi: + name = "inv_mul2_pi" + gnu = "" + std = "" + glm = "one_over_two_pi" + operation = "1÷2π" + def compute(): return fdiv(1, fmul(2, mp.pi)) + +constants.append(_inv_mul2_pi) + +class _div2_pi: + name = "div2_pi" + gnu = "M_2_PI" + std = "" + glm = "two_over_pi" + operation = "2÷π" + def compute(): return fdiv(2, mp.pi) + +constants.append(_div2_pi) + +class _div180_pi: + name = "div180_pi" + gnu = "" + std = "" + glm = "" + operation = "180÷π" + def compute(): return fdiv(180, mp.pi) + +constants.append(_div180_pi) + +class _divpi_2: + name = "divpi_2" + gnu = "M_PI_2" + std = "" + glm = "half_pi" + operation = "π÷2" + def compute(): return fdiv(mp.pi, 2) + +constants.append(_divpi_2) + +class _divpi_4: + name = "divpi_4" + gnu = "M_PI_4" + std = "" + glm = "quarter_pi" + operation = "π÷4" + def compute(): return fdiv(mp.pi, 4) + +constants.append(_divpi_4) + +class _divpi_90: + name = "divpi_90" + gnu = "" + std = "" + glm = "" + operation = "π÷90" + def compute(): return fdiv(mp.pi, 90) + +constants.append(_divpi_90) + +class _divpi_180: + name = "divpi_180" + gnu = "" + std = "" + glm = "" + operation = "π÷180" + def compute(): return fdiv(mp.pi, 180) + +constants.append(_divpi_180) + +class _divpi_360: + name = "divpi_360" + gnu = "" + std = "" + glm = "" + operation = "π÷360" + def compute(): return fdiv(mp.pi, 360) + +constants.append(_divpi_360) + +class _sqrtpi: + name = "sqrtpi" + gnu = "" + std = "sqrtpi" + glm = "root_pi" + operation = "√π" + def compute(): return sqrt(mp.pi) + +constants.append(_sqrtpi) + +class _sqrt2: + name = "sqrt2" + gnu = "M_SQRT2" + std = "sqrt2" + glm = "root_two" + operation = "√2" + def compute(): return sqrt(2) + +constants.append(_sqrt2) + +class _sqrt3: + name = "sqrt3" + gnu = "" + std = "sqrt3" + glm = "root_three" + operation = "√3" + def compute(): return sqrt(3) + +constants.append(_sqrt3) + +class _inv_sqrtpi: + name = "inv_sqrtpi" + gnu = "" + std = "inv_sqrtpi" + glm = "" + operation = "1÷√π" + def compute(): return sqrt(mp.pi) + +constants.append(_inv_sqrtpi) + +class _inv_sqrt2: + name = "inv_sqrt2" + gnu = "M_SQRT1_2" + std = "inv_sqrt2" + glm = "one_over_root_two" + operation = "1÷√2" + def compute(): return fdiv(1, sqrt(2)) + +constants.append(_inv_sqrt2) + +class _inv_sqrt3: + name = "inv_sqrt3" + gnu = "" + std = "inv_sqrt3" + glm = "" + operation = "1÷√3" + def compute(): return fdiv(1, sqrt(3)) + +constants.append(_inv_sqrt3) + +class _div2_sqrtpi: + name = "div2_sqrtpi" + gnu = "M_2_SQRTPI" + std = "" + glm = "two_over_root_pi" + operation = "2÷√π" + def compute(): return fdiv(2, sqrt(mp.pi)) + +constants.append(_div2_sqrtpi) + +class _inv_3: + name = "inv_3" + gnu = "" + std = "" + glm = "third" + operation = "1÷3" + def compute(): return fdiv(1, 3) + +constants.append(_inv_3) + +class _div2_3: + name = "div2_3" + gnu = "" + std = "" + glm = "two_third" + operation = "2÷3" + def compute(): return fdiv(2, 3) + +constants.append(_div2_3) + +types = [] + +class _float: + name = "float" + slug = "_f" + suffix = "f" + has_std = True + std_suffix = "f" + precision = 9 + +if write_float: + types.append(_float) + +class _double: + name = "double" + slug = "_d" + suffix = "" + has_std = True + std_suffix = "" + precision = 20 + +if write_double: + types.append(_double) + +class _long_double: + name = "long double" + slug = "_l" + suffix = "l" + has_std = False + std_suffix = "" + precision = 37 + +if write_long_double: + types.append(_long_double) + +def beautify(v): + value = str(v); + e = 0 + + if value.startswith("0."): + value = value[1:] + + while value.startswith("."): + value = "{}{}{}".format(value[1], ".", value[2:]) + e -= 1 + + if value.startswith("0."): + value = value[1:] + + if "." in value: + if len(value) < mp.dps + 1: + value = "{}{}".format(value, "0") + + sign = ["+", "-"][e < 0] + exponent = "e{}{}".format(sign, abs(e)) + + return "{}{}".format(value, exponent) + +def output(string=""): + print(string) + print(string, file=file_handle) + +keyword = "constexpr" +value = "0" + +keyword_pad = len(keyword) +value_pad = len(value) + +type_head = "Type" +name_head = "Name" +value_head = "Value" +operation_head = "Operation" +gnu_head = "GNU" +std_head = "std::numbers" +glm_head = "GLM" + +output(header) +output() +output("#ifndef {}".format(header_id)) +output("#define {}".format(header_id)) +output() +output("namespace Math {") + +first = True + +for t in types: + if first: + first = False + else: + output() + + mp.dps = t.precision + + name_pad = len(name_head) + operation_pad = len(operation_head) + gnu_pad = len(gnu_head) + std_pad = [0, len(std_head)][t.has_std] + type_pad = len(t.name) + + for c in constants: + name = c.name + t.slug + + l = len(name) + if l > name_pad: + name_pad = l + + l = len(c.operation) + if l > operation_pad: + operation_pad = l + + if t.has_std: + l = len(c.std) + if l > std_pad: + std_pad = l + + gnu = c.gnu + + if gnu: + gnu = gnu + t.suffix + + l = len(gnu) + if l > gnu_pad: + gnu_pad = l + + value = beautify(c.compute()) + t.suffix + + l = len(value) + if l > value_pad: + value_pad = l + + operation_pad += 2 + std_pad += [0, 2][t.has_std] + gnu_pad += 2 + + std = ["", std_head][t.has_std] + + sizes = keyword_pad, type_pad, name_pad, value_pad, operation_pad, std_pad, gnu_pad + string = "\t{:<%s} {:<%s} {:<%s} {:<1} {:>%s}{:<1} {:<2} {:<%s}{:<%s}{:<%s}{}" % sizes + + fields = "//", type_head, name_head, "", value_head, "", "", operation_head, std, gnu_head, glm_head + output(string.format(*fields).rstrip()) + + for c in constants: + name = c.name + t.slug + + gnu = c.gnu + if gnu: + gnu = gnu + t.suffix + + if t.has_std: + std = c.std + if std: + std = std + t.std_suffix + else: + std = "" + + glm = c.glm + + value = beautify(c.compute()) + t.suffix + + fields = keyword, t.name, name, "=", value, ";", "//", c.operation, std, gnu, glm + output(string.format(*fields).rstrip()) + +output("}") +output() +output("#endif // {}".format(header_id)) + +file_handle.close()