Math.h 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. /******************************************************************************/
  2. enum DIST_TYPE // Distance Type
  3. {
  4. DIST_NONE , // none
  5. DIST_POINT0, // 0th point
  6. DIST_POINT1, // 1st point
  7. DIST_POINT2, // 2nd point
  8. DIST_POINT3, // 3rd point
  9. DIST_EDGE0 , // 0th edge
  10. DIST_EDGE1 , // 1st edge
  11. DIST_EDGE2 , // 2nd edge
  12. DIST_EDGE3 , // 3rd edge
  13. DIST_PLANE , // plane
  14. DIST_TRI , // triangle
  15. DIST_QUAD , // quad
  16. DIST_POINT=DIST_POINT0, // point
  17. DIST_EDGE =DIST_EDGE0 , // edge
  18. };
  19. /******************************************************************************/
  20. #if EE_PRIVATE
  21. struct Int24
  22. {
  23. Byte b[3];
  24. Bool negative()C {return (b[2]>>7)!=0;}
  25. Int asInt()C {Int out; CopyFast(&out, b, 3); ((Byte*)&out)[3]=(negative() ? 0xFF : 0); return out;}
  26. Int24& operator=(Int i) {CopyFast(b, &i, 3); return T;}
  27. };
  28. #endif
  29. /******************************************************************************/
  30. Bool Special(C Flt &r); // if 'r' is a special type float (NaN, -Inf, +Inf)
  31. Bool Special(C Dbl &r); // if 'r' is a special type double (NaN, -Inf, +Inf)
  32. Bool NaN (C Flt &r); // if 'r' is Not a Number
  33. Bool NaN (C Dbl &r); // if 'r' is Not a Number
  34. Bool Inf (C Flt &r); // if 'r' is Infinite
  35. Bool Inf (C Dbl &r); // if 'r' is Infinite
  36. #if EE_PRIVATE
  37. // minimum & maximum
  38. inline void MinMax ( Byte a, Byte b , Byte &min, Byte &max) {if(a<b){min=a; max=b;}else{min=b; max=a;}} // get min max values : min=Min(a, b); max=Max(a, b);
  39. inline void MinMax ( Int a, Int b , Int &min, Int &max) {if(a<b){min=a; max=b;}else{min=b; max=a;}} // get min max values : min=Min(a, b); max=Max(a, b);
  40. inline void MinMax ( Flt a, Flt b , Flt &min, Flt &max) {if(a<b){min=a; max=b;}else{min=b; max=a;}} // get min max values : min=Min(a, b); max=Max(a, b);
  41. inline void MinMax ( Dbl a, Dbl b , Dbl &min, Dbl &max) {if(a<b){min=a; max=b;}else{min=b; max=a;}} // get min max values : min=Min(a, b); max=Max(a, b);
  42. void MinMax (C Flt *f, Int elms, Flt &min, Flt &max); // get min max values : min =Min(f[]); max =Max(f[]);
  43. void MinMax (C Dbl *f, Int elms, Dbl &min, Dbl &max); // get min max values : min =Min(f[]); max =Max(f[]);
  44. void MinMaxI(C Flt *f, Int elms, Int &min, Int &max); // get min max index : f[min]=Min(f[]); f[max]=Max(f[]);
  45. void MinMaxI(C Dbl *f, Int elms, Int &min, Int &max); // get min max index : f[min]=Min(f[]); f[max]=Max(f[]);
  46. #endif
  47. // change sign
  48. inline void CHS(Int &x) {x=-x;}
  49. inline void CHS(Long &x) {x=-x;}
  50. inline void CHS(Flt &x) {((U32&) x) ^=SIGN_BIT;} // works as "x=-x;" but faster
  51. inline void CHS(Dbl &x) {((U32*)&x)[1]^=SIGN_BIT;} // works as "x=-x;" but faster
  52. #if EE_PRIVATE
  53. INLINE Bool NegativeSB(Flt x) {return FlagTest ((UInt&)x, SIGN_BIT);}
  54. INLINE void CHSSB(Flt &x) { FlagToggle ((UInt&)x, SIGN_BIT);}
  55. INLINE void ABSSB(Flt &x) { FlagDisable((UInt&)x, SIGN_BIT);}
  56. inline Flt Xor(Flt a, UInt b) {((U32&) a) ^=b; return a;} // used for fast changing of the 'a' sign, 'b' should be either 0 or SIGN_BIT
  57. inline Dbl Xor(Dbl a, UInt b) {((U32*)&a)[1]^=b; return a;} // used for fast changing of the 'a' sign, 'b' should be either 0 or SIGN_BIT
  58. void DecRealByBit(Flt &r); // increment real value by just 1 bit
  59. void DecRealByBit(Dbl &r); // increment real value by just 1 bit
  60. void IncRealByBit(Flt &r); // increment real value by just 1 bit
  61. void IncRealByBit(Dbl &r); // increment real value by just 1 bit
  62. #endif
  63. // get absolute value
  64. constexpr Int Abs( Int x) {return (x>=0) ? x : -x;}
  65. constexpr Long Abs( Long x) {return (x>=0) ? x : -x;}
  66. constexpr Flt Abs( Flt x) {return (x>=0) ? x : -x;}
  67. constexpr Dbl Abs( Dbl x) {return (x>=0) ? x : -x;}
  68. inline Vec2 Abs(C Vec2 &v) {return Vec2 (Abs(v.x), Abs(v.y) );}
  69. inline VecD2 Abs(C VecD2 &v) {return VecD2(Abs(v.x), Abs(v.y) );}
  70. inline VecI2 Abs(C VecI2 &v) {return VecI2(Abs(v.x), Abs(v.y) );}
  71. inline Vec Abs(C Vec &v) {return Vec (Abs(v.x), Abs(v.y), Abs(v.z) );}
  72. inline VecD Abs(C VecD &v) {return VecD (Abs(v.x), Abs(v.y), Abs(v.z) );}
  73. inline VecI Abs(C VecI &v) {return VecI (Abs(v.x), Abs(v.y), Abs(v.z) );}
  74. inline Vec4 Abs(C Vec4 &v) {return Vec4 (Abs(v.x), Abs(v.y), Abs(v.z), Abs(v.w));}
  75. inline VecD4 Abs(C VecD4 &v) {return VecD4(Abs(v.x), Abs(v.y), Abs(v.z), Abs(v.w));}
  76. inline VecI4 Abs(C VecI4 &v) {return VecI4(Abs(v.x), Abs(v.y), Abs(v.z), Abs(v.w));}
  77. // make absolute value
  78. inline void ABS(Int &x) {if(x<0)x=-x;} // works as "x=Abs(x);"
  79. inline void ABS(Long &x) {if(x<0)x=-x;} // works as "x=Abs(x);"
  80. inline void ABS(Flt &x) {((U32&) x) &=~SIGN_BIT;} // works as "x=Abs(x);"
  81. inline void ABS(Dbl &x) {((U32*)&x)[1]&=~SIGN_BIT;} // works as "x=Abs(x);"
  82. #if EE_PRIVATE
  83. // get absolute scale
  84. inline Flt AbsScale(Flt x, Flt base) {return (x>base) ? x/base : base/x;}
  85. inline Dbl AbsScale(Dbl x, Dbl base) {return (x>base) ? x/base : base/x;}
  86. #endif
  87. // get middle value
  88. constexpr Int Mid( Int x, Int min, Int max) {return (x>=max) ? max : (x<=min) ? min : x;}
  89. constexpr Long Mid( Long x, Long min, Long max) {return (x>=max) ? max : (x<=min) ? min : x;}
  90. constexpr Flt Mid( Flt x, Flt min, Flt max) {return (x>=max) ? max : (x<=min) ? min : x;}
  91. constexpr Dbl Mid( Dbl x, Dbl min, Dbl max) {return (x>=max) ? max : (x<=min) ? min : x;}
  92. inline Vec2 Mid(C Vec2 &v, C Vec2 &min, C Vec2 &max) {return Vec2(Mid(v.x, min.x, max.x), Mid(v.y, min.y, max.y) );}
  93. inline Vec Mid(C Vec &v, C Vec &min, C Vec &max) {return Vec (Mid(v.x, min.x, max.x), Mid(v.y, min.y, max.y), Mid(v.z, min.z, max.z) );}
  94. inline Vec4 Mid(C Vec4 &v, C Vec4 &min, C Vec4 &max) {return Vec4(Mid(v.x, min.x, max.x), Mid(v.y, min.y, max.y), Mid(v.z, min.z, max.z), Mid(v.w, min.w, max.w));}
  95. // get saturated (clamped to 0..1)
  96. constexpr Int Sat( Int x) {return Mid(x, 0 , 1 );}
  97. constexpr Long Sat( Long x) {return Mid(x, 0LL , 1LL );}
  98. constexpr Flt Sat( Flt x) {return Mid(x, 0.0f, 1.0f);}
  99. constexpr Dbl Sat( Dbl x) {return Mid(x, 0.0 , 1.0 );}
  100. inline Vec2 Sat(C Vec2 &v) {return Vec2 (Sat(v.x), Sat(v.y) );}
  101. inline VecD2 Sat(C VecD2 &v) {return VecD2(Sat(v.x), Sat(v.y) );}
  102. inline Vec Sat(C Vec &v) {return Vec (Sat(v.x), Sat(v.y), Sat(v.z) );}
  103. inline VecD Sat(C VecD &v) {return VecD (Sat(v.x), Sat(v.y), Sat(v.z) );}
  104. inline Vec4 Sat(C Vec4 &v) {return Vec4 (Sat(v.x), Sat(v.y), Sat(v.z), Sat(v.w));}
  105. inline VecD4 Sat(C VecD4 &v) {return VecD4(Sat(v.x), Sat(v.y), Sat(v.z), Sat(v.w));}
  106. // make saturated (clamp to 0..1)
  107. inline Int & SAT(Int &x) {return x=Sat(x);}
  108. inline Long& SAT(Long &x) {return x=Sat(x);}
  109. inline Flt & SAT(Flt &x) {return x=Sat(x);}
  110. inline Dbl & SAT(Dbl &x) {return x=Sat(x);}
  111. // sign
  112. constexpr Int SignBool(Bool x) {return x ? 1 : -1;} // sign from Bool
  113. constexpr Int Sign( Int x) {return (x>0) ? 1 : (x<0) ? -1 : 0;} // sign
  114. constexpr Int Sign( Long x) {return (x>0) ? 1 : (x<0) ? -1 : 0;} // sign
  115. constexpr Int Sign( Flt x) {return (x>0) ? 1 : (x<0) ? -1 : 0;} // sign
  116. constexpr Int Sign( Dbl x) {return (x>0) ? 1 : (x<0) ? -1 : 0;} // sign
  117. inline VecI2 Sign(C VecI2 &v) {return VecI2(Sign(v.x), Sign(v.y) );}
  118. inline VecI Sign(C VecI &v) {return VecI (Sign(v.x), Sign(v.y), Sign(v.z) );}
  119. inline VecI4 Sign(C VecI4 &v) {return VecI4(Sign(v.x), Sign(v.y), Sign(v.z), Sign(v.w));}
  120. inline VecI2 Sign(C Vec2 &v) {return VecI2(Sign(v.x), Sign(v.y) );}
  121. inline VecI Sign(C Vec &v) {return VecI (Sign(v.x), Sign(v.y), Sign(v.z) );}
  122. inline VecI4 Sign(C Vec4 &v) {return VecI4(Sign(v.x), Sign(v.y), Sign(v.z), Sign(v.w));}
  123. inline Int SignEps(Flt x, Flt eps=EPS ) {return (x>eps) ? 1 : (x<-eps) ? -1 : 0;} // sign using epsilon
  124. inline Int SignEps(Dbl x, Dbl eps=EPSD) {return (x>eps) ? 1 : (x<-eps) ? -1 : 0;} // sign using epsilon
  125. #if EE_PRIVATE
  126. inline Flt PackInf(Flt x) {return 1-1/(x+1);} // pack value from 0..Inf to 0..1
  127. inline Flt UnpackInf(Flt x) {return 1/(1-x)-1;} // unpack value from 0..1 to 0..Inf
  128. #endif
  129. inline Flt ScaleFactor (Flt x) {return (x>=0) ? (1+x) : (1/(1-x));} // get scaling factor from linear value
  130. inline Dbl ScaleFactor (Dbl x) {return (x>=0) ? (1+x) : (1/(1-x));} // get scaling factor from linear value
  131. inline Flt ScaleFactorR(Flt s) {return (s>=1) ? (s-1) : (1-(1/s));} // get linear value from scaling factor
  132. inline Dbl ScaleFactorR(Dbl s) {return (s>=1) ? (s-1) : (1-(1/s));} // get linear value from scaling factor
  133. Vec2 ScaleFactor(C Vec2 &vec); Vec2 ScaleFactorR(C Vec2 &vec);
  134. VecD2 ScaleFactor(C VecD2 &vec); VecD2 ScaleFactorR(C VecD2 &vec);
  135. Vec ScaleFactor(C Vec &vec); Vec ScaleFactorR(C Vec &vec);
  136. VecD ScaleFactor(C VecD &vec); VecD ScaleFactorR(C VecD &vec);
  137. Vec4 ScaleFactor(C Vec4 &vec); Vec4 ScaleFactorR(C Vec4 &vec);
  138. VecD4 ScaleFactor(C VecD4 &vec); VecD4 ScaleFactorR(C VecD4 &vec);
  139. constexpr Int Sqr ( Int x) {return x*x ;} // square = x**2
  140. constexpr UInt Sqr ( UInt x) {return x*x ;} // square = x**2
  141. constexpr Long Sqr ( Long x) {return x*x ;} // square = x**2
  142. constexpr ULong Sqr ( ULong x) {return x*x ;} // square = x**2
  143. constexpr Flt Sqr ( Flt x) {return x*x ;} // square = x**2
  144. constexpr Dbl Sqr ( Dbl x) {return x*x ;} // square = x**2
  145. inline Vec2 Sqr (C Vec2 &x) {return x*x ;} // square = x**2
  146. inline Vec Sqr (C Vec &x) {return x*x ;} // square = x**2
  147. inline Vec4 Sqr (C Vec4 &x) {return x*x ;} // square = x**2
  148. constexpr Int Cube ( Int x) {return x*x*x ;} // cube = x**3
  149. constexpr UInt Cube ( UInt x) {return x*x*x ;} // cube = x**3
  150. constexpr Long Cube ( Long x) {return x*x*x ;} // cube = x**3
  151. constexpr ULong Cube ( ULong x) {return x*x*x ;} // cube = x**3
  152. constexpr Flt Cube ( Flt x) {return x*x*x ;} // cube = x**3
  153. constexpr Dbl Cube ( Dbl x) {return x*x*x ;} // cube = x**3
  154. constexpr Int Quart( Int x) {return Sqr(x*x);} // quartic = x**4
  155. constexpr UInt Quart( UInt x) {return Sqr(x*x);} // quartic = x**4
  156. constexpr Long Quart( Long x) {return Sqr(x*x);} // quartic = x**4
  157. constexpr ULong Quart( ULong x) {return Sqr(x*x);} // quartic = x**4
  158. constexpr Flt Quart( Flt x) {return Sqr(x*x);} // quartic = x**4
  159. constexpr Dbl Quart( Dbl x) {return Sqr(x*x);} // quartic = x**4
  160. constexpr Int SqrS ( Int x) {return (x>=0) ? Sqr(x) : -Sqr(x);} // sign preserving square
  161. constexpr Long SqrS ( Long x) {return (x>=0) ? Sqr(x) : -Sqr(x);} // sign preserving square
  162. constexpr Flt SqrS ( Flt x) {return (x>=0) ? Sqr(x) : -Sqr(x);} // sign preserving square
  163. constexpr Dbl SqrS ( Dbl x) {return (x>=0) ? Sqr(x) : -Sqr(x);} // sign preserving square
  164. #if EE_PRIVATE
  165. UInt SqrtI(UInt x ); // integer square root (binary method, fastest)
  166. Int SqrtI( Int x ); // integer square root (binary method, fastest)
  167. UInt SqrtI(ULong x ); // integer square root (binary method, fastest)
  168. Int SqrtI( Long x ); // integer square root (binary method, fastest)
  169. UInt SqrtI(UInt x, Int max_steps); // integer square root (iterative method, slower but can be faster if "max_steps<=2")
  170. #endif
  171. inline Flt SqrtFast( Int x) {return sqrtf(x);} // square root, returns NaN for negative values
  172. inline Flt SqrtFast( Flt x) {return sqrtf(x);} // square root, returns NaN for negative values
  173. inline Dbl SqrtFast( Dbl x) {return sqrt (x);} // square root, returns NaN for negative values
  174. Flt Sqrt ( Int x); // square root, returns 0 for negative values
  175. Flt Sqrt ( Flt x); // square root, returns 0 for negative values
  176. Dbl Sqrt ( Dbl x); // square root, returns 0 for negative values
  177. Vec2 Sqrt (C Vec2 &x); // square root, returns 0 for negative values
  178. Vec Sqrt (C Vec &x); // square root, returns 0 for negative values
  179. Vec4 Sqrt (C Vec4 &x); // square root, returns 0 for negative values
  180. Flt SqrtS ( Int x); // sign preserving square root, returns -Sqrt(-x) for negative values
  181. Flt SqrtS ( Flt x); // sign preserving square root, returns -Sqrt(-x) for negative values
  182. Dbl SqrtS ( Dbl x); // sign preserving square root, returns -Sqrt(-x) for negative values
  183. inline Flt Cbrt ( Int x) {return cbrtf(x);} // cube root, works ok for negative values
  184. inline Flt Cbrt ( Flt x) {return cbrtf(x);} // cube root, works ok for negative values
  185. inline Dbl Cbrt ( Dbl x) {return cbrt (x);} // cube root, works ok for negative values
  186. inline Flt Pow(Int x, Flt y) {return powf(x, y);} // raise 'x' to the power 'y'
  187. inline Flt Pow(Flt x, Int y) {return powf(x, y);} // raise 'x' to the power 'y'
  188. inline Flt Pow(Flt x, Flt y) {return powf(x, y);} // raise 'x' to the power 'y'
  189. inline Dbl Pow(Int x, Dbl y) {return pow (x, y);} // raise 'x' to the power 'y'
  190. inline Dbl Pow(Dbl x, Int y) {return pow (x, y);} // raise 'x' to the power 'y'
  191. inline Dbl Pow(Dbl x, Dbl y) {return pow (x, y);} // raise 'x' to the power 'y'
  192. inline Flt Ln (Flt x) {return logf(x);} // e-base logarithm
  193. inline Dbl Ln (Dbl x) {return log (x);} // e-base logarithm
  194. #if (!ANDROID || __ANDROID_API__>=18) // Android below API 18 doesn't have log2f/log2
  195. inline Flt Log2(Flt x) {return log2f(x);} // 2-base logarithm
  196. inline Dbl Log2(Dbl x) {return log2 (x);} // 2-base logarithm
  197. #else
  198. inline Flt Log2(Flt x) {return logf(x)*1.4426950408889634073599246810019f;} // 2-base logarithm = Ln(x)/Ln(2)
  199. inline Dbl Log2(Dbl x) {return log (x)*1.4426950408889634073599246810019 ;} // 2-base logarithm = Ln(x)/Ln(2)
  200. #endif
  201. Flt Log (Flt x, Flt base); // logarithm
  202. Dbl Log (Dbl x, Dbl base); // logarithm
  203. Flt Pinch(Flt x, Flt pinch); // pinch, 'x'=0..1, 'pinch'=0..Inf (<1 makes the curve start slow and accelerate, 1 makes the curve linear, >1 makes the curve start fast and deccelerate)
  204. // calculate squared distance of coordinates from point zero
  205. inline Int Dist2(Int x, Int y ) {return x*x + y*y ;}
  206. inline Flt Dist2(Flt x, Flt y ) {return x*x + y*y ;}
  207. inline Dbl Dist2(Dbl x, Dbl y ) {return x*x + y*y ;}
  208. inline Int Dist2(Int x, Int y, Int z ) {return x*x + y*y + z*z ;}
  209. inline Flt Dist2(Flt x, Flt y, Flt z ) {return x*x + y*y + z*z ;}
  210. inline Dbl Dist2(Dbl x, Dbl y, Dbl z ) {return x*x + y*y + z*z ;}
  211. inline Flt Dist2(Flt x, Flt y, Flt z, Flt w) {return x*x + y*y + z*z + w*w;}
  212. // calculate distance of coordinates from point zero
  213. Flt Dist(Int x, Int y );
  214. Flt Dist(Flt x, Flt y );
  215. Dbl Dist(Dbl x, Dbl y );
  216. Flt Dist(Int x, Int y, Int z);
  217. Flt Dist(Flt x, Flt y, Flt z);
  218. Dbl Dist(Dbl x, Dbl y, Dbl z);
  219. // density
  220. Flt SplitAlpha (Flt alpha , Int steps); // calculate alpha to be used for drawing graphics using 'steps' amount of steps to generate the same results as when drawing with 'alpha' using only 1 step
  221. Flt VisibleOpacity(Flt density, Flt range); // calculate visible opacity (0..1) having 'density' environment density (0..1), and 'range' (0..Inf)
  222. Flt AccumulatedDensity(Flt density, Flt range); // calculate accumulated density (0..1) having 'density' environment density (0..1), and 'range' (0..Inf)
  223. // sigmoid
  224. Flt SigmoidExp (Flt x);
  225. Flt SigmoidDiv (Flt x);
  226. Flt SigmoidAtan (Flt x);
  227. Flt SigmoidSqrt (Flt x);
  228. Flt SigmoidSqrtInv(Flt y); // inverse function of 'SigmoidSqrt', SigmoidSqrtInv(SigmoidSqrt(x))=x
  229. Flt SigmoidGd (Flt x);
  230. Flt SigmoidTanh (Flt x);
  231. Flt SigmoidErf (Flt x);
  232. /******************************************************************************/
  233. // ANGLES
  234. /******************************************************************************/
  235. inline Flt Sin ( Flt angle) {return sinf(angle);} // get sine of angle, -1..1
  236. inline Dbl Sin ( Dbl angle) {return sin (angle);} // get sine of angle, -1..1
  237. inline Flt Cos ( Flt angle) {return cosf(angle);} // get cosine of angle, -1..1
  238. inline Dbl Cos ( Dbl angle) {return cos (angle);} // get cosine of angle, -1..1
  239. void CosSin( Flt &cos, Flt &sin, Flt angle); // get cosine and sine of angle, cos=Cos(angle), sin=Sin(angle)
  240. void CosSin( Dbl &cos, Dbl &sin, Dbl angle); // get cosine and sine of angle, cos=Cos(angle), sin=Sin(angle)
  241. inline Flt Tan ( Flt angle) {return tanf(angle);} // get tangent "sin/cos" of angle, -Inf..Inf
  242. inline Dbl Tan ( Dbl angle) {return tan (angle);} // get tangent "sin/cos" of angle, -Inf..Inf
  243. Vec2 Tan (C Vec2 &angle); // get tangent "sin/cos" of angle, -Inf..Inf
  244. inline Flt Ctg ( Flt angle) {return tanf(PI_2 -angle);} // get cotangent "cos/sin" of angle, -Inf..Inf, alternative: {Flt t=tanf(angle); return t ? 1.0f/t : 0;}
  245. inline Dbl Ctg ( Dbl angle) {return tan (PID_2-angle);} // get cotangent "cos/sin" of angle, -Inf..Inf, alternative: {Dbl t=tan (angle); return t ? 1.0 /t : 0;}
  246. Flt Acos ( Flt cos ); // get arc cosine (angle which has specified cosine), 0..PI
  247. Dbl Acos ( Dbl cos ); // get arc cosine (angle which has specified cosine), 0..PI
  248. Flt Asin ( Flt sin ); // get arc sine (angle which has specified sine), -PI_2..PI_2
  249. Dbl Asin ( Dbl sin ); // get arc sine (angle which has specified sine), -PI_2..PI_2
  250. inline Flt Atan ( Flt tan ) {return atanf(tan);} // get arc tangent (angle which has specified tangent), -PI_2..PI_2
  251. inline Dbl Atan ( Dbl tan ) {return atan (tan);} // get arc tangent (angle which has specified tangent), -PI_2..PI_2
  252. Vec2 Atan (C Vec2 &tan ); // get arc tangent (angle which has specified tangent), -PI_2..PI_2
  253. #if EE_PRIVATE
  254. Flt ACosSin(Flt cos, Flt sin); // get angle which has specified cosine and sine, 0..PI (this assumes "sin>=0"), this is faster than 'Angle', however point needs to be normalized (X=cos, Y=sin), and remember that this function ignores "sin<0"
  255. Dbl ACosSin(Dbl cos, Dbl sin); // get angle which has specified cosine and sine, 0..PI (this assumes "sin>=0"), this is faster than 'Angle', however point needs to be normalized (X=cos, Y=sin), and remember that this function ignores "sin<0"
  256. #endif
  257. inline Flt Angle (Flt x, Flt y) {return atan2f( y, x);} // get point angle (-PI..PI)
  258. inline Dbl Angle (Dbl x, Dbl y) {return atan2 ( y, x);} // get point angle (-PI..PI)
  259. inline Flt Angle (C Vec2 &v ) {return atan2f(v.y, v.x);} // get point angle (-PI..PI)
  260. inline Dbl Angle (C VecD2 &v ) {return atan2 (v.y, v.x);} // get point angle (-PI..PI)
  261. Flt Angle (C Vec &v, C Vec &x, C Vec &y); // get point angle according to given axes (-PI..PI)
  262. inline Flt Angle (C Vec &v, C Vec &pos, C Vec &x, C Vec &y) {return Angle(v-pos, x, y);} // get point angle according to given axes and center (-PI..PI)
  263. inline Flt Angle (C Vec &v, C Matrix3 &matrix ) {return Angle(v , matrix.x, matrix.y);} // get point angle according to given matrix (-PI..PI)
  264. inline Flt AngleXZ(C Vec &v, C Matrix3 &matrix ) {return Angle(v , matrix.x, matrix.z);} // get point angle according to given matrix (-PI..PI)
  265. inline Flt Angle (C Vec &v, C Matrix &matrix ) {return Angle(v, matrix.pos, matrix.x, matrix.y);} // get point angle according to given matrix (-PI..PI)
  266. inline Flt AngleXZ(C Vec &v, C Matrix &matrix ) {return Angle(v, matrix.pos, matrix.x, matrix.z);} // get point angle according to given matrix (-PI..PI)
  267. Flt AngleFast(Flt x, Flt y); // get point angle approximation (-PI..PI)
  268. Flt AngleFast(C Vec2 &v ); // get point angle approximation (-PI..PI)
  269. #if EE_PRIVATE
  270. Flt AngleFast (C Vec &v, C Vec &x, C Vec &y); // get point angle approximation according to given axes (-PI..PI)
  271. inline Flt AngleFast (C Vec &v, C Vec &pos, C Vec &x, C Vec &y) {return AngleFast(v-pos, x, y);} // get point angle approximation according to given axes and center (-PI..PI)
  272. inline Flt AngleFast (C Vec &v, C Matrix3 &matrix ) {return AngleFast(v , matrix.x, matrix.y);} // get point angle approximation according to given matrix (-PI..PI)
  273. inline Flt AngleFastXZ(C Vec &v, C Matrix3 &matrix ) {return AngleFast(v , matrix.x, matrix.z);} // get point angle approximation according to given matrix (-PI..PI)
  274. inline Flt AngleFast (C Vec &v, C Matrix &matrix ) {return AngleFast(v, matrix.pos, matrix.x, matrix.y);} // get point angle approximation according to given matrix (-PI..PI)
  275. inline Flt AngleFastXZ(C Vec &v, C Matrix &matrix ) {return AngleFast(v, matrix.pos, matrix.x, matrix.z);} // get point angle approximation according to given matrix (-PI..PI)
  276. #endif
  277. inline Flt AngleFull (Flt angle ) {return Frac(angle, PI2 );} // normalize angle to 0..PI2 (wrap angle to 0..PI2 range)
  278. inline Dbl AngleFull (Dbl angle ) {return Frac(angle, PID2);} // normalize angle to 0..PI2 (wrap angle to 0..PI2 range)
  279. Flt AngleNormalize(Flt angle ); // normalize angle to -PI..PI (wrap angle to -PI..PI range)
  280. Dbl AngleNormalize(Dbl angle ); // normalize angle to -PI..PI (wrap angle to -PI..PI range)
  281. inline Flt AngleDelta (Flt from, Flt to) {return AngleNormalize(to-from);} // get angle delta -PI..PI (difference between angles wrapped to -PI..PI range)
  282. inline Dbl AngleDelta (Dbl from, Dbl to) {return AngleNormalize(to-from);} // get angle delta -PI..PI (difference between angles wrapped to -PI..PI range)
  283. inline Flt CosSin(Flt cos_sin) {return Sqrt(1-cos_sin*cos_sin);} // convert cos<->sin, this function converts sine value to cosine value (of the same angle), and cosine value to sine value (of the same angle) at the same time
  284. inline Dbl CosSin(Dbl cos_sin) {return Sqrt(1-cos_sin*cos_sin);} // convert cos<->sin, this function converts sine value to cosine value (of the same angle), and cosine value to sine value (of the same angle) at the same time
  285. #if EE_PRIVATE
  286. inline Flt CosSinPrecise(Flt cos_sin) {return CosSin(Dbl (cos_sin));} // this is more precise than regular 'CosSin' and still fast
  287. inline Dbl CosSinPrecise(Dbl cos_sin) {return Sin (Acos(cos_sin));} // this is more precise than regular 'CosSin' but slow
  288. #endif
  289. inline Flt CalcZ(C Vec2 &v) {return Sqrt(1 - v.x*v.x - v.y*v.y);}
  290. Vec DequantizeNormal(C Vec &n); // improve precision of normal, assuming it was generated from 8-bit values
  291. // angle between vectors
  292. Flt AngleBetween (C Vec2 &a, C Vec2 &b); // -PI..PI, 'a b'=direction vectors (they DON'T NEED to be normalized)
  293. Dbl AngleBetween (C VecD2 &a, C VecD2 &b); // -PI..PI, 'a b'=direction vectors (they DON'T NEED to be normalized)
  294. inline Flt AbsAngleBetween (C Vec2 &a, C Vec2 &b) {return Abs(AngleBetween(a, b));} // 0..PI, 'a b'=direction vectors (they DON'T NEED to be normalized)
  295. inline Dbl AbsAngleBetween (C VecD2 &a, C VecD2 &b) {return Abs(AngleBetween(a, b));} // 0..PI, 'a b'=direction vectors (they DON'T NEED to be normalized)
  296. Flt AbsAngleBetween (C Vec &a, C Vec &b); // 0..PI, 'a b'=direction vectors (they DON'T NEED to be normalized)
  297. Dbl AbsAngleBetween (C VecD &a, C VecD &b); // 0..PI, 'a b'=direction vectors (they DON'T NEED to be normalized)
  298. Flt AbsAngleBetweenN(C Vec &a, C Vec &b); // 0..PI, 'a b'=direction vectors (they NEED to be normalized)
  299. Dbl AbsAngleBetweenN(C VecD &a, C VecD &b); // 0..PI, 'a b'=direction vectors (they NEED to be normalized)
  300. Flt AngleBetween (C Vec &a, C Vec &b, C Vec &z); // -PI..PI, 'a b'=direction vectors (they DON'T NEED to be normalized), 'z'=forward axis orientation (it doesn't need to be normalized)
  301. Dbl AngleBetween (C VecD &a, C VecD &b, C VecD &z); // -PI..PI, 'a b'=direction vectors (they DON'T NEED to be normalized), 'z'=forward axis orientation (it doesn't need to be normalized)
  302. // cos of angle between vectors (they DON'T NEED to be normalized)
  303. Flt CosBetween(C Vec2 &a, C Vec2 &b); // -1..1
  304. Dbl CosBetween(C VecD2 &a, C VecD2 &b); // -1..1
  305. Flt CosBetween(C Vec &a, C Vec &b); // -1..1
  306. Dbl CosBetween(C VecD &a, C VecD &b); // -1..1
  307. // cos of angle between vectors (they NEED to be normalized)
  308. inline Flt CosBetweenN(C Vec2 &a, C Vec2 &b) {return Dot(a, b);} // -1..1
  309. inline Dbl CosBetweenN(C VecD2 &a, C VecD2 &b) {return Dot(a, b);} // -1..1
  310. inline Flt CosBetweenN(C Vec &a, C Vec &b) {return Dot(a, b);} // -1..1
  311. inline Dbl CosBetweenN(C VecD &a, C VecD &b) {return Dot(a, b);} // -1..1
  312. // sin of angle between vectors (they DON'T NEED to be normalized)
  313. Flt SinBetween(C Vec2 &a, C Vec2 &b); // -1..1
  314. Dbl SinBetween(C VecD2 &a, C VecD2 &b); // -1..1
  315. Flt AbsSinBetween(C Vec &a, C Vec &b); // 0..1
  316. Dbl AbsSinBetween(C VecD &a, C VecD &b); // 0..1
  317. // sin of angle between vectors (they NEED to be normalized)
  318. inline Flt SinBetweenN(C Vec2 &a, C Vec2 &b) {return Cross(a, b) ;} // -1..1
  319. inline Dbl SinBetweenN(C VecD2 &a, C VecD2 &b) {return Cross(a, b) ;} // -1..1
  320. inline Flt AbsSinBetweenN(C Vec &a, C Vec &b) {return Cross(a, b).length();} // 0..1
  321. inline Dbl AbsSinBetweenN(C VecD &a, C VecD &b) {return Cross(a, b).length();} // 0..1
  322. #if EE_PRIVATE
  323. inline Flt AngleBetween(C Vec2 &prev, C Vec2 &cur, C Vec2 &next) {return AngleBetween(prev-cur, next-cur);} // -PI..PI
  324. inline Dbl AngleBetween(C VecD2 &prev, C VecD2 &cur, C VecD2 &next) {return AngleBetween(prev-cur, next-cur);} // -PI..PI
  325. inline Flt AbsAngleBetween(C Vec2 &prev, C Vec2 &cur, C Vec2 &next) {return AbsAngleBetween(prev-cur, next-cur);} // 0..PI
  326. inline Dbl AbsAngleBetween(C VecD2 &prev, C VecD2 &cur, C VecD2 &next) {return AbsAngleBetween(prev-cur, next-cur);} // 0..PI
  327. inline Flt AbsAngleBetween(C Vec &prev, C Vec &cur, C Vec &next) {return AbsAngleBetween(prev-cur, next-cur);} // 0..PI
  328. inline Dbl AbsAngleBetween(C VecD &prev, C VecD &cur, C VecD &next) {return AbsAngleBetween(prev-cur, next-cur);} // 0..PI
  329. inline Flt CosBetween(C Vec2 &prev, C Vec2 &cur, C Vec2 &next) {return CosBetween(prev-cur, next-cur);} // -1..1
  330. inline Dbl CosBetween(C VecD2 &prev, C VecD2 &cur, C VecD2 &next) {return CosBetween(prev-cur, next-cur);} // -1..1
  331. inline Flt CosBetween(C Vec &prev, C Vec &cur, C Vec &next) {return CosBetween(prev-cur, next-cur);} // -1..1
  332. inline Dbl CosBetween(C VecD &prev, C VecD &cur, C VecD &next) {return CosBetween(prev-cur, next-cur);} // -1..1
  333. #endif
  334. inline Flt AngleFlipX (Flt angle) {return PI -angle;} // flip angle so that (x, y)->(-x, y), where x=Cos(angle), y=Sin(angle)
  335. inline Flt AngleFlipY (Flt angle) {return PI2-angle;} // flip angle so that (x, y)->( x,-y), where x=Cos(angle), y=Sin(angle)
  336. inline Flt AngleFlipXY(Flt angle) {return PI +angle;} // flip angle so that (x, y)->(-x,-y), where x=Cos(angle), y=Sin(angle)
  337. // average direction
  338. void AvgDirU(Vec2 &dir, C MemPtr<Vec2> &points); // get average direction from array of points, points should be located around center Vec2(0,0), direction is not normalized
  339. /******************************************************************************/
  340. // BLENDING
  341. /******************************************************************************/
  342. // get smooth curves that start slowly from 0, accelerate, and slow down to 1
  343. #if EE_PRIVATE
  344. Flt _SmoothQuintic(Flt x ); // fast version that doesn't check for 'x' being out of 0..1 range, this function is not an approximate of 'SmoothSin', it's sharper
  345. #endif
  346. Flt SmoothSqr (Flt x );
  347. inline Flt _SmoothCube (Flt x ) {return (3-2*x)*x*x;} // fast version that doesn't check for 'x' being out of 0..1 range
  348. Flt SmoothCube (Flt x );
  349. Flt SmoothCubeInv(Flt y ); // inverse function of 'SmoothCube', SmoothCubeInv(SmoothCube(x))=x
  350. Flt SmoothCube2 (Flt x ); // this function is sharper than 'SmoothCube'
  351. Flt SmoothSextic (Flt x );
  352. Flt SmoothSin (Flt x );
  353. Flt SmoothPow (Flt x, Flt pow );
  354. Flt SmoothPinch (Flt x, Flt pinch);
  355. // get smooth curves that return blend value (0..1), basing on the 'x' distance (-1..1), highest intensity '1' is returned for "x==0" which smoothly drops to zero when 'x' becomes more away from the '0' position and reaches '-1' or '+1' or greater distances
  356. Flt BlendSqr (Flt x); // get square blend value (0..1), basing on the 'x' distance (-1..1), highest intensity '1' is returned for "x==0" which smoothly drops to zero when 'x' becomes more away from the '0' position and reaches '-1' or '+1' or greater distances
  357. Flt BlendSmoothSqr (Flt x); // get smooth square blend value (0..1), basing on the 'x' distance (-1..1), highest intensity '1' is returned for "x==0" which smoothly drops to zero when 'x' becomes more away from the '0' position and reaches '-1' or '+1' or greater distances
  358. Flt BlendSmoothCube (Flt x); // get smooth cubic blend value (0..1), basing on the 'x' distance (-1..1), highest intensity '1' is returned for "x==0" which smoothly drops to zero when 'x' becomes more away from the '0' position and reaches '-1' or '+1' or greater distances
  359. Flt BlendSmoothSextic(Flt x); // get smooth sextic blend value (0..1), basing on the 'x' distance (-1..1), highest intensity '1' is returned for "x==0" which smoothly drops to zero when 'x' becomes more away from the '0' position and reaches '-1' or '+1' or greater distances
  360. Flt BlendSmoothSin (Flt x); // get smooth sine blend value (0..1), basing on the 'x' distance (-1..1), highest intensity '1' is returned for "x==0" which smoothly drops to zero when 'x' becomes more away from the '0' position and reaches '-1' or '+1' or greater distances
  361. constexpr Int BlendSmoothCubeSum (Int range) {return range ;} // get sum of all weights for all "-range..range" steps, calculated using "Flt weight=0; for(Int dist=-range; dist<=range; dist++)weight+=BlendSmoothCube(dist/Flt(range));"
  362. constexpr Flt BlendSmoothCubeSumHalf(Int range) {return range*0.5f+0.5f;} // get sum of all weights for all " 0..range" steps, calculated using "Flt weight=0; for(Int dist= 0; dist<=range; dist++)weight+=BlendSmoothCube(dist/Flt(range));"
  363. Flt Gaussian(Flt x); // get the Probability Density Function (PDF) of the Normal (Gaussian) distribution "expf(-x*x)", this function returns highest value of 1 at "x==0" and drops towards zero when 'x' becomes more away from the '0' position, theoretically it never reaches zero value, however due to floating point numerical precision zero will be reached for 'x' values far from '0' position
  364. Flt SmoothOffset(Flt &offset, Flt max_length);
  365. Vec2 SmoothOffset(Vec2 &offset, Flt max_length);
  366. Vec SmoothOffset(Vec &offset, Flt max_length);
  367. /******************************************************************************/
  368. // INTERPOLATION
  369. /******************************************************************************/
  370. // get tangent, based on previous and next value
  371. Flt GetTangent ( Flt prev, Flt next);
  372. Vec2 GetTangent (C Vec2 &prev, C Vec2 &next);
  373. Vec GetTangent (C Vec &prev, C Vec &next);
  374. Vec4 GetTangent (C Vec4 &prev, C Vec4 &next);
  375. Vec2 GetTangentDir(C Vec2 &prev, C Vec2 &next); // get tangent for direction vectors
  376. Vec GetTangentDir(C Vec &prev, C Vec &next); // get tangent for direction vectors
  377. Flt GetTangent ( Flt prev, Flt cur, Flt next); // get tangent from previous, current and next values
  378. Vec2 GetTangent (C Vec2 &prev, C Vec2 &cur, C Vec2 &next); // get tangent from previous, current and next values
  379. Vec GetTangent (C Vec &prev, C Vec &cur, C Vec &next); // get tangent from previous, current and next values
  380. Vec4 GetTangent (C Vec4 &prev, C Vec4 &cur, C Vec4 &next); // get tangent from previous, current and next values
  381. // linear interpolation, 'step'=0..1
  382. inline Flt Lerp( Int from, Int to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  383. inline Flt Lerp( Flt from, Flt to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  384. inline Dbl Lerp( Dbl from, Dbl to, Dbl step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  385. inline Vec2 Lerp(C VecI2 &from, C VecI2 &to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  386. inline Vec2 Lerp(C Vec2 &from, C Vec2 &to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  387. inline VecD2 Lerp(C VecD2 &from, C VecD2 &to, Dbl step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  388. inline Vec Lerp(C VecI &from, C VecI &to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  389. inline Vec Lerp(C Vec &from, C Vec &to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  390. inline VecD Lerp(C VecD &from, C VecD &to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  391. inline VecD Lerp(C VecD &from, C VecD &to, Dbl step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  392. inline Vec4 Lerp(C VecI4 &from, C VecI4 &to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  393. inline Vec4 Lerp(C Vec4 &from, C Vec4 &to, Flt step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  394. inline VecD4 Lerp(C VecD4 &from, C VecD4 &to, Dbl step) {return from+step*(to-from);} // faster than "from*(1-step) + to*step"
  395. #if EE_PRIVATE
  396. VecB4 Lerp(C VecB4 &from, C VecB4 &to, Flt step);
  397. VecB4 Lerp(C VecB4 &a , C VecB4 &b , C VecB4 &c, C Vec &blend); // linear interpolation between vectors, returns a*blend.x + b*blend.y + c*blend.z
  398. #endif
  399. // linear interpolation reverse, get interpolation step from value, these functions return 0 if "value==from" and 1 if "value==to", in other cases returned value is interpolated between 0..1
  400. inline Flt LerpR( Int from, Int to, Int value) {return Flt(value-from)/(to-from);}
  401. inline Flt LerpR( Flt from, Flt to, Flt value) {return (value-from)/(to-from);}
  402. inline Dbl LerpR( Dbl from, Dbl to, Dbl value) {return (value-from)/(to-from);}
  403. Flt LerpR(C Vec2 &from, C Vec2 &to, C Vec2 &value);
  404. Dbl LerpR(C VecD2 &from, C VecD2 &to, C VecD2 &value);
  405. Flt LerpR(C Vec &from, C Vec &to, C Vec &value);
  406. Dbl LerpR(C VecD &from, C VecD &to, C VecD &value);
  407. Flt LerpR(C Vec4 &from, C Vec4 &to, C Vec4 &value);
  408. Dbl LerpR(C VecD4 &from, C VecD4 &to, C VecD4 &value);
  409. // linear interpolation reverse saturated, get saturated interpolation step from value, these functions return 0 if "value==from" and 1 if "value==to", in other cases returned value is interpolated between 0..1 and clamped to 0..1 range
  410. inline Flt LerpRS( Int from, Int to, Int value) {return Sat(LerpR(from, to, value));}
  411. inline Flt LerpRS( Flt from, Flt to, Flt value) {return Sat(LerpR(from, to, value));}
  412. inline Dbl LerpRS( Dbl from, Dbl to, Dbl value) {return Sat(LerpR(from, to, value));}
  413. inline Flt LerpRS(C Vec2 &from, C Vec2 &to, C Vec2 &value) {return Sat(LerpR(from, to, value));}
  414. inline Dbl LerpRS(C VecD2 &from, C VecD2 &to, C VecD2 &value) {return Sat(LerpR(from, to, value));}
  415. inline Flt LerpRS(C Vec &from, C Vec &to, C Vec &value) {return Sat(LerpR(from, to, value));}
  416. inline Dbl LerpRS(C VecD &from, C VecD &to, C VecD &value) {return Sat(LerpR(from, to, value));}
  417. inline Flt LerpRS(C Vec4 &from, C Vec4 &to, C Vec4 &value) {return Sat(LerpR(from, to, value));}
  418. inline Dbl LerpRS(C VecD4 &from, C VecD4 &to, C VecD4 &value) {return Sat(LerpR(from, to, value));}
  419. Flt LerpAngle(Flt from, Flt to, Flt step); // angle based interpolation, 'step'=0..1
  420. void Lerp4Weights(Vec4 &weights, Flt step); // get weights used for 'Lerp4' function, 'step'=0..1
  421. Flt Lerp4( Flt v0, Flt v1, Flt v2, Flt v3, Flt step); // 4 values based interpolation (hermite spline), smoothly interpolate between v1..v2, 'step'=0..1
  422. Vec2 Lerp4(C Vec2 &v0, C Vec2 &v1, C Vec2 &v2, C Vec2 &v3, Flt step); // 4 values based interpolation (hermite spline), smoothly interpolate between v1..v2, 'step'=0..1
  423. Vec Lerp4(C Vec &v0, C Vec &v1, C Vec &v2, C Vec &v3, Flt step); // 4 values based interpolation (hermite spline), smoothly interpolate between v1..v2, 'step'=0..1
  424. Vec4 Lerp4(C Vec4 &v0, C Vec4 &v1, C Vec4 &v2, C Vec4 &v3, Flt step); // 4 values based interpolation (hermite spline), smoothly interpolate between v1..v2, 'step'=0..1
  425. Flt LerpTan( Flt from, Flt to, Flt step, Flt tan0, Flt tan1); // tangent based interpolation (hermite spline), 'step'=0..1
  426. Vec2 LerpTan(C Vec2 &from, C Vec2 &to, Flt step, C Vec2 &tan0, C Vec2 &tan1); // tangent based interpolation (hermite spline), 'step'=0..1
  427. Vec LerpTan(C Vec &from, C Vec &to, Flt step, C Vec &tan0, C Vec &tan1); // tangent based interpolation (hermite spline), 'step'=0..1
  428. Vec4 LerpTan(C Vec4 &from, C Vec4 &to, Flt step, C Vec4 &tan0, C Vec4 &tan1); // tangent based interpolation (hermite spline), 'step'=0..1
  429. inline Flt LerpSmoothSqr (Flt from, Flt to, Flt step ) {return Lerp(from, to, SmoothSqr (step ));}
  430. inline Flt LerpSmoothCube (Flt from, Flt to, Flt step ) {return Lerp(from, to, SmoothCube (step ));}
  431. inline Flt LerpSmoothCube2 (Flt from, Flt to, Flt step ) {return Lerp(from, to, SmoothCube2 (step ));}
  432. inline Flt LerpSmoothSextic(Flt from, Flt to, Flt step ) {return Lerp(from, to, SmoothSextic(step ));}
  433. inline Flt LerpSmoothSin (Flt from, Flt to, Flt step ) {return Lerp(from, to, SmoothSin (step ));}
  434. inline Flt LerpSmoothPow (Flt from, Flt to, Flt step, Flt pow ) {return Lerp(from, to, SmoothPow (step, pow ));}
  435. inline Flt LerpSmoothPinch (Flt from, Flt to, Flt step, Flt pinch) {return Lerp(from, to, SmoothPinch (step, pinch));}
  436. /******************************************************************************/
  437. // ADJUST VALUE
  438. /******************************************************************************/
  439. void AdjustValDir (Flt &value, Int dir, Flt dv ); // adjust value by direction, move 'value' according to 'dir' directon * 'dv' and clamps it to -1..1, if 'dir'==0 then moves 'value' towards 0 by 'dv'
  440. void AdjustValDir (Flt &value, Int dir, Flt change , Flt reset ); // adjust value by direction, move 'value' according to 'dir' directon * 'change' and clamps it to -1..1, if 'dir'==0 then moves 'value' towards 0 by 'reset'
  441. void AdjustValBool (Flt &value, Bool on, Flt dv ); // adjust value by Bool , increases/decreases 'value' and clamps it to 0..1, "value=Sat(on ? value+dv : value-dv)"
  442. void AdjustValBool (Flt &value, Bool on, Flt inc , Flt dec ); // adjust value by Bool , increases/decreases 'value' and clamps it to 0..1, "value=Sat(on ? value+dv : value-dv)"
  443. void AdjustValBoolSet(Flt &value, Bool on, Bool set, Flt dv ); // adjust value by Bool or immediate set, "if(set)value=on;else AdjustValBool(value, on, dv );"
  444. void AdjustValBoolSet(Flt &value, Bool on, Bool set, Flt inc , Flt dec ); // adjust value by Bool or immediate set, "if(set)value=on;else AdjustValBool(value, on, inc, dec);"
  445. void AdjustValTime (Flt &value, Flt target, Flt exponent, Flt dt=Time.d()); // adjust value to target by smooth time interpolation, 'exponent'=0..1
  446. void AdjustValTime (Dbl &value, Dbl target, Flt exponent, Flt dt=Time.d()); // adjust value to target by smooth time interpolation, 'exponent'=0..1
  447. void AdjustValTime (Vec2 &value, C Vec2 &target, Flt exponent, Flt dt=Time.d()); // adjust value to target by smooth time interpolation, 'exponent'=0..1
  448. void AdjustValTime (Vec &value, C Vec &target, Flt exponent, Flt dt=Time.d()); // adjust value to target by smooth time interpolation, 'exponent'=0..1
  449. void AdjustValTime (VecD &value, C VecD &target, Flt exponent, Flt dt=Time.d()); // adjust value to target by smooth time interpolation, 'exponent'=0..1
  450. void AdjustValTarget (Flt &value, Flt target, Flt dv ); // adjust value to target, move 'value' towards 'target' by 'dv'
  451. void AdjustValTarget (Dbl &value, Dbl target, Dbl dv ); // adjust value to target, move 'value' towards 'target' by 'dv'
  452. void AdjustValTarget (Vec2 &value, C Vec2 &target, Flt dv ); // adjust value to target, move 'value' towards 'target' by 'dv'
  453. void AdjustValTarget (Vec &value, C Vec &target, Flt dv ); // adjust value to target, move 'value' towards 'target' by 'dv'
  454. void AdjustValTarget (VecD &value, C VecD &target, Dbl dv ); // adjust value to target, move 'value' towards 'target' by 'dv'
  455. void AdjustValTarget (Flt &value, Flt target, Flt inc , Flt dec ); // adjust value to target, increase 'value' towards 'target' by 'inc' or decrease 'value' towards 'target' by 'dec'
  456. /******************************************************************************/
  457. // EQUATIONS
  458. /******************************************************************************/
  459. // solve equations of given formula
  460. // return number of solutions (-1=infinite, 0=none, 1=one, 2=two, 3=three), set 'x' as solutions
  461. // polynominals
  462. inline Int Polynominal0(Flt a) {return a ? 0 : -1;} // a = 0
  463. inline Int Polynominal0(Dbl a) {return a ? 0 : -1;} // a = 0
  464. Int Polynominal1(Flt a, Flt b, Flt &x ); // a*x + b = 0
  465. Int Polynominal1(Dbl a, Dbl b, Dbl &x ); // a*x + b = 0
  466. Int Polynominal2(Flt a, Flt b, Flt c, Flt &x0, Flt &x1 ); // a*x^2 + b*x + c = 0
  467. Int Polynominal2(Dbl a, Dbl b, Dbl c, Dbl &x0, Dbl &x1 ); // a*x^2 + b*x + c = 0
  468. Int Polynominal3(Flt a, Flt b, Flt c, Flt d, Flt &x0, Flt &x1, Flt &x2); // a*x^3 + b*x^2 + c*x + d = 0
  469. Int Polynominal3(Dbl a, Dbl b, Dbl c, Dbl d, Dbl &x0, Dbl &x1, Dbl &x2); // a*x^3 + b*x^2 + c*x + d = 0
  470. // simultaneous equations
  471. Int Solve(Flt a1, Flt a2, Flt b1, Flt b2, Flt c1, Flt c2, Flt &x, Flt &y);
  472. Int Solve(Dbl a1, Dbl a2, Dbl b1, Dbl b2, Dbl c1, Dbl c2, Dbl &x, Dbl &y);
  473. // x*a1 + y*b1 = c1
  474. // x*a2 + y*b2 = c2
  475. /******************************************************************************/
  476. // CONVERT UNITS
  477. /******************************************************************************/
  478. inline Flt DegToRad( Int deg) {return deg*(PI /180);} // convert Degrees to Radians
  479. inline Flt DegToRad( Flt deg) {return deg*(PI /180);} // convert Degrees to Radians
  480. inline Dbl DegToRad( Dbl deg) {return deg*(PID/180);} // convert Degrees to Radians
  481. inline Vec2 DegToRad(C Vec2 &deg) {return deg*(PI /180);} // convert Degrees to Radians
  482. inline Vec DegToRad(C Vec &deg) {return deg*(PI /180);} // convert Degrees to Radians
  483. inline Vec4 DegToRad(C Vec4 &deg) {return deg*(PI /180);} // convert Degrees to Radians
  484. inline Flt RadToDeg( Flt rad) {return rad*(180/PI );} // convert Radians to Degrees
  485. inline Dbl RadToDeg( Dbl rad) {return rad*(180/PID);} // convert Radians to Degrees
  486. inline Vec2 RadToDeg(C Vec2 &rad) {return rad*(180/PI );} // convert Radians to Degrees
  487. inline Vec RadToDeg(C Vec &rad) {return rad*(180/PI );} // convert Radians to Degrees
  488. inline Vec4 RadToDeg(C Vec4 &rad) {return rad*(180/PI );} // convert Radians to Degrees
  489. inline Flt MpsToKmph (Flt x) {return x*((60*60)/1000.0f);} // convert "Meter per Second" To "Kilometer per Hour "
  490. inline Flt KmphToMps (Flt x) {return x*(1000.0f/(60*60));} // convert "Kilometer per Hour " To "Meter per Second"
  491. inline Flt RadpsToRotpm(Flt x) {return x*(60/PI2 );} // convert "Radian per Second" To "Rotation per Minute"
  492. inline Flt RotpmToRadps(Flt x) {return x*(PI2/60 );} // convert "Rotation per Minute" To "Radian per Second"
  493. #if EE_PRIVATE
  494. inline Byte FltToByte(Flt f) {return Mid(RoundPos(f*255), 0, 255);} // 0..1 -> 0..255, it's okay to clamp after converting to int for small values
  495. inline Flt ByteToFlt(Byte b) {return b/255.0f ;} // 0..255 -> 0..1
  496. inline SByte SFltToSByte(Flt f) {return Mid(Round(f*(255.0f/2)) , -128, 127);} // -1..1 -> -128..127, it's okay to clamp after converting to int for small values
  497. inline Byte SFltToUByte(Flt f) {return Mid(Round(f*(255.0f/2))+128, 0, 255);} // -1..1 -> 0..255, it's okay to clamp after converting to int for small values
  498. inline Flt SByteToSFlt(SByte b) {return -1+(b+128)*(2.0f/255);} // -128..127 -> -1..1
  499. inline Flt UByteToSFlt( Byte b) {return -1+ b *(2.0f/255);} // 0..255 -> -1..1
  500. #endif
  501. /******************************************************************************/
  502. // TIME, DISTANCE, VELOCITY, ACCELERATION
  503. /******************************************************************************/
  504. inline Flt ZeroVelTravelTime (Flt dist, Flt accel) {return 2*SqrtFast(accel*dist)/accel;} // get time needed to travel 'dist' distance using 'accel' acceleration, assuming that initial velocity is zero, first half is accelerated with 'accel', second half decelerated with 'accel' and final velocity is zero
  505. inline Flt ZeroVelTravelDist (Flt time, Flt accel) {return accel*Sqr(time)/4;} // get travelled distance in 'time' using 'accel' acceleration, assuming that initial velocity is zero, first half is accelerated with 'accel', second half decelerated with 'accel' and final velocity is zero
  506. inline Flt ZeroVelTravelAccel(Flt time, Flt dist ) {return dist /Sqr(time)*4;} // get acceleration needed to travel 'dist' distance in 'time' , assuming that initial velocity is zero, first half is accelerated with 'accel', second half decelerated with 'accel' and final velocity is zero
  507. /******************************************************************************/
  508. extern const Int PrimeNumbers[16]; // first 16 prime numbers = { 2, 3, 5, .. }
  509. /******************************************************************************/