PageRenderTime 27ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/static/lib/glquery/glquery.math.module.js

https://github.com/circuithub/morpheus
JavaScript | 478 lines | 334 code | 44 blank | 100 comment | 8 complexity | 1f9c57dac223d0e52741a31b448c18a5 MD5 | raw file
  1. /*
  2. * glQuery-math - A math module from a fluent WebGL engine (https://github.com/glQuery)
  3. * glQuery-math is free, public domain software (http://creativecommons.org/publicdomain/zero/1.0/)
  4. * Originally created by Rehno Lindeque of http://www.mischievousmeerkat.com
  5. */
  6. var glQueryMath = new (function() {
  7. "use strict";
  8. var glQueryMath = this != null? this : window;
  9. (function(){
  10. var gl = glQueryMath;
  11. // Define a local copy of glQuery
  12. var MathMemoryPool = {
  13. matrix4: [
  14. [0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0],
  15. [0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0],
  16. [0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0],
  17. [0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0]],
  18. matrix3: [
  19. [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0],
  20. [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0],
  21. [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0]],
  22. matrix2: [
  23. [0.0,0.0, 0.0,0.0],
  24. [0.0,0.0, 0.0,0.0]],
  25. vector4: [[0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0], [0.0,0.0,0.0,0.0]],
  26. vector3: [[0.0,0.0,0.0], [0.0,0.0,0.0], [0.0,0.0,0.0], [0.0,0.0,0.0]],
  27. vector2: [[0.0,0.0], [0.0,0.0], [0.0,0.0], [0.0,0.0]]
  28. };
  29. var v2 = gl.vec2 = {};
  30. v2.add = function(result,a,b) {
  31. result[0] = a[0] + b[0];
  32. result[1] = a[1] + b[1];
  33. return result;
  34. };
  35. v2.subtract = function(result,a,b) {
  36. result[0] = a[0] - b[0];
  37. result[1] = a[1] - b[1];
  38. return result;
  39. };
  40. v2.mul = function(result,a,b) {
  41. result[0] = a[0] * b;
  42. result[1] = a[1] * b;
  43. return result;
  44. };
  45. v2.div = function(result,a,b) {
  46. result[0] = a[0] / b;
  47. result[1] = a[1] / b;
  48. return result;
  49. };
  50. v2.neg = function(result,a) {
  51. result[0] = -a[0];
  52. result[1] = -a[1];
  53. };
  54. v2.dot = function(a,b) {
  55. return a[0] * b[0] + a[1] * b[1];
  56. };
  57. v2.length = function(a) {
  58. return Math.sqrt(a[0] * a[0] + a[1] * a[1]);
  59. };
  60. var v3 = gl.vec3 = {};
  61. v3.add = function(result,a,b) {
  62. result[0] = a[0] + b[0];
  63. result[1] = a[1] + b[1];
  64. result[2] = a[2] + b[2];
  65. return result;
  66. };
  67. v3.sub = function(result,a,b) {
  68. result[0] = a[0] - b[0];
  69. result[1] = a[1] - b[1];
  70. result[2] = a[2] - b[2];
  71. return result;
  72. };
  73. v3.mul = function(result,a,b) {
  74. result[0] = a[0] * b;
  75. result[1] = a[1] * b;
  76. result[2] = a[2] * b;
  77. return result;
  78. };
  79. v3.div = function(result,a,b) {
  80. result[0] = a[0] / b;
  81. result[1] = a[1] / b;
  82. result[2] = a[2] / b;
  83. return result;
  84. };
  85. v3.neg = function(result,a) {
  86. result[0] = -a[0];
  87. result[1] = -a[1];
  88. result[2] = -a[2];
  89. return result;
  90. };
  91. v3.dot = function(a,b) {
  92. return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
  93. };
  94. v3.cross = function(result,a,b) {
  95. result[0] = a[1] * b[2] - a[2] * b[1];
  96. result[1] = a[2] * b[0] - a[0] * b[2];
  97. result[2] = a[0] * b[1] - a[1] * b[0];
  98. return result;
  99. };
  100. v3.length = function(a) {
  101. return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
  102. };
  103. v3.normalize = function(result,a) {
  104. return v3.div(result, a, v3.length(a));
  105. };
  106. var v4 = v4 = {};
  107. v4.add = function(result,a,b) {
  108. result[0] = a[0] + b[0];
  109. result[1] = a[1] + b[1];
  110. result[2] = a[2] + b[2];
  111. result[3] = a[3] + b[3];
  112. return result;
  113. };
  114. v4.subtract = function(result,a,b) {
  115. result[0] = a[0] - b[0];
  116. result[1] = a[1] - b[1];
  117. result[2] = a[2] - b[2];
  118. result[3] = a[3] - b[3];
  119. return result;
  120. };
  121. v4.mul = function(result,a,b) {
  122. result[0] = a[0] * b;
  123. result[1] = a[1] * b;
  124. result[2] = a[2] * b;
  125. result[3] = a[3] * b;
  126. return result;
  127. };
  128. v4.div = function(result,a,b) {
  129. result[0] = a[0] / b;
  130. result[1] = a[1] / b;
  131. result[2] = a[2] / b;
  132. result[3] = a[3] / b;
  133. return result;
  134. };
  135. v4.neg = function(result,a) {
  136. result[0] = -a[0];
  137. result[1] = -a[1];
  138. result[2] = -a[2];
  139. result[3] = -a[3];
  140. };
  141. v4.dot = function(a,b) {
  142. return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
  143. };
  144. v4.length = function(a) {
  145. return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
  146. };
  147. var m3 = gl.matrix3 = {};
  148. m3.mul = function(result,a,b) {
  149. var r = MathMemoryPool.matrix3[0];
  150. r[0*3+0] = a[0*3+0] * b[0*3+0] + a[0*3+1] * b[1*3+0] + a[0*3+2] * b[2*3+0];
  151. r[0*3+1] = a[0*3+0] * b[0*3+1] + a[0*3+1] * b[1*3+1] + a[0*3+2] * b[2*3+1];
  152. r[0*3+2] = a[0*3+0] * b[0*3+2] + a[0*3+1] * b[1*3+2] + a[0*3+2] * b[2*3+2];
  153. r[1*3+0] = a[1*3+0] * b[0*3+0] + a[1*3+1] * b[1*3+0] + a[1*3+2] * b[2*3+0];
  154. r[1*3+1] = a[1*3+0] * b[0*3+1] + a[1*3+1] * b[1*3+1] + a[1*3+2] * b[2*3+1];
  155. r[1*3+2] = a[1*3+0] * b[0*3+2] + a[1*3+1] * b[1*3+2] + a[1*3+2] * b[2*3+2];
  156. r[2*3+0] = a[2*3+0] * b[0*3+0] + a[2*3+1] * b[1*3+0] + a[2*3+2] * b[2*3+0];
  157. r[2*3+1] = a[2*3+0] * b[0*3+1] + a[2*3+1] * b[1*3+1] + a[2*3+2] * b[2*3+1];
  158. r[2*3+2] = a[2*3+0] * b[0*3+2] + a[2*3+1] * b[1*3+2] + a[2*3+2] * b[2*3+2];
  159. for (var i = 0; i < 9; ++i)
  160. result[i] = r[i];
  161. return result;
  162. }
  163. // Rotate transformations for matrices in right-handed coordinate systems
  164. m3.rotateX = function(result, a, angle) {
  165. // TODO: Optimize
  166. return m3.mul(result, a, m3.newRotationX(angle));
  167. };
  168. m3.rotateY = function(result, a, angle) {
  169. // TODO: Optimize
  170. return m3.mul(result, a, m3.newRotationY(angle));
  171. };
  172. m3.rotateZ = function(result, a, angle) {
  173. // TODO: Optimize
  174. return m3.mul(result, a, m3.newRotationZ(angle));
  175. };
  176. m3.rotateXY = function(result, a, angles) {
  177. // TODO: Optimize
  178. return m3.mul(result, a, m3.newRotationXY(angles));
  179. };
  180. m3.rotateYX = function(result, a, angles) {
  181. // TODO: Optimize
  182. return m3.mul(result, a, m3.newRotationYX(angles));
  183. };
  184. m3.rotateXZ = function(result, a, angles) {
  185. // TODO: Optimize
  186. return m3.mul(result, a, m3.newRotationXZ(angles));
  187. };
  188. m3.rotateZX = function(result, a, angles) {
  189. // TODO: Optimize
  190. return m3.mul(result, a, m3.newRotationZX(angles));
  191. };
  192. m3.rotateYZ = function(result, a, angles) {
  193. // TODO: Optimize
  194. return m3.mul(result, a, m3.newRotationYZ(angles));
  195. };
  196. m3.rotateZY = function(result, a, angles) {
  197. // TODO: Optimize
  198. return m3.mul(result, a, m3.newRotationZY(angles));
  199. };
  200. // Module for setting 3x3 matrix values
  201. // Axis-angle rotation matrix using the right hand rule
  202. m3.newAxisRotation = function(axis, angle) {
  203. var
  204. // Convert rotation to quaternion representation
  205. length = Math.sqrt(axis[0]*axis[0], axis[1]*axis[1], axis[2]*axis[2]),
  206. halfAngle = angle * 0.5,
  207. sinHalfOverLength = Math.sin(halfAngle) / length,
  208. x = axis[0] * sinHalfOverLength,
  209. y = axis[1] * sinHalfOverLength,
  210. z = axis[2] * sinHalfOverLength,
  211. w = Math.cos(halfAngle),
  212. // Convert quaternion to matrix representation
  213. xx = x*x, xy = x*y, xz = x*z, xw = x*w,
  214. yy = y*y, yz = y*z, yw = y*w,
  215. zz = z*z, zw = z*w;
  216. return [
  217. 1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw),
  218. 2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw),
  219. 2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy)];
  220. };
  221. // Matrix identity
  222. m3.newIdentity = function() {
  223. return [
  224. 1.0, 0.0, 0.0,
  225. 0.0, 1.0, 0.0,
  226. 0.0, 0.0, 1.0];
  227. };
  228. // Right handed rotation matrices
  229. m3.newRotationX = function(angle) {
  230. var
  231. c = Math.cos(angle),
  232. s = Math.sin(angle);
  233. return [
  234. 1.0, 0.0, 0.0,
  235. 0.0, c, s,
  236. 0.0,-s, c
  237. ]
  238. };
  239. m3.newRotationY = function(angle) {
  240. var
  241. c = Math.cos(angle),
  242. s = Math.sin(angle);
  243. return [
  244. c, 0.0,-s,
  245. 0.0, 1.0, 0.0,
  246. s, 0.0, c
  247. ]
  248. };
  249. m3.newRotationZ = function(angle) {
  250. var
  251. c = Math.cos(angle),
  252. s = Math.sin(angle);
  253. return [
  254. c, s, 0.0,
  255. -s, c, 0.0,
  256. 0.0, 0.0, 1.0
  257. ]
  258. };
  259. m3.newRotationXY = function(angles) {
  260. /* TODO: Optimize
  261. var
  262. c0 = Math.cos(angles[0]),
  263. s0 = Math.sin(angles[0]),
  264. c1 = Math.cos(angles[1]),
  265. s1 = Math.sin(angles[1]);
  266. return [
  267. c1 , 0.0,-s_ ,
  268. s1 * s_, c_ , c_ * c_,
  269. s_ * s_,-s_ , c_ * c_
  270. ];//*/
  271. var result = [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0];
  272. return m3.mul(result, m3.newRotationX(angles[0]), m3.newRotationY(angles[1]));
  273. };
  274. m3.newRotationYX = function(angles) {
  275. /* TODO: Optimize
  276. var
  277. c0 = Math.cos(angles[0]),
  278. s0 = Math.sin(angles[0]),
  279. c1 = Math.cos(angles[1]),
  280. s1 = Math.sin(angles[1]);
  281. return [
  282. c, s*s,-s*c,
  283. 0.0, c, s,
  284. s, -s*c, c*c
  285. ];//*/
  286. var result = [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0];
  287. return m3.mul(result, m3.newRotationY(angles[0]), m3.newRotationX(angles[1]));
  288. };
  289. m3.newRotationXZ = function(angles) {
  290. /* TODO: Optimize
  291. var
  292. c0 = Math.cos(angles[0]),
  293. s0 = Math.sin(angles[0]),
  294. c1 = Math.cos(angles[1]),
  295. s1 = Math.sin(angles[1]);
  296. return [
  297. c, s, 0.0,
  298. -c*s, c*c, s,
  299. s*s,-s*c, c
  300. ];//*/
  301. var result = [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0];
  302. return m3.mul(result, m3.newRotationX(angles[0]), m3.newRotationZ(angles[1]));
  303. };
  304. m3.newRotationZX = function(angles) {
  305. /* TODO: Optimize
  306. var
  307. c0 = Math.cos(angles[0]),
  308. s0 = Math.sin(angles[0]),
  309. c1 = Math.cos(angles[1]),
  310. s1 = Math.sin(angles[1]);
  311. return [
  312. c, s*c, s*s,
  313. -s, c*c, c*s,
  314. s, 0.0, c
  315. ];//*/
  316. var result = [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0];
  317. return m3.mul(result, m3.newRotationZ(angles[0]), m3.newRotationX(angles[1]));
  318. };
  319. m3.newRotationYZ = function(angles) {
  320. /* TODO: Optimize
  321. var
  322. c0 = Math.cos(angles[0]),
  323. s0 = Math.sin(angles[0]),
  324. c1 = Math.cos(angles[1]),
  325. s1 = Math.sin(angles[1]);
  326. return [
  327. c*c, c*s, -s,
  328. -s, c, 0.0,
  329. s*c, s*s, c
  330. ];//*/
  331. var result = [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0];
  332. return m3.mul(result, m3.newRotationY(angles[0]), m3.newRotationZ(angles[1]));
  333. };
  334. m3.newRotationZY = function(angles) {
  335. /* TODO: Optimize
  336. var
  337. c0 = Math.cos(angles[0]),
  338. s0 = Math.sin(angles[0]),
  339. c1 = Math.cos(angles[1]),
  340. s1 = Math.sin(angles[1]);
  341. return [
  342. c*c, s,-c*s,
  343. -s*c, c, s*s,
  344. s, 0.0, c
  345. ];//*/
  346. var result = [0.0,0.0,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0];
  347. return m3.mul(result, m3.newRotationZ(angles[0]), m3.newRotationY(angles[1]));
  348. };
  349. var m4 = gl.matrix4 = {};
  350. // Module for setting 4x4 matrix values
  351. // Axis-angle rotation matrix using the right hand rule
  352. m4.newAxisRotation = function(axis, angle) {
  353. var
  354. // Convert rotation to quaternion representation
  355. length = Math.sqrt(axis[0]*axis[0], axis[1]*axis[1], axis[2]*axis[2]),
  356. halfAngle = angle * 0.5,
  357. sinHalfOverLength = Math.sin(halfAngle) / length,
  358. x = axis[0] * sinHalfOverLength,
  359. y = axis[1] * sinHalfOverLength,
  360. z = axis[2] * sinHalfOverLength,
  361. w = Math.cos(halfAngle),
  362. // Convert quaternion to matrix representation
  363. xx = x*x, xy = x*y, xz = x*z, xw = x*w,
  364. yy = y*y, yz = y*z, yw = y*w,
  365. zz = z*z, zw = z*w;
  366. return [
  367. 1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0,
  368. 2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw), 0,
  369. 2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0,
  370. 0, 0, 0, 1];
  371. };
  372. // Matrix identity
  373. m4.newIdentity = function() {
  374. return [
  375. 1.0, 0.0, 0.0, 0.0,
  376. 0.0, 1.0, 0.0, 0.0,
  377. 0.0, 0.0, 1.0, 0.0,
  378. 0.0, 0.0, 0.0, 1.0];
  379. };
  380. m4.newRows = function(r0, r1, r2, r3) {
  381. return [].concat(r0, r1, r2, r3);
  382. }
  383. m4.newColumns = function(c0, c1, c2, c3) {
  384. return [
  385. c0[0], c1[0], c2[0],c3[0],
  386. c0[1], c1[1], c2[1],c3[1],
  387. c0[2], c1[2], c2[2],c3[2],
  388. c0[3], c1[3], c2[3],c3[3]
  389. ];
  390. }
  391. // Right-handed orthogonal projection matrix
  392. m4.newOrtho = function(left, right, bottom, top, near, far) {
  393. var x = left - right,
  394. y = bottom - top,
  395. z = near - far;
  396. return [
  397. -2.0 / x, 0.0, 0.0, 0.0,
  398. 0.0, -2.0 / y, 0.0, 0.0,
  399. 0.0, 0.0, 2.0 / z, 0.0,
  400. (left + right) / x, (top + bottom) / y, (far + near) / z, 1.0
  401. ];
  402. };
  403. // Right-handed look-at matrix
  404. m4.newLookAt = function(eye, target, up) {
  405. // TODO: See if it would be more efficient to try and build the matrix
  406. // by rows instead of by columns as is done presently
  407. var x = MathMemoryPool.vector4[0],
  408. y = MathMemoryPool.vector4[1],
  409. z = MathMemoryPool.vector4[2],
  410. w = MathMemoryPool.vector4[3];
  411. gl.vec3.sub(z, eye, target);
  412. gl.vec3.cross(x, up, z);
  413. // (probably best to normalize z and x after cross product for best numerical accuracy)
  414. gl.vec3.normalize(x, x);
  415. gl.vec3.normalize(z, z);
  416. // (no need to normalize y because x and z was already normalized)
  417. gl.vec3.cross(y, z, x);
  418. x[3] = -gl.vec3.dot(x, eye);
  419. y[3] = -gl.vec3.dot(y, eye);
  420. z[3] = -gl.vec3.dot(z, eye);
  421. w[0] = 0.0;
  422. w[1] = 0.0;
  423. w[2] = 0.0;
  424. w[3] = 1.0;
  425. return m4.newColumns(x,y,z,w);
  426. };
  427. })();
  428. // Extend glQuery if it is defined
  429. if (typeof glQuery !== 'undefined' && glQuery != null)
  430. for(var key in glQueryMath)
  431. if (glQuery[key] == null)
  432. glQuery[key] = glQueryMath[key];
  433. return glQueryMath;
  434. })();