00001 //--------------------------------------------------------------------------------- 00002 // File Name: Maths.h 00003 // Description: 00006 // 00007 // Copyright (C) 2004 - 2006 True Axis Pty Ltd, Australia. 00008 // All Rights Reserved. 00009 // 00010 // History: 00011 // Created File. 00012 //--------------------------------------------------------------------------------- 00013 00014 #ifndef TA_MATHS_H 00015 #define TA_MATHS_H 00016 00017 #ifndef TA_TYPES_H 00018 #include "Types.h" 00019 #endif // TA_TYPES_H 00020 00021 #ifndef TA_DEBUG_H 00022 #include "Debug.h" 00023 #endif // TA_DEBUG_H 00024 00025 #include <math.h> 00026 #include <float.h> 00027 00028 TA_OBFUSCATION_SKIP_PASS_2 00029 00030 namespace TA 00031 { 00032 00035 00037 00038 00039 TA_OBFUSCATION_RESERVED_FULL_ON 00040 //--------------------------------------------------------------------------------- 00041 // Maths constants 00042 //--------------------------------------------------------------------------------- 00043 const float k_fPi = 3.14159f; 00044 // SpellCheckerDisable 00045 const float k_fMaxFloat = FLT_MAX; 00046 const float k_fMinFloat = FLT_MIN; 00047 // SpellCheckerEnabled 00048 TA_OBFUSCATION_RESERVED_FULL_OFF 00049 00050 TA_OBFUSCATION_RESERVED_ON 00051 //--------------------------------------------------------------------------------- 00052 //--------------------------------------------------------------------------------- 00053 //inline float TAC_CALL Fabs(float fValue) { return (float)fabs(fValue); } 00054 inline float TAC_CALL Fabs(float fValue) { return (float)fabs((double)fValue); } 00055 00056 //--------------------------------------------------------------------------------- 00057 //--------------------------------------------------------------------------------- 00058 inline int TAC_CALL Abs(int nValue) 00059 { 00060 #ifdef TA_GCC 00061 return (nValue ^ (nValue >> (31))) + ((unsigned) nValue >> (31)); 00062 #else 00063 return abs(nValue); 00064 #endif 00065 } 00066 00067 //--------------------------------------------------------------------------------- 00068 //--------------------------------------------------------------------------------- 00069 inline float TAC_CALL Sign(float fValue) 00070 { 00071 // 0x3f800000 // hex representation of a floating point one 00072 u32 nSign = (((u32&)fValue) & 0x80000000) + 0x3f800000; 00073 return (float&)nSign; 00074 // return fValue >= 0.0f ? 1.0f : -1.0f; 00075 } 00076 00077 //--------------------------------------------------------------------------------- 00078 //--------------------------------------------------------------------------------- 00079 /*inline float TAC_CALL CopySign(float fTo, float fFrom) 00080 { 00081 // 0x3f800000 // hex representation of a floating point one 00082 //u32 nSign = (((u32&)fValue) & 0x80000000) + 0x3f800000; 00083 //return (float&)nSign; 00084 return (float&) ((u32&)fTo & 0x7FFFFFFF | (u32&)fFrom & 0x8000000); 00085 } */ 00086 00087 //--------------------------------------------------------------------------------- 00088 //--------------------------------------------------------------------------------- 00089 inline bool TAC_CALL SignsEqual(float fA, float fB) 00090 { 00091 return (((u32&)fA) & 0x80000000) == (((u32&)fB) & 0x80000000); 00092 } 00093 00094 //--------------------------------------------------------------------------------- 00095 //--------------------------------------------------------------------------------- 00096 inline float TAC_CALL Sqrt(float fValue) { return (float)sqrtf(fValue); } 00097 00098 //--------------------------------------------------------------------------------- 00099 //--------------------------------------------------------------------------------- 00100 inline float TAC_CALL ReciprocalSqrt(float fValue) { return 1.0f / (float)sqrtf(fValue); } 00101 00102 //--------------------------------------------------------------------------------- 00103 //--------------------------------------------------------------------------------- 00104 inline float TAC_CALL Pow(float fValue, float fExponent) { return (float)powf(fValue, fExponent); } 00105 00106 //--------------------------------------------------------------------------------- 00107 //--------------------------------------------------------------------------------- 00108 inline float Pow2(float fX) { return fX * fX; } 00109 00110 //--------------------------------------------------------------------------------- 00111 //--------------------------------------------------------------------------------- 00112 inline float TAC_CALL Sin(float fAngle) { return (float)sinf(fAngle); } 00113 00114 //--------------------------------------------------------------------------------- 00115 //--------------------------------------------------------------------------------- 00116 inline float TAC_CALL Cos(float fAngle) { return (float)cosf(fAngle); } 00117 00118 //--------------------------------------------------------------------------------- 00119 //--------------------------------------------------------------------------------- 00120 inline float TAC_CALL Tan(float fAngle) { return (float)tanf(fAngle); } 00121 00122 //--------------------------------------------------------------------------------- 00123 //--------------------------------------------------------------------------------- 00124 inline void TAC_CALL SinAndCos(float fAngle, float& fSin, float& fCos) 00125 { 00126 #ifdef TA_MSVC_X86_INLINE_ASM 00127 TA_OBFUSCATION_RESERVED_FULL_ON 00128 float fSin2_reserved; 00129 float fCos2_reserved; 00130 float fAngle_reserved; 00131 TA_OBFUSCATION_RESERVED_FULL_OFF 00132 fAngle_reserved = fAngle; 00133 __asm 00134 { 00135 fld fAngle_reserved 00136 fsincos 00137 fstp fCos2_reserved 00138 fstp fSin2_reserved 00139 } 00140 fCos = fCos2_reserved; 00141 fSin = fSin2_reserved; 00142 #else 00143 fSin = Sin(fAngle); 00144 fCos = Cos(fAngle); 00145 #endif 00146 } 00147 00148 //--------------------------------------------------------------------------------- 00149 //--------------------------------------------------------------------------------- 00150 inline float TAC_CALL ATan2(float fY, float fX) { return (float)atan2f(fY, fX); } 00151 00152 //--------------------------------------------------------------------------------- 00153 //--------------------------------------------------------------------------------- 00154 inline float TAC_CALL ACos(float fValue) { return (float)acosf(fValue); } 00155 00156 //--------------------------------------------------------------------------------- 00157 // Todo: test efficiency 00158 //--------------------------------------------------------------------------------- 00159 inline float TAC_CALL FMod(float fValue, float fMod) { return (float)fmodf(fValue, fMod); } 00160 00161 //--------------------------------------------------------------------------------- 00162 //--------------------------------------------------------------------------------- 00163 inline float TAC_CALL Exp(float fValue) { return (float)expf(fValue); } 00164 00165 //--------------------------------------------------------------------------------- 00166 //--------------------------------------------------------------------------------- 00167 inline float TAC_CALL Log(float fValue) { return (float)logf(fValue); } 00168 00169 //--------------------------------------------------------------------------------- 00170 //--------------------------------------------------------------------------------- 00171 inline bool TAC_CALL IsEqualToOneWithInError(float fValue) { return Fabs(1.0f - fValue) < 0.001f; } 00172 00173 //--------------------------------------------------------------------------------- 00174 //--------------------------------------------------------------------------------- 00175 inline void TAC_CALL Clamp(float& fValue, float const fMin, const float fMax) 00176 { 00177 if (fValue > fMax) 00178 fValue = fMax; 00179 else if (fValue < fMin) 00180 fValue = fMin; 00181 } 00182 00183 //--------------------------------------------------------------------------------- 00184 //--------------------------------------------------------------------------------- 00185 inline void TAC_CALL Clamp(int& nValue, const int nMin, int const nMax) 00186 { 00187 if (nValue > nMax) 00188 nValue = nMax; 00189 else if (nValue < nMin) 00190 nValue = nMin; 00191 } 00192 00193 //--------------------------------------------------------------------------------- 00194 //--------------------------------------------------------------------------------- 00195 inline void TAC_CALL ClampPosNeg(float& fValue, float fPositive) 00196 { 00197 if (fValue > fPositive) 00198 fValue = fPositive; 00199 else if (fValue < -fPositive) 00200 fValue = -fPositive; 00201 } 00202 00203 //--------------------------------------------------------------------------------- 00204 // Only wraps once: 00205 // if (fValue > k_kPi) 00206 // fValue -= k_kPi * 2.0f; 00207 // else if (fValue < -k_kPi) 00208 // fValue += k_kPi * 2.0f; 00209 //--------------------------------------------------------------------------------- 00210 inline void TAC_CALL WrapAngle(float& fValue) 00211 { 00212 if (fValue > k_fPi) 00213 fValue -= k_fPi * 2.0f; 00214 else if (fValue < -k_fPi) 00215 fValue += k_fPi * 2.0f; 00216 } 00217 00218 //--------------------------------------------------------------------------------- 00219 //--------------------------------------------------------------------------------- 00220 inline int TAC_CALL FastFloatToInt(float fValue) 00221 { 00222 TA_OBFUSCATION_RESERVED_FULL_ON 00223 int nReturnVal_reserved; 00224 float fValue_reserved; 00225 TA_OBFUSCATION_RESERVED_FULL_OFF 00226 fValue_reserved = fValue; 00227 #if defined (TA_GCC_X86_INLINE_ASM) 00228 return (int)fValue; 00229 //asm("fld %0 fistp %1" : "=r" (fValue) : "r" (nReturnVal)); 00230 #elif defined (TA_MSVC_X86_INLINE_ASM) 00231 __asm 00232 { 00233 fld fValue_reserved 00234 fistp nReturnVal_reserved 00235 } 00236 #else 00237 nReturnVal_reserved = (int)fValue_reserved; 00238 #endif 00239 return nReturnVal_reserved; 00240 } 00241 00242 //--------------------------------------------------------------------------------- 00243 //--------------------------------------------------------------------------------- 00244 inline bool TAC_CALL FloatIsOK(float fValue) { return ((*(int*)&fValue) & 0x7F800000) != 0x7F800000; } 00245 00246 //--------------------------------------------------------------------------------- 00247 // Not 100% accurate. 00248 // Whether it is faster or not may depend on where it is used. 00249 //--------------------------------------------------------------------------------- 00250 inline float TAC_CALL FastMin(float fA, float fB) { return (fA + fB - Fabs(fB - fA)) * 0.5f; } 00251 00252 //--------------------------------------------------------------------------------- 00253 // Not 100% accurate 00254 //--------------------------------------------------------------------------------- 00255 inline float TAC_CALL FastMax(float fA, float fB) { return (fA + fB + Fabs(fB - fA)) * 0.5f; } 00256 00257 //--------------------------------------------------------------------------------- 00258 //--------------------------------------------------------------------------------- 00259 inline float TAC_CALL Min(float fA, float fB) { return (fA < fB) ? fA : fB; } 00260 00261 //--------------------------------------------------------------------------------- 00262 //--------------------------------------------------------------------------------- 00263 inline float TAC_CALL Max(float fA, float fB) { return (fA > fB) ? fA : fB; } 00264 00265 //--------------------------------------------------------------------------------- 00266 //--------------------------------------------------------------------------------- 00267 inline void TAC_CALL ClampIfLessThen(float& fValue, float fClampTo) { if (fValue < fClampTo) fValue = fClampTo; } 00268 00269 //--------------------------------------------------------------------------------- 00270 //--------------------------------------------------------------------------------- 00271 inline void TAC_CALL ClampIfGreaterThen(float& fValue, float fClampTo) { if (fValue > fClampTo) fValue = fClampTo; } 00272 00273 //--------------------------------------------------------------------------------- 00274 //--------------------------------------------------------------------------------- 00275 template<class Type> 00276 inline void TAC_CALL Swap(Type& a, Type& b) { Type tmp = a; a = b; b = tmp; } 00277 00279 00281 TA_OBFUSCATION_RESERVED_OFF 00282 00283 }; 00284 00285 #endif //TA_MATHS_H 00286