mConsoleFunctions.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "core/strings/stringFunctions.h"
  23. #include "console/console.h"
  24. #include "math/mMathFn.h"
  25. #include "math/mRandom.h"
  26. #include "math/mMath.h"
  27. #include "math/mathUtils.h"
  28. #include "console/engineAPI.h"
  29. DefineEngineFunction( mSolveQuadratic, const char*, ( F32 a, F32 b, F32 c ),,
  30. "Solve a quadratic equation (2nd degree polynomial) of form a*x^2 + b*x + c = 0.\n"
  31. "@param a First Coefficient."
  32. "@param b Second Coefficient."
  33. "@param c Third Coefficient."
  34. "@returns A triple, containing: (sol x0 x1). (sol) is the number of solutions"
  35. "(being 0, 1, or 2), and (x0) and (x1) are the solutions, if any."
  36. "@ingroup Math" )
  37. {
  38. F32 x[2];
  39. U32 sol = mSolveQuadratic( a, b, c, x );
  40. static const U32 bufSize = 256;
  41. char * retBuffer = Con::getReturnBuffer(bufSize);
  42. dSprintf(retBuffer, bufSize, "%d %g %g", sol, x[0], x[1]);
  43. return retBuffer;
  44. }
  45. DefineEngineFunction( mSolveCubic, const char*, ( F32 a, F32 b, F32 c, F32 d ),,
  46. "Solve a cubic equation (3rd degree polynomial) of form a*x^3 + b*x^2 + c*x + d = 0.\n"
  47. "@param a First Coefficient."
  48. "@param b Second Coefficient."
  49. "@param c Third Coefficient."
  50. "@param d Fourth Coefficient."
  51. "@returns A 4-tuple, containing: (sol x0 x1 x2). (sol) is the number of solutions"
  52. "(being 0, 1, 2 or 3), and (x0), (x1) and (x2) are the solutions, if any."
  53. "@ingroup Math" )
  54. {
  55. F32 x[3];
  56. U32 sol = mSolveCubic( a, b, c, d, x );
  57. static const U32 bufSize = 256;
  58. char * retBuffer = Con::getReturnBuffer(bufSize);
  59. dSprintf(retBuffer, bufSize, "%d %g %g %g", sol, x[0], x[1], x[2]);
  60. return retBuffer;
  61. }
  62. DefineEngineFunction( mSolveQuartic, const char*, ( F32 a, F32 b, F32 c, F32 d, F32 e ),,
  63. "Solve a quartic equation (4th degree polynomial) of form a*x^4 + b*x^3 + c*x^2 + d*x + e = 0.\n"
  64. "@param a First Coefficient."
  65. "@param b Second Coefficient."
  66. "@param c Third Coefficient."
  67. "@param d Fourth Coefficient."
  68. "@param e Fifth Coefficient."
  69. "@returns A 5-tuple, containing: (sol x0 x1 x2 c3). (sol) is the number of solutions"
  70. "(being 0, 1, 2, 3 or 4), and (x0), (x1), (x2) and (x3) are the solutions, if any."
  71. "@ingroup Math" )
  72. {
  73. F32 x[4];
  74. static const U32 bufSize = 256;
  75. char * retBuffer = Con::getReturnBuffer(bufSize);
  76. U32 sol = mSolveQuartic(a, b, c, d, e, x);
  77. dSprintf(retBuffer, bufSize, "%d %g %g %g %g", sol, x[0], x[1], x[2], x[3]);
  78. return retBuffer;
  79. }
  80. DefineEngineFunction( mFloor, S32, ( F32 v ),,
  81. "Round v down to the nearest integer.\n"
  82. "@param v Number to convert to integer."
  83. "@returns Number converted to integer."
  84. "@ingroup Math" )
  85. {
  86. return (S32)mFloor( v );
  87. }
  88. DefineEngineFunction( mRound, S32, ( F32 v ),,
  89. "Round v to the nth decimal place or the nearest whole number by default."
  90. "@param v Value to roundn"
  91. "@return The rounded value as a S32."
  92. "@ingroup Math" )
  93. {
  94. return mRound(v);
  95. }
  96. DefineEngineFunction(mRoundF, F32, (F32 v, F32 step), ,
  97. "Round v to the nth decimal place or the nearest whole number by default."
  98. "@param v Value to roundn"
  99. "@return The rounded value as a F32."
  100. "@ingroup Math")
  101. {
  102. return mRoundF(v, step);
  103. }
  104. DefineEngineFunction(mRoundDelta, S32, (F32 v, S32 d), (0.0, 1),
  105. "Round v to the nearest number based on the delta"
  106. "@param v Value to round"
  107. "@param d Delta use when rounding"
  108. "@return The rounded value as a S32."
  109. "@ingroup Math")
  110. {
  111. return (mFloor(v / d + 0.5) * d);
  112. }
  113. DefineEngineFunction( mRoundColour, F32, ( F32 v, S32 n ), (0),
  114. "Round v to the nth decimal place or the nearest whole number by default."
  115. "@param v Value to roundn"
  116. "@param n Number of decimal places to round to, 0 by defaultn"
  117. "@return The rounded value as a S32."
  118. "@ingroup Math")
  119. {
  120. if (n <= 0)
  121. return mRound(v);
  122. else
  123. return mRound(v, n);
  124. }
  125. DefineEngineFunction( mCeil, S32, ( F32 v ),,
  126. "Round v up to the nearest integer.\n"
  127. "@param v Number to convert to integer."
  128. "@returns Number converted to integer."
  129. "@ingroup Math" )
  130. {
  131. return (S32)mCeil( v );
  132. }
  133. DefineEngineFunction( mFloatLength, const char*, ( F32 v, U32 precision ),,
  134. "Formats the specified number to the given number of decimal places.\n"
  135. "@param v Number to format."
  136. "@param precision Number of decimal places to format to (1-9)."
  137. "@returns Number formatted to the specified number of decimal places."
  138. "@ingroup Math" )
  139. {
  140. char fmtString[8] = "%.9f";
  141. if (precision >= 9)
  142. precision = 9;
  143. fmtString[2] = '0' + precision;
  144. static const U32 bufSize = 256;
  145. char * outBuffer = Con::getReturnBuffer(bufSize);
  146. dSprintf(outBuffer, bufSize, fmtString, v);
  147. return outBuffer;
  148. }
  149. //------------------------------------------------------------------------------
  150. DefineEngineFunction( mAbs, F32, ( F32 v ),,
  151. "Calculate absolute value of specified value.\n"
  152. "@param v Input Value."
  153. "@returns Absolute value of specified value."
  154. "@ingroup Math" )
  155. {
  156. return mFabs( v );
  157. }
  158. DefineEngineFunction( mFMod, F32, ( F32 v, F32 d ),,
  159. "Calculate the remainder of v/d.\n"
  160. "@param v Input Value."
  161. "@param d Divisor Value."
  162. "@returns The remainder of v/d."
  163. "@ingroup Math" )
  164. {
  165. return mFmod( v, d );
  166. }
  167. DefineEngineFunction( mSqrt, F32, ( F32 v ),,
  168. "Calculate the square-root of v.\n"
  169. "@param v Input Value."
  170. "@returns The square-root of the input value."
  171. "@ingroup Math" )
  172. {
  173. return mSqrt (v );
  174. }
  175. DefineEngineFunction( mPow, F32, ( F32 v, F32 p ),,
  176. "Calculate b raised to the p-th power.\n"
  177. "@param v Input Value."
  178. "@param p Power to raise value by."
  179. "@returns v raised to the p-th power."
  180. "@ingroup Math" )
  181. {
  182. return mPow( v, p );
  183. }
  184. DefineEngineFunction( mLog, F32, ( F32 v ),,
  185. "Calculate the natural logarithm of v.\n"
  186. "@param v Input Value."
  187. "@returns The natural logarithm of the input value."
  188. "@ingroup Math" )
  189. {
  190. return mLog( v );
  191. }
  192. DefineEngineFunction( mSin, F32, ( F32 v ),,
  193. "Calculate the sine of v.\n"
  194. "@param v Input Value (in radians)."
  195. "@returns The sine of the input value."
  196. "@ingroup Math" )
  197. {
  198. return mSin( v );
  199. }
  200. DefineEngineFunction( mCos, F32, ( F32 v ),,
  201. "Calculate the cosine of v.\n"
  202. "@param v Input Value (in radians)."
  203. "@returns The cosine of the input value."
  204. "@ingroup Math" )
  205. {
  206. return mCos( v );
  207. }
  208. DefineEngineFunction( mTan, F32, ( F32 v ),,
  209. "Calculate the tangent of v.\n"
  210. "@param v Input Value (in radians)."
  211. "@returns The tangent of the input value."
  212. "@ingroup Math" )
  213. {
  214. return mTan( v );
  215. }
  216. DefineEngineFunction( mAsin, F32, ( F32 v ),,
  217. "Calculate the arc-sine of v.\n"
  218. "@param v Input Value (in radians)."
  219. "@returns The arc-sine of the input value."
  220. "@ingroup Math" )
  221. {
  222. return mAsin( v );
  223. }
  224. DefineEngineFunction( mAcos, F32, ( F32 v ),,
  225. "Calculate the arc-cosine of v.\n"
  226. "@param v Input Value (in radians)."
  227. "@returns The arc-cosine of the input value."
  228. "@ingroup Math" )
  229. {
  230. return mAcos( v );
  231. }
  232. DefineEngineFunction( mAtan, F32, ( F32 rise, F32 run ),,
  233. "Calculate the arc-tangent (slope) of a line defined by rise and run.\n"
  234. "@param rise of line."
  235. "@param run of line."
  236. "@returns The arc-tangent (slope) of a line defined by rise and run."
  237. "@ingroup Math" )
  238. {
  239. return mAtan2( rise, run );
  240. }
  241. DefineEngineFunction( mRadToDeg, F32, ( F32 radians ),,
  242. "Convert specified radians into degrees.\n"
  243. "@param radians Input Value (in radians)."
  244. "@returns The specified radians value converted to degrees."
  245. "@ingroup Math" )
  246. {
  247. return mRadToDeg( radians );
  248. }
  249. DefineEngineFunction( mDegToRad, F32, ( F32 degrees ),,
  250. "Convert specified degrees into radians.\n"
  251. "@param degrees Input Value (in degrees)."
  252. "@returns The specified degrees value converted to radians."
  253. "@ingroup Math" )
  254. {
  255. return mDegToRad( degrees );
  256. }
  257. DefineEngineFunction( mClamp, F32, ( F32 v, F32 min, F32 max ),,
  258. "Clamp the specified value between two bounds.\n"
  259. "@param v Input value."
  260. "@param min Minimum Bound."
  261. "@param max Maximum Bound."
  262. "@returns The specified value clamped to the specified bounds."
  263. "@ingroup Math" )
  264. {
  265. return mClampF( v, min, max );
  266. }
  267. DefineEngineFunction( mSaturate, F32, ( F32 v ),,
  268. "Clamp the specified value between 0 and 1 (inclusive).\n"
  269. "@param v Input value."
  270. "@returns The specified value clamped between 0 and 1 (inclusive)."
  271. "@ingroup Math" )
  272. {
  273. return mClampF( v, 0.0f, 1.0f );
  274. }
  275. DefineEngineFunction(mWrapF, F32, (F32 v, F32 min, F32 max), ,
  276. "Wrap the specified value between two bounds.\n"
  277. "@param v Input value."
  278. "@param min Minimum Bound."
  279. "@param max Maximum Bound."
  280. "@returns The specified value wrapped to the specified bounds."
  281. "@ingroup Math")
  282. {
  283. return mWrapF(v, min, max);
  284. }
  285. DefineEngineFunction(mWrap, S32, (S32 v, S32 min, S32 max), ,
  286. "Wrap the specified value between two bounds.\n"
  287. "@param v Input value."
  288. "@param min Minimum Bound."
  289. "@param max Maximum Bound."
  290. "@returns The specified value wrapped to the specified bounds."
  291. "@ingroup Math")
  292. {
  293. return mWrap(v, min, max);
  294. }
  295. DefineEngineFunction( getMax, F32, ( F32 v1, F32 v2 ),,
  296. "Calculate the greater of two specified numbers.\n"
  297. "@param v1 Input value."
  298. "@param v2 Input value."
  299. "@returns The greater value of the two specified values."
  300. "@ingroup Math" )
  301. {
  302. return getMax( v1, v2 );
  303. }
  304. DefineEngineFunction( getMin, F32, ( F32 v1, F32 v2 ),,
  305. "Calculate the lesser of two specified numbers.\n"
  306. "@param v1 Input value."
  307. "@param v2 Input value."
  308. "@returns The lesser value of the two specified values."
  309. "@ingroup Math" )
  310. {
  311. return getMin( v1, v2 );
  312. }
  313. DefineEngineFunction( mLerp, F32, ( F32 v1, F32 v2, F32 time ),,
  314. "Calculate linearly interpolated value between two specified numbers using specified normalized time.\n"
  315. "@param v1 Interpolate From Input value."
  316. "@param v2 Interpolate To Input value."
  317. "@param time Normalized time used to interpolate values (0-1)."
  318. "@returns The interpolated value between the two specified values at normalized time t."
  319. "@ingroup Math" )
  320. {
  321. return mLerp( v1, v2, time );
  322. }
  323. DefineEngineFunction(mInvLerp, F32, (F32 v1, F32 v2, F32 point), ,
  324. "Calculate the percentage of a point along a line.\n"
  325. "@param v1 Interpolate From Input value."
  326. "@param v2 Interpolate To Input value."
  327. "@param point Point along range."
  328. "@returns normalized time used to interpolate values"
  329. "@ingroup Math")
  330. {
  331. return mInvLerp(v1, v2, point);
  332. }
  333. DefineEngineFunction( mPi, F32, (),,
  334. "Return the value of PI (half-circle in radians).\n"
  335. "@returns The value of PI."
  336. "@ingroup Math" )
  337. {
  338. return M_PI_F;
  339. }
  340. DefineEngineFunction( m2Pi, F32, (),,
  341. "Return the value of 2*PI (full-circle in radians).\n"
  342. "@returns The value of 2*PI."
  343. "@ingroup Math" )
  344. {
  345. return M_2PI_F;
  346. }
  347. DefineEngineFunction( mIsPow2, bool, ( S32 v ),,
  348. "Returns whether the value is an exact power of two.\n"
  349. "@param v Input value."
  350. "@returns Whether the specified value is an exact power of two."
  351. "@ingroup Math" )
  352. {
  353. return isPow2( v );
  354. }
  355. DefineEngineFunction( mRandomDir, Point3F, (Point3F axis, F32 angleMin, F32 angleMax),,
  356. "Returns a randomized direction based on a starting axis and the min/max angles.\n"
  357. "@param axis Main axis to deviate the direction from."
  358. "@param angleMin minimum amount of deviation from the axis."
  359. "@param angleMax maximum amount of deviation from the axis."
  360. "@returns Randomized direction vector."
  361. "@ingroup Math")
  362. {
  363. return MathUtils::randomDir(axis, angleMin, angleMax);
  364. }
  365. DefineEngineFunction( mRandomPointInSphere, Point3F, (F32 radius), ,
  366. "Returns a randomized point inside a sphere of a given radius.\n"
  367. "@param radius The radius of the sphere to find a point in."
  368. "@returns Randomized point inside a sphere."
  369. "@ingroup Math")
  370. {
  371. return MathUtils::randomPointInSphere(radius);
  372. }
  373. DefineEngineFunction( mGetAngleBetweenVectors, F32, (VectorF vecA, VectorF vecB), ,
  374. "Returns angle between two vectors.\n"
  375. "@param vecA First input vector."
  376. "@param vecB Second input vector."
  377. "@returns Angle between both vectors in radians."
  378. "@ingroup Math")
  379. {
  380. return MathUtils::getAngleBetweenVectors(vecA, vecB);
  381. }
  382. DefineEngineFunction(mGetSignedAngleBetweenVectors, F32, (VectorF vecA, VectorF vecB, VectorF norm), (VectorF::Zero, VectorF::Zero, VectorF::Zero),
  383. "Returns signed angle between two vectors, using a normal for orientation.\n"
  384. "@param vecA First input vector."
  385. "@param vecB Second input vector."
  386. "@param norm Normal/Cross Product vector."
  387. "@returns Angle between both vectors in radians."
  388. "@ingroup Math")
  389. {
  390. if (vecA.isZero() || vecB.isZero() || norm.isZero())
  391. {
  392. Con::errorf("mGetSignedAngleBetweenVectors - Error! Requires all 3 vectors used to be non-zero!");
  393. return 0;
  394. }
  395. return MathUtils::getSignedAngleBetweenVectors(vecA, vecB, norm);
  396. }
  397. DefineEngineFunction(mBinToDec, S32, (String n),,"convert a binary to decimal")
  398. {
  399. String num = n;
  400. int dec_value = 0;
  401. // Initializing base value to 1, i.e 2^0
  402. int base = 1;
  403. int len = num.length();
  404. for (int i = len - 1; i >= 0; i--) {
  405. if (num[i] == '1')//pick out our 1s and concatenate
  406. dec_value += base;
  407. base = base * 2;//next power of 2
  408. }
  409. return dec_value;
  410. }
  411. DefineEngineFunction(mDecToBin, const char*, (S32 n), , "convert decimal to a binary")
  412. {
  413. String ret;
  414. while (n > 0) {
  415. int r = n % 2;//modulus aka remainder of 2. nets you a 0 or a 1
  416. n /= 2;//next power of 2
  417. ret = String::ToString("%i",r) + ret;//add to the front of the stack
  418. }
  419. return ret.c_str();
  420. }
  421. DefineEngineFunction(mEulDegToAng, AngAxisF, (EulerF euler), , "convert euler to degrees")
  422. {
  423. return mEulDegToAng(euler);
  424. }
  425. DefineEngineFunction(mAngToEul, EulerF, (AngAxisF angAx), , "convert degrees to euler")
  426. {
  427. return mAngToEul(angAx);
  428. }