matruces.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. var MDN = MDN || {};
  2. MDN.matrixArrayToCssMatrix = function (array) {
  3. return "matrix3d(" + array.join(',') + ")";
  4. }
  5. MDN.multiplyPoint = function (matrix, point) {
  6. var x = point[0], y = point[1], z = point[2], w = point[3];
  7. var c1r1 = matrix[ 0], c2r1 = matrix[ 1], c3r1 = matrix[ 2], c4r1 = matrix[ 3],
  8. c1r2 = matrix[ 4], c2r2 = matrix[ 5], c3r2 = matrix[ 6], c4r2 = matrix[ 7],
  9. c1r3 = matrix[ 8], c2r3 = matrix[ 9], c3r3 = matrix[10], c4r3 = matrix[11],
  10. c1r4 = matrix[12], c2r4 = matrix[13], c3r4 = matrix[14], c4r4 = matrix[15];
  11. return [
  12. x*c1r1 + y*c1r2 + z*c1r3 + w*c1r4,
  13. x*c2r1 + y*c2r2 + z*c2r3 + w*c2r4,
  14. x*c3r1 + y*c3r2 + z*c3r3 + w*c3r4,
  15. x*c4r1 + y*c4r2 + z*c4r3 + w*c4r4
  16. ];
  17. }
  18. MDN.multiplyMatrices = function (a, b) {
  19. // TODO - Simplify for explanation
  20. // currently taken from https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js#L306-L337
  21. var result = [];
  22. var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
  23. a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
  24. a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
  25. a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
  26. // Cache only the current line of the second matrix
  27. var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3];
  28. result[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  29. result[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  30. result[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  31. result[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  32. b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7];
  33. result[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  34. result[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  35. result[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  36. result[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  37. b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11];
  38. result[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  39. result[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  40. result[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  41. result[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  42. b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15];
  43. result[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
  44. result[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
  45. result[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
  46. result[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
  47. return result;
  48. }
  49. MDN.multiplyArrayOfMatrices = function (matrices) {
  50. var inputMatrix = matrices[0];
  51. for(var i=1; i < matrices.length; i++) {
  52. inputMatrix = MDN.multiplyMatrices(inputMatrix, matrices[i]);
  53. }
  54. return inputMatrix;
  55. }
  56. MDN.normalMatrix = function (matrix) {
  57. /*
  58. This function takes the inverse and then transpose of the provided
  59. 4x4 matrix. The result is a 3x3 matrix. Essentially the translation
  60. part of the matrix gets removed.
  61. https://github.com/toji/gl-matrix
  62. */
  63. var a00 = matrix[0], a01 = matrix[1], a02 = matrix[2], a03 = matrix[3],
  64. a10 = matrix[4], a11 = matrix[5], a12 = matrix[6], a13 = matrix[7],
  65. a20 = matrix[8], a21 = matrix[9], a22 = matrix[10], a23 = matrix[11],
  66. a30 = matrix[12], a31 = matrix[13], a32 = matrix[14], a33 = matrix[15],
  67. b00 = a00 * a11 - a01 * a10,
  68. b01 = a00 * a12 - a02 * a10,
  69. b02 = a00 * a13 - a03 * a10,
  70. b03 = a01 * a12 - a02 * a11,
  71. b04 = a01 * a13 - a03 * a11,
  72. b05 = a02 * a13 - a03 * a12,
  73. b06 = a20 * a31 - a21 * a30,
  74. b07 = a20 * a32 - a22 * a30,
  75. b08 = a20 * a33 - a23 * a30,
  76. b09 = a21 * a32 - a22 * a31,
  77. b10 = a21 * a33 - a23 * a31,
  78. b11 = a22 * a33 - a23 * a32,
  79. // Calculate the determinant
  80. det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  81. if (!det) {
  82. return null;
  83. }
  84. det = 1.0 / det;
  85. var result = []
  86. result[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  87. result[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  88. result[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  89. result[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  90. result[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  91. result[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  92. result[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  93. result[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  94. result[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  95. return result;
  96. }
  97. MDN.rotateXMatrix = function (a) {
  98. var cos = Math.cos;
  99. var sin = Math.sin;
  100. return [
  101. 1, 0, 0, 0,
  102. 0, cos(a), -sin(a), 0,
  103. 0, sin(a), cos(a), 0,
  104. 0, 0, 0, 1
  105. ];
  106. }
  107. MDN.rotateYMatrix = function (a) {
  108. var cos = Math.cos;
  109. var sin = Math.sin;
  110. return [
  111. cos(a), 0, sin(a), 0,
  112. 0, 1, 0, 0,
  113. -sin(a), 0, cos(a), 0,
  114. 0, 0, 0, 1
  115. ];
  116. }
  117. MDN.rotateZMatrix = function (a) {
  118. var cos = Math.cos;
  119. var sin = Math.sin;
  120. return [
  121. cos(a), -sin(a), 0, 0,
  122. sin(a), cos(a), 0, 0,
  123. 0, 0, 1, 0,
  124. 0, 0, 0, 1
  125. ];
  126. }
  127. MDN.translateMatrix = function (x, y, z) {
  128. return [
  129. 1, 0, 0, 0,
  130. 0, 1, 0, 0,
  131. 0, 0, 1, 0,
  132. x, y, z, 1
  133. ];
  134. }
  135. MDN.scaleMatrix = function (w, h, d) {
  136. return [
  137. w, 0, 0, 0,
  138. 0, h, 0, 0,
  139. 0, 0, d, 0,
  140. 0, 0, 0, 1
  141. ];
  142. }
  143. MDN.perspectiveMatrix = function (fieldOfViewInRadians, aspectRatio, near, far) {
  144. // Construct a perspective matrix
  145. /*
  146. Field of view - the angle in radians of what's in view along the Y axis
  147. Aspect Ratio - the ratio of the canvas, typically canvas.width / canvas.height
  148. Near - Anything before this point in the Z direction gets clipped (resultside of the clip space)
  149. Far - Anything after this point in the Z direction gets clipped (outside of the clip space)
  150. */
  151. var f = 1.0 / Math.tan(fieldOfViewInRadians / 2);
  152. var rangeInv = 1 / (near - far);
  153. return [
  154. f / aspectRatio, 0, 0, 0,
  155. 0, f, 0, 0,
  156. 0, 0, (near + far) * rangeInv, -1,
  157. 0, 0, near * far * rangeInv * 2, 0
  158. ];
  159. }
  160. MDN.orthographicMatrix = function(left, right, bottom, top, near, far) {
  161. // Each of the parameters represents the plane of the bounding box
  162. var lr = 1 / (left - right);
  163. var bt = 1 / (bottom - top);
  164. var nf = 1 / (near - far);
  165. var row4col1 = (left + right) * lr;
  166. var row4col2 = (top + bottom) * bt;
  167. var row4col3 = (far + near) * nf;
  168. return [
  169. -2 * lr, 0, 0, 0,
  170. 0, -2 * bt, 0, 0,
  171. 0, 0, 2 * nf, 0,
  172. row4col1, row4col2, row4col3, 1
  173. ];
  174. }
  175. MDN.normalize = function( vector ) {
  176. // A utility function to make a vector have a length of 1
  177. var length = Math.sqrt(
  178. vector[0] * vector[0] +
  179. vector[1] * vector[1] +
  180. vector[2] * vector[2]
  181. )
  182. return [
  183. vector[0] / length,
  184. vector[1] / length,
  185. vector[2] / length
  186. ]
  187. }
  188. MDN.invertMatrix = function( matrix ) {
  189. // Adapted from: https://github.com/mrdoob/three.js/blob/master/src/math/Matrix4.js
  190. // Performance note: Try not to allocate memory during a loop. This is done here
  191. // for the ease of understanding the code samples.
  192. var result = [];
  193. var n11 = matrix[0], n12 = matrix[4], n13 = matrix[ 8], n14 = matrix[12];
  194. var n21 = matrix[1], n22 = matrix[5], n23 = matrix[ 9], n24 = matrix[13];
  195. var n31 = matrix[2], n32 = matrix[6], n33 = matrix[10], n34 = matrix[14];
  196. var n41 = matrix[3], n42 = matrix[7], n43 = matrix[11], n44 = matrix[15];
  197. result[ 0] = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44;
  198. result[ 4] = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44;
  199. result[ 8] = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44;
  200. result[12] = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
  201. result[ 1] = n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44;
  202. result[ 5] = n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44;
  203. result[ 9] = n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44;
  204. result[13] = n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34;
  205. result[ 2] = n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44;
  206. result[ 6] = n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44;
  207. result[10] = n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44;
  208. result[14] = n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34;
  209. result[ 3] = n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43;
  210. result[ 7] = n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43;
  211. result[11] = n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43;
  212. result[15] = n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33;
  213. var determinant = n11 * result[0] + n21 * result[4] + n31 * result[8] + n41 * result[12];
  214. if ( determinant === 0 ) {
  215. throw new Error("Can't invert matrix, determinant is 0");
  216. }
  217. for( var i=0; i < result.length; i++ ) {
  218. result[i] /= determinant;
  219. }
  220. return result;
  221. }
  222. export default MDN