////////////////////////////////////////////////////////////////////////////// // // floating point math functions // ////////////////////////////////////////////////////////////////////////////// #ifndef _zmath_H_ #define _zmath_H_ #include "float.h" ////////////////////////////////////////////////////////////////////////////// // // Constants // ////////////////////////////////////////////////////////////////////////////// const float pi = 3.14159265359f; const float sqrt2 = 1.41421356237f; // , fix these const int c_maxInt = 0x7fffffff; const int c_minInt = 0x80000000; inline const float RadiansFromDegrees(float value) { return value * pi / 180.0f; } inline const float DegreesFromRadians(float value) { return value * 180.0f / pi; } ////////////////////////////////////////////////////////////////////////////// // // Handy function for getting the next larger power of 2 // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // Return the next larger multiple of size. // ////////////////////////////////////////////////////////////////////////////// inline int NextMultipleOf(int size, int value) { return ((value + size - 1) / size) * size; } ////////////////////////////////////////////////////////////////////////////// // // Handy bit manipulation functions // ////////////////////////////////////////////////////////////////////////////// DWORD CountBits(DWORD dw); DWORD GetShift(DWORD dw); DWORD NextPowerOf2(DWORD x); inline DWORD PowerOf2(DWORD exponent) { return 1 << exponent; } inline DWORD MakeMask(int bits, int shift) { return (PowerOf2(bits) - 1) << shift; } ////////////////////////////////////////////////////////////////////////////// // // functions // ////////////////////////////////////////////////////////////////////////////// inline bool odd(int value) { return value >= 0 ? value & 1 : !(value & 1); } template inline ValueType bound(ValueType value, ValueType min, ValueType max) { return value < min ? min : (value > max ? max : value); } template inline void swap(Type& x, Type& y) { Type temp(x); x = y; y = temp; } ////////////////////////////////////////////////////////////////////////////// // // float functions // ////////////////////////////////////////////////////////////////////////////// template inline ValueType sign(ValueType x) { return x >= (ValueType)0 ? (ValueType)1 : (ValueType)-1; } // VS.Net 2003 port #if _MSC_VER < 1300 inline float abs(float x) { return x < 0 ? -x : x; } #endif inline float mod(float x, float limit) { if (limit == 0) { return 0; } else { return (float)fmod(x, limit); } } #ifdef DREAMCAST #include "floatmathlib.h" #else // VS.Net 2003 port #if _MSC_VER < 1300 inline float floor(float x) { return floorf(x); } inline float pow(float x, float y) { return powf(x, y); } inline float cos(float x) { return cosf(x); } inline float sin(float x) { return sinf(x); } inline float tan(float x) { return tanf(x); } inline float atan(float x) { return atanf(x); } inline float atan2(float x, float y) { return atan2f(x, y); } inline float log(float x) { return logf(x); } inline float sqrt(float x) { ZAssert(x >= 0); return sqrtf(x); } inline float acos(float x) { ZAssert(x >= -1 && x <= 1); return acosf(x); } inline float asin(float x) { ZAssert(x >= -1 && x <= 1); return asinf(x); } #endif #endif inline float random(float min, float max) { return (((float)rand()) / RAND_MAX) * (max * (1.0f - FLT_EPSILON) - min) + min; } ////////////////////////////////////////////////////////////////////////////// // // Interger functions // ////////////////////////////////////////////////////////////////////////////// inline int randomInt(int min, int max) { return min + (rand() % (1 + max - min)); } ////////////////////////////////////////////////////////////////////////////// // // Interpolation // ////////////////////////////////////////////////////////////////////////////// inline float SmoothInterpolant(float value) { return 0.5f - 0.5f * cos(pi * value); } template inline Type Interpolate(Type v1, Type v2, float value) { return ((1 - value) * v1) + (value * v2); } ////////////////////////////////////////////////////////////////////////////// // // TRange // ////////////////////////////////////////////////////////////////////////////// template class TRange { private: int m_value; void Validate() { while (m_value < 0 ) m_value += count; while (m_value >= count) m_value -= count; } public: TRange(int value) : m_value(value) { Validate(); } operator int() { return m_value; } TRange& operator=(int value) { m_value = value; Validate(); return *this; } TRange operator++() { TRange old = *this; m_value++; Validate(); return old; } TRange operator--() { TRange old = *this; m_value--; Validate(); return old; } TRange& operator++(int) { m_value++; Validate(); return *this; } TRange& operator--(int) { m_value--; Validate(); return *this; } TRange& operator+=(int value) { m_value += value; Validate(); return *this; } TRange& operator-=(int value) { m_value -= value; Validate(); return *this; } }; ////////////////////////////////////////////////////////////////////////////// // // A function object which maps from {} -> {} // ////////////////////////////////////////////////////////////////////////////// class NullFunc { public: void operator () () {}; }; ////////////////////////////////////////////////////////////////////////////// // // Fast floating point // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // Constants // ////////////////////////////////////////////////////////////////////////////// extern float g_0 ; extern float g_1 ; extern float g_0_5 ; extern float g_255 ; extern float g_Inv255; ////////////////////////////////////////////////////////////////////////////// // // Fast floating point // ////////////////////////////////////////////////////////////////////////////// #ifdef FLOATASM #define MakeIntMacro(value, result) _asm fld value _asm fistp result __forceinline int MakeInt(float value) { int result; MakeIntMacro(value, result); return result; } __forceinline int MakeInt(double value) { int result; MakeIntMacro(value, result); return result; } #else __forceinline int MakeIntMacro(const float& value, const int& result) { result = int(value); } __forceinline int MakeInt(float value) { return int(Value); } __forceinline int MakeInt(double value) { return int(value); } #endif __forceinline int FloorInt(float value) { return MakeInt(value - 0.5f); } #endif