mat4d_test.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. // Copyright 2013 The Closure Library Authors. All Rights Reserved.
  2. // Use of this source code is governed by the Apache License, Version 2.0.
  3. ////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
  4. // //
  5. // Any edits to this file must be applied to mat4f_test.js by running: //
  6. // swap_type.sh mat4d_test.js > mat4f_test.js //
  7. // //
  8. ////////////////////////// NOTE ABOUT EDITING THIS FILE ///////////////////////
  9. goog.provide('goog.vec.mat4dTest');
  10. goog.setTestOnly('goog.vec.mat4dTest');
  11. goog.require('goog.testing.jsunit');
  12. goog.require('goog.vec.Quaternion');
  13. goog.require('goog.vec.mat4d');
  14. goog.require('goog.vec.vec3d');
  15. goog.require('goog.vec.vec4d');
  16. var randommat4d = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  17. 0.8025078773498535,
  18. 0.7559120655059814,
  19. 0.15274643898010254,
  20. 0.19196106493473053,
  21. 0.0890120416879654,
  22. 0.15422114729881287,
  23. 0.09754583984613419,
  24. 0.44862601161003113,
  25. 0.9196512699127197,
  26. 0.5310639142990112,
  27. 0.8962187170982361,
  28. 0.280601441860199,
  29. 0.594650387763977,
  30. 0.4134795069694519,
  31. 0.06632178276777267,
  32. 0.8837796449661255);
  33. function testCreate() {
  34. var m = goog.vec.mat4d.create();
  35. assertElementsEquals([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m);
  36. }
  37. function testCreateIdentity() {
  38. var m = goog.vec.mat4d.createIdentity();
  39. assertElementsEquals([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m);
  40. }
  41. function testSet() {
  42. var m0 = goog.vec.mat4d.create();
  43. var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
  44. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
  45. goog.vec.mat4d.setFromArray(m0, m1);
  46. assertElementsEquals(
  47. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  48. goog.vec.mat4d.setFromValues(
  49. m0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
  50. assertElementsEquals(
  51. [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], m0);
  52. }
  53. function testSetDiagonal() {
  54. var m0 = goog.vec.mat4d.create();
  55. goog.vec.mat4d.setDiagonalValues(m0, 1, 2, 3, 4);
  56. assertElementsEquals(
  57. [1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], m0);
  58. goog.vec.mat4d.setDiagonal(m0, [4, 5, 6, 7]);
  59. assertElementsEquals(
  60. [4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 7], m0);
  61. }
  62. function testGetDiagonal() {
  63. var v0 = goog.vec.vec4d.create();
  64. var m0 = goog.vec.mat4d.create();
  65. goog.vec.mat4d.setFromArray(
  66. m0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
  67. goog.vec.mat4d.getDiagonal(m0, v0);
  68. assertElementsEquals([0, 5, 10, 15], v0);
  69. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  70. goog.vec.mat4d.getDiagonal(m0, v0, 1);
  71. assertElementsEquals([4, 9, 14, 0], v0);
  72. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  73. goog.vec.mat4d.getDiagonal(m0, v0, 2);
  74. assertElementsEquals([8, 13, 0, 0], v0);
  75. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  76. goog.vec.mat4d.getDiagonal(m0, v0, 3);
  77. assertElementsEquals([12, 0, 0, 0], v0);
  78. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  79. goog.vec.mat4d.getDiagonal(m0, v0, 4);
  80. assertElementsEquals([0, 0, 0, 0], v0);
  81. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  82. goog.vec.mat4d.getDiagonal(m0, v0, -1);
  83. assertElementsEquals([1, 6, 11, 0], v0);
  84. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  85. goog.vec.mat4d.getDiagonal(m0, v0, -2);
  86. assertElementsEquals([2, 7, 0, 0], v0);
  87. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  88. goog.vec.mat4d.getDiagonal(m0, v0, -3);
  89. assertElementsEquals([3, 0, 0, 0], v0);
  90. goog.vec.vec4d.setFromArray(v0, [0, 0, 0, 0]);
  91. goog.vec.mat4d.getDiagonal(m0, v0, -4);
  92. assertElementsEquals([0, 0, 0, 0], v0);
  93. }
  94. function testSetGetColumn() {
  95. var m0 = goog.vec.mat4d.create();
  96. goog.vec.mat4d.setColumn(m0, 0, [1, 2, 3, 4]);
  97. goog.vec.mat4d.setColumn(m0, 1, [5, 6, 7, 8]);
  98. goog.vec.mat4d.setColumn(m0, 2, [9, 10, 11, 12]);
  99. goog.vec.mat4d.setColumn(m0, 3, [13, 14, 15, 16]);
  100. assertElementsEquals(
  101. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  102. var v0 = [0, 0, 0, 0];
  103. goog.vec.mat4d.getColumn(m0, 0, v0);
  104. assertElementsEquals([1, 2, 3, 4], v0);
  105. goog.vec.mat4d.getColumn(m0, 1, v0);
  106. assertElementsEquals([5, 6, 7, 8], v0);
  107. goog.vec.mat4d.getColumn(m0, 2, v0);
  108. assertElementsEquals([9, 10, 11, 12], v0);
  109. goog.vec.mat4d.getColumn(m0, 3, v0);
  110. assertElementsEquals([13, 14, 15, 16], v0);
  111. }
  112. function testSetGetColumns() {
  113. var m0 = goog.vec.mat4d.create();
  114. goog.vec.mat4d.setColumns(
  115. m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
  116. assertElementsEquals(
  117. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  118. var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
  119. var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
  120. goog.vec.mat4d.getColumns(m0, v0, v1, v2, v3);
  121. assertElementsEquals([1, 2, 3, 4], v0);
  122. assertElementsEquals([5, 6, 7, 8], v1);
  123. assertElementsEquals([9, 10, 11, 12], v2);
  124. assertElementsEquals([13, 14, 15, 16], v3);
  125. }
  126. function testSetGetRow() {
  127. var m0 = goog.vec.mat4d.create();
  128. goog.vec.mat4d.setRow(m0, 0, [1, 2, 3, 4]);
  129. goog.vec.mat4d.setRow(m0, 1, [5, 6, 7, 8]);
  130. goog.vec.mat4d.setRow(m0, 2, [9, 10, 11, 12]);
  131. goog.vec.mat4d.setRow(m0, 3, [13, 14, 15, 16]);
  132. assertElementsEquals(
  133. [1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
  134. var v0 = [0, 0, 0, 0];
  135. goog.vec.mat4d.getRow(m0, 0, v0);
  136. assertElementsEquals([1, 2, 3, 4], v0);
  137. goog.vec.mat4d.getRow(m0, 1, v0);
  138. assertElementsEquals([5, 6, 7, 8], v0);
  139. goog.vec.mat4d.getRow(m0, 2, v0);
  140. assertElementsEquals([9, 10, 11, 12], v0);
  141. goog.vec.mat4d.getRow(m0, 3, v0);
  142. assertElementsEquals([13, 14, 15, 16], v0);
  143. }
  144. function testSetGetRows() {
  145. var m0 = goog.vec.mat4d.create();
  146. goog.vec.mat4d.setRows(
  147. m0, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
  148. assertElementsEquals(
  149. [1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m0);
  150. var v0 = [0, 0, 0, 0], v1 = [0, 0, 0, 0];
  151. var v2 = [0, 0, 0, 0], v3 = [0, 0, 0, 0];
  152. goog.vec.mat4d.getRows(m0, v0, v1, v2, v3);
  153. assertElementsEquals([1, 2, 3, 4], v0);
  154. assertElementsEquals([5, 6, 7, 8], v1);
  155. assertElementsEquals([9, 10, 11, 12], v2);
  156. assertElementsEquals([13, 14, 15, 16], v3);
  157. }
  158. function testMakeZero() {
  159. var m0 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
  160. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
  161. assertElementsEquals(
  162. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  163. goog.vec.mat4d.makeZero(m0);
  164. assertElementsEquals(
  165. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], m0);
  166. }
  167. function testMakeIdentity() {
  168. var m0 = goog.vec.mat4d.create();
  169. goog.vec.mat4d.makeIdentity(m0);
  170. assertElementsEquals(
  171. [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], m0);
  172. }
  173. function testSetGetElement() {
  174. var m0 = goog.vec.mat4d.create();
  175. for (var r = 0; r < 4; r++) {
  176. for (var c = 0; c < 4; c++) {
  177. var value = c * 4 + r + 1;
  178. goog.vec.mat4d.setElement(m0, r, c, value);
  179. assertEquals(value, goog.vec.mat4d.getElement(m0, r, c));
  180. }
  181. }
  182. assertElementsEquals(
  183. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  184. }
  185. function testAddMat() {
  186. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  187. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  188. var m1 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  189. 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
  190. var m2 = goog.vec.mat4d.create();
  191. goog.vec.mat4d.addMat(m0, m1, m2);
  192. assertElementsEquals(
  193. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  194. assertElementsEquals(
  195. [9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
  196. assertElementsEquals(
  197. [10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m2);
  198. goog.vec.mat4d.addMat(m0, m1, m0);
  199. assertElementsEquals(
  200. [9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
  201. assertElementsEquals(
  202. [10, 12, 14, 16, 18, 20, 22, 24, 10, 12, 14, 16, 18, 20, 22, 24], m0);
  203. }
  204. function testSubMat() {
  205. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  206. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  207. var m1 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  208. 9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8);
  209. var m2 = goog.vec.mat4d.create();
  210. goog.vec.mat4d.subMat(m0, m1, m2);
  211. assertElementsEquals(
  212. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  213. assertElementsEquals(
  214. [9, 10, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5, 6, 7, 8], m1);
  215. assertElementsEquals(
  216. [-8, -8, -8, -8, -8, -8, -8, -8, 8, 8, 8, 8, 8, 8, 8, 8], m2);
  217. goog.vec.mat4d.subMat(m1, m0, m1);
  218. assertElementsEquals(
  219. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  220. assertElementsEquals(
  221. [8, 8, 8, 8, 8, 8, 8, 8, -8, -8, -8, -8, -8, -8, -8, -8], m1);
  222. }
  223. function testMultScalar() {
  224. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  225. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  226. var m1 = goog.vec.mat4d.create();
  227. goog.vec.mat4d.multScalar(m0, 2, m1);
  228. assertElementsEquals(
  229. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m0);
  230. assertElementsEquals(
  231. [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32], m1);
  232. goog.vec.mat4d.multScalar(m0, 5, m0);
  233. assertElementsEquals(
  234. [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80], m0);
  235. }
  236. function testMultMat() {
  237. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  238. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  239. var m1 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  240. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  241. var m2 = goog.vec.mat4d.create();
  242. goog.vec.mat4d.multMat(m0, m1, m2);
  243. assertElementsEquals(
  244. [90, 100, 110, 120, 202, 228, 254, 280,
  245. 314, 356, 398, 440, 426, 484, 542, 600], m2);
  246. goog.vec.mat4d.multScalar(m1, 2, m1);
  247. goog.vec.mat4d.multMat(m1, m0, m1);
  248. assertElementsEquals(
  249. [180, 200, 220, 240, 404, 456, 508, 560,
  250. 628, 712, 796, 880, 852, 968, 1084, 1200], m1);
  251. }
  252. function testTranspose() {
  253. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  254. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  255. var m1 = goog.vec.mat4d.create();
  256. goog.vec.mat4d.transpose(m0, m1);
  257. assertElementsEquals(
  258. [1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16], m1);
  259. goog.vec.mat4d.transpose(m1, m1);
  260. assertElementsEquals(
  261. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], m1);
  262. }
  263. function testDeterminant() {
  264. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  265. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
  266. assertEquals(0, goog.vec.mat4d.determinant(m0));
  267. assertElementsEquals(
  268. [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
  269. goog.vec.mat4d.setFromValues(
  270. m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
  271. assertEquals(160, goog.vec.mat4d.determinant(m0));
  272. assertElementsEquals(
  273. [1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3], m0);
  274. }
  275. function testInvert() {
  276. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  277. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
  278. assertFalse(goog.vec.mat4d.invert(m0, m0));
  279. assertElementsEquals(
  280. [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], m0);
  281. goog.vec.mat4d.setFromValues(
  282. m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
  283. assertTrue(goog.vec.mat4d.invert(m0, m0));
  284. assertElementsRoughlyEqual(
  285. [-0.225, 0.025, 0.025, 0.275, 0.025, 0.025, 0.275, -0.225,
  286. 0.025, 0.275, -0.225, 0.025, 0.275, -0.225, 0.025, 0.025], m0,
  287. goog.vec.EPSILON);
  288. goog.vec.mat4d.makeScale(m0, .01, .01, .01);
  289. assertTrue(goog.vec.mat4d.invert(m0, m0));
  290. var m1 = goog.vec.mat4d.create();
  291. goog.vec.mat4d.makeScale(m1, 100, 100, 100);
  292. assertElementsEquals(m1, m0);
  293. }
  294. function testEquals() {
  295. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  296. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  297. var m1 = goog.vec.mat4d.setFromMat4d(goog.vec.mat4d.create(), m0);
  298. assertTrue(goog.vec.mat4d.equals(m0, m1));
  299. assertTrue(goog.vec.mat4d.equals(m1, m0));
  300. for (var i = 0; i < 16; i++) {
  301. m1[i] = 18;
  302. assertFalse(goog.vec.mat4d.equals(m0, m1));
  303. assertFalse(goog.vec.mat4d.equals(m1, m0));
  304. m1[i] = i + 1;
  305. }
  306. }
  307. function testMultVec3() {
  308. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  309. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  310. var v0 = [1, 2, 3];
  311. var v1 = [0, 0, 0];
  312. goog.vec.mat4d.multVec3(m0, v0, v1);
  313. assertElementsEquals([1, 2, 3], v0);
  314. assertElementsEquals([51, 58, 65], v1);
  315. goog.vec.mat4d.multVec3(m0, v0, v0);
  316. assertElementsEquals([51, 58, 65], v0);
  317. }
  318. function testMultVec3NoTranslate() {
  319. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  320. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  321. var v0 = [1, 2, 3];
  322. var v1 = [0, 0, 0];
  323. goog.vec.mat4d.multVec3NoTranslate(m0, v0, v1);
  324. assertElementsEquals([1, 2, 3], v0);
  325. assertElementsEquals([38, 44, 50], v1);
  326. goog.vec.mat4d.multVec3NoTranslate(m0, v0, v0);
  327. assertElementsEquals([38, 44, 50], v0);
  328. }
  329. function testMultVec3Projective() {
  330. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  331. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  332. var v0 = [1, 2, 3];
  333. var v1 = [0, 0, 0];
  334. var invw = 1 / 72;
  335. goog.vec.mat4d.multVec3Projective(m0, v0, v1);
  336. assertElementsEquals([1, 2, 3], v0);
  337. assertElementsEquals(
  338. [51 * invw, 58 * invw, 65 * invw], v1);
  339. goog.vec.mat4d.multVec3Projective(m0, v0, v0);
  340. assertElementsEquals(
  341. [51 * invw, 58 * invw, 65 * invw], v0);
  342. }
  343. function testMultVec4() {
  344. var m0 = goog.vec.mat4d.setFromValues(goog.vec.mat4d.create(),
  345. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
  346. var v0 = [1, 2, 3, 4];
  347. var v1 = [0, 0, 0, 0];
  348. goog.vec.mat4d.multVec4(m0, v0, v1);
  349. assertElementsEquals([90, 100, 110, 120], v1);
  350. goog.vec.mat4d.multVec4(m0, v0, v0);
  351. assertElementsEquals([90, 100, 110, 120], v0);
  352. }
  353. function testSetValues() {
  354. var a0 = goog.vec.mat4d.create();
  355. assertElementsEquals(
  356. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], a0);
  357. a0 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
  358. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
  359. assertElementsEquals(
  360. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a0);
  361. var a1 = goog.vec.mat4d.create();
  362. goog.vec.mat4d.setDiagonalValues(a1, 1, 2, 3, 4);
  363. assertElementsEquals(
  364. [1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4], a1);
  365. goog.vec.mat4d.setColumnValues(a1, 0, 2, 3, 4, 5);
  366. goog.vec.mat4d.setColumnValues(a1, 1, 6, 7, 8, 9);
  367. goog.vec.mat4d.setColumnValues(a1, 2, 10, 11, 12, 13);
  368. goog.vec.mat4d.setColumnValues(a1, 3, 14, 15, 16, 1);
  369. assertElementsEquals(
  370. [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1], a1);
  371. goog.vec.mat4d.setRowValues(a1, 0, 1, 5, 9, 13);
  372. goog.vec.mat4d.setRowValues(a1, 1, 2, 6, 10, 14);
  373. goog.vec.mat4d.setRowValues(a1, 2, 3, 7, 11, 15);
  374. goog.vec.mat4d.setRowValues(a1, 3, 4, 8, 12, 16);
  375. assertElementsEquals(
  376. [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], a1);
  377. }
  378. function testMakeTranslate() {
  379. var m0 = goog.vec.mat4d.create();
  380. goog.vec.mat4d.makeTranslate(m0, 3, 4, 5);
  381. assertElementsEquals(
  382. [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
  383. }
  384. function testMakeScale() {
  385. var m0 = goog.vec.mat4d.create();
  386. goog.vec.mat4d.makeScale(m0, 3, 4, 5);
  387. assertElementsEquals(
  388. [3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
  389. }
  390. function testMakeRotate() {
  391. var m0 = goog.vec.mat4d.create();
  392. goog.vec.mat4d.makeRotate(m0, Math.PI / 2, 0, 0, 1);
  393. assertElementsRoughlyEqual(
  394. [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
  395. m0, goog.vec.EPSILON);
  396. var m1 = goog.vec.mat4d.create();
  397. goog.vec.mat4d.makeRotate(m1, -Math.PI / 4, 0, 0, 1);
  398. goog.vec.mat4d.multMat(m0, m1, m1);
  399. assertElementsRoughlyEqual(
  400. [0.7071068, 0.7071068, 0, 0,
  401. -0.7071068, 0.7071068, 0, 0,
  402. 0, 0, 1, 0,
  403. 0, 0, 0, 1],
  404. m1, goog.vec.EPSILON);
  405. }
  406. function testMakeRotateX() {
  407. var m0 = goog.vec.mat4d.create();
  408. var m1 = goog.vec.mat4d.create();
  409. goog.vec.mat4d.makeRotateX(m0, Math.PI / 7);
  410. goog.vec.mat4d.makeRotate(m1, Math.PI / 7, 1, 0, 0);
  411. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  412. }
  413. function testMakeRotateY() {
  414. var m0 = goog.vec.mat4d.create();
  415. var m1 = goog.vec.mat4d.create();
  416. goog.vec.mat4d.makeRotateY(m0, Math.PI / 7);
  417. goog.vec.mat4d.makeRotate(m1, Math.PI / 7, 0, 1, 0);
  418. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  419. }
  420. function testMakeRotateZ() {
  421. var m0 = goog.vec.mat4d.create();
  422. var m1 = goog.vec.mat4d.create();
  423. goog.vec.mat4d.makeRotateZ(m0, Math.PI / 7);
  424. goog.vec.mat4d.makeRotate(m1, Math.PI / 7, 0, 0, 1);
  425. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  426. }
  427. function testTranslate() {
  428. var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
  429. goog.vec.mat4d.translate(m0, 3, 4, 5);
  430. assertElementsEquals(
  431. [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3, 4, 5, 1], m0);
  432. goog.vec.mat4d.setFromValues(
  433. m0, 1, 2, 3, 4, 2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3);
  434. var m1 = goog.vec.mat4d.create();
  435. goog.vec.mat4d.makeTranslate(m1, 5, 6, 7);
  436. var m2 = goog.vec.mat4d.create();
  437. goog.vec.mat4d.multMat(m0, m1, m2);
  438. goog.vec.mat4d.translate(m0, 5, 6, 7);
  439. assertElementsEquals(m2, m0);
  440. }
  441. function testScale() {
  442. var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
  443. goog.vec.mat4d.scale(m0, 3, 4, 5);
  444. assertElementsEquals([3, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1], m0);
  445. }
  446. function testRotate() {
  447. var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
  448. goog.vec.mat4d.rotate(m0, Math.PI / 2, 0, 0, 1);
  449. assertElementsRoughlyEqual(
  450. [0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
  451. m0, goog.vec.EPSILON);
  452. goog.vec.mat4d.rotate(m0, -Math.PI / 4, 0, 0, 1);
  453. assertElementsRoughlyEqual(
  454. [0.7071068, 0.7071068, 0, 0,
  455. -0.7071068, 0.7071068, 0, 0,
  456. 0, 0, 1, 0,
  457. 0, 0, 0, 1],
  458. m0, goog.vec.EPSILON);
  459. }
  460. function testRotateX() {
  461. var m0 = goog.vec.mat4d.create();
  462. var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d);
  463. goog.vec.mat4d.makeRotateX(m0, Math.PI / 7);
  464. goog.vec.mat4d.multMat(m1, m0, m0);
  465. goog.vec.mat4d.rotateX(m1, Math.PI / 7);
  466. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  467. }
  468. function testRotateY() {
  469. var m0 = goog.vec.mat4d.create();
  470. var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d);
  471. goog.vec.mat4d.makeRotateY(m0, Math.PI / 7);
  472. goog.vec.mat4d.multMat(m1, m0, m0);
  473. goog.vec.mat4d.rotateY(m1, Math.PI / 7);
  474. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  475. }
  476. function testRotateZ() {
  477. var m0 = goog.vec.mat4d.create();
  478. var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d);
  479. goog.vec.mat4d.makeRotateZ(m0, Math.PI / 7);
  480. goog.vec.mat4d.multMat(m1, m0, m0);
  481. goog.vec.mat4d.rotateZ(m1, Math.PI / 7);
  482. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  483. }
  484. function testMakeRotationTranslation() {
  485. // Create manually.
  486. var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
  487. goog.vec.mat4d.translate(m0, 3, 4, 5);
  488. goog.vec.mat4d.rotate(m0, Math.PI / 2, 3 / 13, 4 / 13, 12 / 13);
  489. // Create using makeRotationTranslation.
  490. var m1 = goog.vec.mat4d.create();
  491. var q = goog.vec.Quaternion.createFloat64();
  492. var axis = goog.vec.vec3d.createFromValues(3 / 13, 4 / 13, 12 / 13);
  493. goog.vec.Quaternion.fromAngleAxis(Math.PI / 2, axis, q);
  494. var v = goog.vec.vec3d.createFromValues(3, 4, 5);
  495. goog.vec.mat4d.makeRotationTranslation(m1, q, v);
  496. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  497. }
  498. function testMakeRotationTranslationScale() {
  499. // Create manually.
  500. var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
  501. goog.vec.mat4d.translate(m0, 3, 4, 5);
  502. goog.vec.mat4d.rotate(m0, Math.PI / 2, 3 / 13, 4 / 13, 12 / 13);
  503. goog.vec.mat4d.scale(m0, 6, 7, 8);
  504. // Create using makeRotationTranslationScale.
  505. var m1 = goog.vec.mat4d.create();
  506. var q = goog.vec.Quaternion.createFloat64();
  507. var axis = goog.vec.vec3d.createFromValues(3 / 13, 4 / 13, 12 / 13);
  508. goog.vec.Quaternion.fromAngleAxis(Math.PI / 2, axis, q);
  509. var v = goog.vec.vec3d.createFromValues(3, 4, 5);
  510. var s = goog.vec.vec3d.createFromValues(6, 7, 8);
  511. goog.vec.mat4d.makeRotationTranslationScale(m1, q, v, s);
  512. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  513. }
  514. function testMakeRotationTranslationScaleOrigin() {
  515. // Create manually.
  516. var m0 = goog.vec.mat4d.makeIdentity(goog.vec.mat4d.create());
  517. goog.vec.mat4d.translate(m0, 3, 4, 5);
  518. goog.vec.mat4d.translate(m0, 9, 10, -11); // Origin.
  519. goog.vec.mat4d.rotate(m0, Math.PI / 2, 3 / 13, 4 / 13, 12 / 13);
  520. goog.vec.mat4d.scale(m0, 6, 7, 8);
  521. goog.vec.mat4d.translate(m0, -9, -10, 11); // -Origin.
  522. // Create using makeRotationTranslationScaleOrigin.
  523. var m1 = goog.vec.mat4d.create();
  524. var q = goog.vec.Quaternion.createFloat64();
  525. var axis = goog.vec.vec3d.createFromValues(3 / 13, 4 / 13, 12 / 13);
  526. goog.vec.Quaternion.fromAngleAxis(Math.PI / 2, axis, q);
  527. var v = goog.vec.vec3d.createFromValues(3, 4, 5);
  528. var s = goog.vec.vec3d.createFromValues(6, 7, 8);
  529. var o = goog.vec.vec3d.createFromValues(9, 10, -11);
  530. goog.vec.mat4d.makeRotationTranslationScaleOrigin(m1, q, v, s, o);
  531. assertElementsRoughlyEqual(m0, m1, 0.00001); // Slightly larger epsilon.
  532. }
  533. function testGetTranslation() {
  534. var mat = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d);
  535. var translation = goog.vec.vec3d.create();
  536. goog.vec.mat4d.getTranslation(mat, translation);
  537. assertElementsRoughlyEqual(
  538. [0.59465038776, 0.413479506969, 0.0663217827677],
  539. translation, goog.vec.EPSILON);
  540. }
  541. function testMakeFrustum() {
  542. var m0 = goog.vec.mat4d.create();
  543. goog.vec.mat4d.makeFrustum(m0, -1, 2, -2, 1, .1, 1.1);
  544. assertElementsRoughlyEqual(
  545. [0.06666666, 0, 0, 0,
  546. 0, 0.06666666, 0, 0,
  547. 0.33333333, -0.33333333, -1.2, -1,
  548. 0, 0, -0.22, 0], m0, goog.vec.EPSILON);
  549. }
  550. function testMakePerspective() {
  551. var m0 = goog.vec.mat4d.create();
  552. goog.vec.mat4d.makePerspective(m0, 90 * Math.PI / 180, 2, 0.1, 1.1);
  553. assertElementsRoughlyEqual(
  554. [0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1.2, -1, 0, 0, -0.22, 0],
  555. m0, goog.vec.EPSILON);
  556. }
  557. function testMakeOrtho() {
  558. var m0 = goog.vec.mat4d.create();
  559. goog.vec.mat4d.makeOrtho(m0, -1, 2, -2, 1, 0.1, 1.1);
  560. assertElementsRoughlyEqual(
  561. [0.6666666, 0, 0, 0,
  562. 0, 0.6666666, 0, 0,
  563. 0, 0, -2, 0,
  564. -0.333333, 0.3333333, -1.2, 1], m0, goog.vec.EPSILON);
  565. }
  566. function testMakeEulerZXZ() {
  567. var m0 = goog.vec.mat4d.create();
  568. var roll = 0.200982 * 2 * Math.PI;
  569. var tilt = 0.915833 * Math.PI;
  570. var yaw = 0.839392 * 2 * Math.PI;
  571. goog.vec.mat4d.makeRotate(m0, roll, 0, 0, 1);
  572. goog.vec.mat4d.rotate(m0, tilt, 1, 0, 0);
  573. goog.vec.mat4d.rotate(m0, yaw, 0, 0, 1);
  574. var m1 = goog.vec.mat4d.create();
  575. goog.vec.mat4d.makeEulerZXZ(m1, roll, tilt, yaw);
  576. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  577. var euler = [0, 0, 0];
  578. goog.vec.mat4d.toEulerZXZ(m0, euler);
  579. assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
  580. assertRoughlyEquals(tilt, euler[1], goog.vec.EPSILON);
  581. assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
  582. // Test negative tilt now.
  583. goog.vec.mat4d.makeRotate(m0, roll, 0, 0, 1);
  584. goog.vec.mat4d.rotate(m0, -tilt, 1, 0, 0);
  585. goog.vec.mat4d.rotate(m0, yaw, 0, 0, 1);
  586. goog.vec.mat4d.makeEulerZXZ(m1, roll, -tilt, yaw);
  587. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  588. var euler = [0, 0, 0];
  589. goog.vec.mat4d.toEulerZXZ(m0, euler, true);
  590. assertRoughlyEquals(roll, euler[0], goog.vec.EPSILON);
  591. assertRoughlyEquals(-tilt, euler[1], goog.vec.EPSILON);
  592. assertRoughlyEquals(yaw, euler[2], goog.vec.EPSILON);
  593. }
  594. function testEulerZXZExtrema() {
  595. var m0 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
  596. [1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1]);
  597. var m1 = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(),
  598. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
  599. var euler = [0, 0, 0];
  600. goog.vec.mat4d.toEulerZXZ(m0, euler);
  601. assertElementsRoughlyEqual(
  602. [Math.PI, Math.PI / 2, Math.PI], euler, goog.vec.EPSILON);
  603. goog.vec.mat4d.makeEulerZXZ(m1, euler[0], euler[1], euler[2]);
  604. assertElementsRoughlyEqual(m0, m1, goog.vec.EPSILON);
  605. }
  606. function testLookAt() {
  607. var viewMatrix = goog.vec.mat4d.create();
  608. goog.vec.mat4d.makeLookAt(
  609. viewMatrix, [0, 0, 0], [1, 0, 0], [0, 1, 0]);
  610. assertElementsRoughlyEqual(
  611. [0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], viewMatrix,
  612. goog.vec.EPSILON);
  613. }
  614. function testToLookAt() {
  615. // This test does not use the default precision goog.vec.EPSILON due to
  616. // precision issues in some browsers leading to flaky tests.
  617. var EPSILON = 1e-4;
  618. var eyeExp = [0, 0, 0];
  619. var fwdExp = [1, 0, 0];
  620. var upExp = [0, 1, 0];
  621. var centerExp = [0, 0, 0];
  622. goog.vec.vec3d.add(eyeExp, fwdExp, centerExp);
  623. var view = goog.vec.mat4d.create();
  624. goog.vec.mat4d.makeLookAt(view, eyeExp, centerExp, upExp);
  625. var eyeRes = [0, 0, 0];
  626. var fwdRes = [0, 0, 0];
  627. var upRes = [0, 0, 0];
  628. goog.vec.mat4d.toLookAt(view, eyeRes, fwdRes, upRes);
  629. assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
  630. assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
  631. assertElementsRoughlyEqual(upExp, upRes, EPSILON);
  632. }
  633. function testLookAtDecomposition() {
  634. // This test does not use the default precision goog.vec.EPSILON due to
  635. // precision issues in some browsers leading to flaky tests.
  636. var EPSILON = 1e-4;
  637. var viewExp = goog.vec.mat4d.create();
  638. var viewRes = goog.vec.mat4d.create();
  639. // Get a valid set of random vectors eye, forward, up by decomposing
  640. // a random matrix into a set of lookAt vectors.
  641. var tmp = goog.vec.mat4d.setFromArray(goog.vec.mat4d.create(), randommat4d);
  642. var eyeExp = [0, 0, 0];
  643. var fwdExp = [0, 0, 0];
  644. var upExp = [0, 0, 0];
  645. var centerExp = [0, 0, 0];
  646. // Project the random matrix into a real modelview matrix.
  647. goog.vec.mat4d.toLookAt(tmp, eyeExp, fwdExp, upExp);
  648. goog.vec.vec3d.add(eyeExp, fwdExp, centerExp);
  649. // Compute the expected modelview matrix from a set of valid random vectors.
  650. goog.vec.mat4d.makeLookAt(viewExp, eyeExp, centerExp, upExp);
  651. var eyeRes = [0, 0, 0];
  652. var fwdRes = [0, 0, 0];
  653. var upRes = [0, 0, 0];
  654. var centerRes = [0, 0, 0];
  655. goog.vec.mat4d.toLookAt(viewExp, eyeRes, fwdRes, upRes);
  656. goog.vec.vec3d.add(eyeRes, fwdRes, centerRes);
  657. goog.vec.mat4d.makeLookAt(viewRes, eyeRes, centerRes, upRes);
  658. assertElementsRoughlyEqual(eyeExp, eyeRes, EPSILON);
  659. assertElementsRoughlyEqual(fwdExp, fwdRes, EPSILON);
  660. assertElementsRoughlyEqual(upExp, upRes, EPSILON);
  661. assertElementsRoughlyEqual(viewExp, viewRes, EPSILON);
  662. }