Math.lua 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. ----------------------------------------------------------------------------------------------------
  2. --
  3. -- Copyright (c) Contributors to the Open 3D Engine Project.
  4. -- For complete copyright and license terms please see the LICENSE at the root of this distribution.
  5. --
  6. -- SPDX-License-Identifier: Apache-2.0 OR MIT
  7. --
  8. --
  9. --
  10. ----------------------------------------------------------------------------------------------------
  11. function ConstVec(v)
  12. return v
  13. end
  14. ----------------------------------------------------
  15. -- global Vectors table and some vector functions
  16. ----------------------------------------------------
  17. g_Vectors =
  18. {
  19. v000=ConstVec({x=0,y=0,z=0}),
  20. v001=ConstVec({x=0,y=0,z=1}),
  21. v010=ConstVec({x=0,y=1,z=0}),
  22. v011=ConstVec({x=0,y=1,z=1}),
  23. v100=ConstVec({x=1,y=0,z=0}),
  24. v101=ConstVec({x=1,y=0,z=1}),
  25. v110=ConstVec({x=1,y=1,z=0}),
  26. v111=ConstVec({x=1,y=1,z=1}),
  27. up = ConstVec({x=0,y=0,z=1}),
  28. down = ConstVec({x=0,y=0,z=-1}),
  29. temp={x=0,y=0,z=0},
  30. tempColor={x=0,y=0,z=0},
  31. temp_v1={x=0,y=0,z=0},
  32. temp_v2={x=0,y=0,z=0},
  33. temp_v3={x=0,y=0,z=0},
  34. temp_v4={x=0,y=0,z=0},
  35. temp_v5={x=0,y=0,z=0},
  36. temp_v6={x=0,y=0,z=0},
  37. vecMathTemp1={x=0,y=0,z=0},
  38. vecMathTemp2={x=0,y=0,z=0},
  39. }
  40. -----------------------------------------------------------------------------
  41. -- Math constants
  42. -----------------------------------------------------------------------------
  43. g_Rad2Deg = 180/math.pi;
  44. g_Deg2Rad = math.pi/180;
  45. g_Pi = math.pi;
  46. g_2Pi = 2*math.pi;
  47. g_Pi2 = 0.5*math.pi;
  48. -----------------------------------------------------------------------------
  49. -- Import commonly used math functions from math. table to global namespace.
  50. -----------------------------------------------------------------------------
  51. random = math.random;
  52. math.randomseed(os.time()); -- seed and pop
  53. random();
  54. -----------------------------------------------------------------------------
  55. function IsNullVector(a)
  56. return (a.x==0 and a.y==0 and a.z ==0);
  57. end
  58. function IsNotNullVector(a)
  59. return (a.x~=0 or a.y~=0 or a.z ~=0);
  60. end
  61. function LengthSqVector(a)
  62. return (a.x * a.x + a.y * a.y + a.z * a.z);
  63. end
  64. function LengthVector(a)
  65. return math.sqrt(LengthSqVector(a));
  66. end
  67. function DistanceSqVectors(a, b)
  68. local x = a.x-b.x;
  69. local y = a.y-b.y;
  70. local z = a.z-b.z;
  71. return x*x + y*y + z*z;
  72. end
  73. function DistanceSqVectors2d(a, b)
  74. local x = a.x-b.x;
  75. local y = a.y-b.y;
  76. return x*x + y*y;
  77. end
  78. function DistanceVectors(a, b)
  79. local x = a.x-b.x;
  80. local y = a.y-b.y;
  81. local z = a.z-b.z;
  82. return math.sqrt(x*x + y*y + z*z);
  83. end
  84. -----------------------------------------------------------------------------
  85. function dotproduct3d(a,b)
  86. return (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
  87. end
  88. -----------------------------------------------------------------------------
  89. function dotproduct2d(a,b)
  90. return (a.x * b.x) + (a.y * b.y);
  91. end
  92. function LogVec(name,v)
  93. Log("%s = (%f %f %f)",name,v.x,v.y,v.z);
  94. end
  95. function ZeroVector(dest)
  96. dest.x=0;
  97. dest.y=0;
  98. dest.z=0;
  99. end
  100. function CopyVector(dest,src)
  101. dest.x=src.x;
  102. dest.y=src.y;
  103. dest.z=src.z;
  104. end
  105. ----------------------------------
  106. function SumVectors(a,b)
  107. return {x=a.x+b.x,y=a.y+b.y,z=a.z+b.z};
  108. end
  109. function NegVector(a)
  110. a.x = -a.x;
  111. a.y = -a.y;
  112. a.z = -a.z;
  113. end
  114. ----------------------------------
  115. function SubVectors(dest,a,b)
  116. dest.x = a.x - b.x;
  117. dest.y = a.y - b.y;
  118. dest.z = a.z - b.z;
  119. end
  120. ----------------------------------
  121. function FastSumVectors(dest,a,b)
  122. dest.x=a.x+b.x;
  123. dest.y=a.y+b.y;
  124. dest.z=a.z+b.z;
  125. end
  126. ----------------------------------
  127. function DifferenceVectors(a,b)
  128. return {x=a.x-b.x,y=a.y-b.y,z=a.z-b.z};
  129. end
  130. ----------------------------------
  131. function FastDifferenceVectors(dest,a,b)
  132. dest.x=a.x-b.x;
  133. dest.y=a.y-b.y;
  134. dest.z=a.z-b.z;
  135. end
  136. ----------------------------------
  137. function ProductVectors(a,b)
  138. return {x=a.x*b.x,y=a.y*b.y,z=a.z*b.z};
  139. end
  140. ----------------------------------
  141. function FastProductVectors(dest,a,b)
  142. dest.x=a.x*b.x;
  143. dest.y=a.y*b.y;
  144. dest.z=a.z*b.z;
  145. end
  146. ----------------------------------
  147. function ScaleVector(a,b)
  148. return {x=a.x*b,y=a.y*b,z=a.z*b};
  149. end
  150. function ScaleVectorInPlace(a,b)
  151. a.x=a.x*b;
  152. a.y=a.y*b;
  153. a.z=a.z*b;
  154. end
  155. ----------------------------------
  156. function NormalizeVector(a)
  157. local len=math.sqrt(LengthSqVector(a));
  158. local multiplier;
  159. if(len>0)then
  160. multiplier=1/len;
  161. else
  162. multiplier=0.0001;
  163. end
  164. a.x=a.x*multiplier;
  165. a.y=a.y*multiplier;
  166. a.z=a.z*multiplier;
  167. return a
  168. end
  169. ----------------------------------
  170. function FastScaleVector(dest,a,b)
  171. dest.x=a.x*b;
  172. dest.y=a.y*b;
  173. dest.z=a.z*b;
  174. end
  175. --linear interpolation
  176. ----------------------------------
  177. function LerpColors(a,b,k)
  178. g_Vectors.tempColor.x = a.x+(b.x-a.x)*k
  179. g_Vectors.tempColor.y = a.y+(b.y-a.y)*k
  180. g_Vectors.tempColor.z = a.z+(b.z-a.z)*k
  181. return g_Vectors.tempColor;
  182. end
  183. ----------------------------------
  184. function Lerp(a,b,k)
  185. return (a + (b - a)*k);
  186. end
  187. ----------------------------------
  188. function __max(a, b)
  189. if (a > b) then
  190. return a;
  191. else
  192. return b;
  193. end
  194. end
  195. ----------------------------------
  196. function __min(a, b)
  197. if (a < b) then
  198. return a;
  199. else
  200. return b;
  201. end
  202. end
  203. ----------------------------------
  204. function clamp(_n, _min, _max)
  205. if (_n > _max) then _n = _max; end
  206. if (_n < _min) then _n = _min; end
  207. return _n;
  208. end
  209. ----------------------------------
  210. function Interpolate(actual,goal,speed)
  211. local delta = goal - actual;
  212. if (math.abs(delta)<0.001) then
  213. return goal;
  214. end
  215. local res = actual + delta * __min(speed,1.0);
  216. return res;
  217. end
  218. -----------------------------------
  219. function sgn(a)
  220. if (a == 0) then
  221. return 0;
  222. elseif (a > 0) then
  223. return 1;
  224. else
  225. return -1;
  226. end
  227. end
  228. -----------------------------------
  229. function sgnnz(a)
  230. return (a>=0) and 1 or -1;
  231. end
  232. -----------------------------------
  233. function sqr(a)
  234. return a*a;
  235. end
  236. -----------------
  237. function randomF(a,b)
  238. if (a>b) then
  239. local c = b;
  240. b = a;
  241. a = c;
  242. end
  243. local delta = b-a;
  244. return (a + math.random()*delta);
  245. end
  246. function VecRotate90_Z(v)
  247. local x = v.x;
  248. v.x = v.y;
  249. v.y = -x;
  250. end
  251. function VecRotateMinus90_Z(v)
  252. local x = v.x;
  253. v.x = -v.y;
  254. v.y = x;
  255. end
  256. function iff(c,a,b)
  257. if c then return a else return b end
  258. end
  259. -----------------------------------------------------------------------------
  260. -- calculate cross product
  261. function crossproduct3d( dest, p, q )
  262. dest.x = p.y*q.z-p.z*q.y;
  263. dest.y = p.z*q.x-p.x*q.z;
  264. dest.z = p.x*q.y-p.y*q.x;
  265. end
  266. -- rotate vector p around vector r by angle
  267. -- the length of r needs to be 1
  268. function RotateVectorAroundR( dest, p, r, angle )
  269. -- p' = v1 + v2 +v3
  270. -- v1 = pcosA
  271. -- v2 = r**psinA;
  272. -- v3 = r< r,p >( 1- cosA );
  273. local cosValue = math.cos( angle );
  274. local sinValue = math.sin( angle );
  275. local v1 = {};
  276. local v2 = {};
  277. local v3 = {};
  278. local vTmp = {};
  279. -- v1
  280. CopyVector( v1, p );
  281. FastScaleVector( v1, v1, cosValue );
  282. -- v2
  283. CopyVector( vTmp, p );
  284. FastScaleVector( vTmp, vTmp, sinValue );
  285. crossproduct3d( v2, r, vTmp );
  286. -- v3
  287. CopyVector( v3, r );
  288. FastScaleVector( v3, v3, dotproduct3d( r, p ) );
  289. FastScaleVector( v3, v3, 1.0 - cosValue );
  290. -- p'
  291. CopyVector( dest, v1 );
  292. FastSumVectors( dest, v1, v2 );
  293. FastSumVectors( dest, dest, v3 );
  294. end
  295. -- project P to the surface whose normal vector is N.
  296. function ProjectVector( dest, P, N )
  297. -- projected vector is vector X (output)
  298. -- X =P+(-P*N)N
  299. local minusP ={};
  300. FastScaleVector( minusP , P , -1.0 );
  301. local t = dotproduct3d( minusP, N );
  302. CopyVector( dest , N );
  303. FastScaleVector( dest , dest , t );
  304. FastSumVectors( dest , dest , P );
  305. end
  306. -- get a distance between line(pt+q) and point(a)
  307. function DistanceLineAndPoint( a, p, q )
  308. -- d=|| p * (a-q) || / ||p||
  309. local length = LengthVector( p );
  310. local outerProduct;
  311. local vOuterProduct = {};
  312. local vTmp = {};
  313. local d;
  314. SubVectors( vTmp, a, q );
  315. crossproduct3d( vOuterProduct, p, vTmp );
  316. outerProduct =LengthVector( vOuterProduct );
  317. if ( length>0.01 ) then
  318. d = outerProduct/length;
  319. else
  320. d = 0.0;
  321. end
  322. return d;
  323. end
  324. -- Get normalized direction vector from point 'a' to point 'b'
  325. function GetDirection(a, b)
  326. local dir = {};
  327. SubVectors(dir, b, a);
  328. NormalizeVector(dir);
  329. return dir;
  330. end
  331. function GetAngleBetweenVectors2D(a, b)
  332. return math.acos(dotproduct2d(a, b));
  333. end
  334. function GetAngleBetweenVectors(a, b)
  335. return math.acos(clamp(dotproduct3d(a, b), -1, 1));
  336. end