mat4_spec.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. local mat4 = require "modules.mat4"
  2. local vec3 = require "modules.vec3"
  3. local utils = require "modules.utils"
  4. describe("mat4:", function()
  5. it("creates an identity matrix", function()
  6. local a = mat4()
  7. assert.is.equal(1, a[1])
  8. assert.is.equal(0, a[2])
  9. assert.is.equal(0, a[3])
  10. assert.is.equal(0, a[4])
  11. assert.is.equal(0, a[5])
  12. assert.is.equal(1, a[6])
  13. assert.is.equal(0, a[7])
  14. assert.is.equal(0, a[8])
  15. assert.is.equal(0, a[9])
  16. assert.is.equal(0, a[10])
  17. assert.is.equal(1, a[11])
  18. assert.is.equal(0, a[12])
  19. assert.is.equal(0, a[13])
  20. assert.is.equal(0, a[14])
  21. assert.is.equal(0, a[15])
  22. assert.is.equal(1, a[16])
  23. assert.is_true(a:is_mat4())
  24. end)
  25. it("creates a filled matrix", function()
  26. local a = mat4 {
  27. 3, 3, 3, 3,
  28. 4, 4, 4, 4,
  29. 5, 5, 5, 5,
  30. 6, 6, 6, 6
  31. }
  32. assert.is.equal(3, a[1])
  33. assert.is.equal(3, a[2])
  34. assert.is.equal(3, a[3])
  35. assert.is.equal(3, a[4])
  36. assert.is.equal(4, a[5])
  37. assert.is.equal(4, a[6])
  38. assert.is.equal(4, a[7])
  39. assert.is.equal(4, a[8])
  40. assert.is.equal(5, a[9])
  41. assert.is.equal(5, a[10])
  42. assert.is.equal(5, a[11])
  43. assert.is.equal(5, a[12])
  44. assert.is.equal(6, a[13])
  45. assert.is.equal(6, a[14])
  46. assert.is.equal(6, a[15])
  47. assert.is.equal(6, a[16])
  48. end)
  49. it("creates a filled matrix from vec4s", function()
  50. local a = mat4 {
  51. { 3, 3, 3, 3 },
  52. { 4, 4, 4, 4 },
  53. { 5, 5, 5, 5 },
  54. { 6, 6, 6, 6 }
  55. }
  56. assert.is.equal(3, a[1])
  57. assert.is.equal(3, a[2])
  58. assert.is.equal(3, a[3])
  59. assert.is.equal(3, a[4])
  60. assert.is.equal(4, a[5])
  61. assert.is.equal(4, a[6])
  62. assert.is.equal(4, a[7])
  63. assert.is.equal(4, a[8])
  64. assert.is.equal(5, a[9])
  65. assert.is.equal(5, a[10])
  66. assert.is.equal(5, a[11])
  67. assert.is.equal(5, a[12])
  68. assert.is.equal(6, a[13])
  69. assert.is.equal(6, a[14])
  70. assert.is.equal(6, a[15])
  71. assert.is.equal(6, a[16])
  72. end)
  73. it("creates a filled matrix from a 3x3 matrix", function()
  74. local a = mat4 {
  75. 3, 3, 3,
  76. 4, 4, 4,
  77. 5, 5, 5
  78. }
  79. assert.is.equal(3, a[1])
  80. assert.is.equal(3, a[2])
  81. assert.is.equal(3, a[3])
  82. assert.is.equal(0, a[4])
  83. assert.is.equal(4, a[5])
  84. assert.is.equal(4, a[6])
  85. assert.is.equal(4, a[7])
  86. assert.is.equal(0, a[8])
  87. assert.is.equal(5, a[9])
  88. assert.is.equal(5, a[10])
  89. assert.is.equal(5, a[11])
  90. assert.is.equal(0, a[12])
  91. assert.is.equal(0, a[13])
  92. assert.is.equal(0, a[14])
  93. assert.is.equal(0, a[15])
  94. assert.is.equal(1, a[16])
  95. end)
  96. it("creates a matrix from perspective", function()
  97. local a = mat4.from_perspective(45, 1, 0.1, 1000)
  98. assert.is_true(utils.tolerance( 2.414-a[1], 0.001))
  99. assert.is_true(utils.tolerance( 2.414-a[6], 0.001))
  100. assert.is_true(utils.tolerance(-1 -a[11], 0.001))
  101. assert.is_true(utils.tolerance(-1 -a[12], 0.001))
  102. assert.is_true(utils.tolerance(-0.2 -a[15], 0.001))
  103. end)
  104. it("creates a matrix from HMD perspective", function()
  105. local t = {
  106. LeftTan = 2.3465312,
  107. RightTan = 0.9616399,
  108. UpTan = 2.8664987,
  109. DownTan = 2.8664987
  110. }
  111. local a = mat4.from_hmd_perspective(t, 0.1, 1000, false, false)
  112. assert.is_true(utils.tolerance(a[1] - 0.605, 0.001))
  113. assert.is_true(utils.tolerance(a[6] - 0.349, 0.001))
  114. assert.is_true(utils.tolerance(a[9] - -0.419, 0.001))
  115. assert.is_true(utils.tolerance(a[11]- -1.000, 0.001))
  116. assert.is_true(utils.tolerance(a[12]- -1.000, 0.001))
  117. assert.is_true(utils.tolerance(a[15]- -0.200, 0.001))
  118. end)
  119. it("clones a matrix", function()
  120. local a = mat4.identity()
  121. local b = a:clone()
  122. assert.is.equal(a, b)
  123. end)
  124. it("multiplies two 4x4 matrices", function()
  125. local a = mat4 {
  126. 1, 2, 3, 4,
  127. 5, 6, 7, 8,
  128. 9, 10, 11, 12,
  129. 13, 14, 15, 16
  130. }
  131. local b = mat4 {
  132. 1, 5, 9, 13,
  133. 2, 6, 10, 14,
  134. 3, 7, 11, 15,
  135. 4, 8, 12, 16
  136. }
  137. local c = a:mul(b)
  138. local d = a * b
  139. assert.is.equal(30, c[1])
  140. assert.is.equal(70, c[2])
  141. assert.is.equal(110, c[3])
  142. assert.is.equal(150, c[4])
  143. assert.is.equal(70, c[5])
  144. assert.is.equal(174, c[6])
  145. assert.is.equal(278, c[7])
  146. assert.is.equal(382, c[8])
  147. assert.is.equal(110, c[9])
  148. assert.is.equal(278, c[10])
  149. assert.is.equal(446, c[11])
  150. assert.is.equal(614, c[12])
  151. assert.is.equal(150, c[13])
  152. assert.is.equal(382, c[14])
  153. assert.is.equal(614, c[15])
  154. assert.is.equal(846, c[16])
  155. assert.is.equal(c, d)
  156. end)
  157. it("multiplies a matrix and a vec4", function()
  158. local a = mat4 {
  159. 1, 2, 3, 4,
  160. 5, 6, 7, 8,
  161. 9, 10, 11, 12,
  162. 13, 14, 15, 16
  163. }
  164. local b = { 10, 20, 30, 40 }
  165. local c = mat4.mul_vec4(a, b)
  166. local d = a * b
  167. assert.is.equal(900, c[1])
  168. assert.is.equal(1000, c[2])
  169. assert.is.equal(1100, c[3])
  170. assert.is.equal(1200, c[4])
  171. assert.is.equal(c[1], d[1])
  172. assert.is.equal(c[2], d[2])
  173. assert.is.equal(c[3], d[3])
  174. assert.is.equal(c[4], d[4])
  175. end)
  176. it("scales a matrix", function()
  177. local a = mat4():scale(vec3(5, 5, 5))
  178. assert.is.equal(5, a[1])
  179. assert.is.equal(5, a[6])
  180. assert.is.equal(5, a[11])
  181. end)
  182. it("rotates a matrix", function()
  183. local a = mat4():rotate(math.rad(45), vec3.unit_z)
  184. assert.is_true(utils.tolerance( 0.7071-a[1], 0.001))
  185. assert.is_true(utils.tolerance( 0.7071-a[2], 0.001))
  186. assert.is_true(utils.tolerance(-0.7071-a[5], 0.001))
  187. assert.is_true(utils.tolerance( 0.7071-a[6], 0.001))
  188. end)
  189. it("translates a matrix", function()
  190. local a = mat4():translate(vec3(5, 5, 5))
  191. assert.is.equal(5, a[13])
  192. assert.is.equal(5, a[14])
  193. assert.is.equal(5, a[15])
  194. end)
  195. it("inverts a matrix", function()
  196. local a = mat4()
  197. :rotate(math.pi/4, vec3.unit_y)
  198. :translate(vec3(4, 5, 6))
  199. local b = a:invert()
  200. local c = a * b
  201. assert.is.equal(mat4(), c)
  202. local d = mat4()
  203. :rotate(math.pi/4, vec3.unit_y)
  204. :translate(vec3(4, 5, 6))
  205. local e = -d
  206. local f = d * e
  207. assert.is.equal(mat4(), f)
  208. end)
  209. it("transposes a matrix", function()
  210. local a = mat4({
  211. 1, 1, 1, 1,
  212. 2, 2, 2, 2,
  213. 3, 3, 3, 3,
  214. 4, 4, 4, 4
  215. }):transpose()
  216. assert.is.equal(1, a[1])
  217. assert.is.equal(2, a[2])
  218. assert.is.equal(3, a[3])
  219. assert.is.equal(4, a[4])
  220. assert.is.equal(1, a[5])
  221. assert.is.equal(2, a[6])
  222. assert.is.equal(3, a[7])
  223. assert.is.equal(4, a[8])
  224. assert.is.equal(1, a[9])
  225. assert.is.equal(2, a[10])
  226. assert.is.equal(3, a[11])
  227. assert.is.equal(4, a[12])
  228. assert.is.equal(1, a[13])
  229. assert.is.equal(2, a[14])
  230. assert.is.equal(3, a[15])
  231. assert.is.equal(4, a[16])
  232. end)
  233. it("shears a matrix", function()
  234. local yx, zx, xy, zy, xz, yz = 1, 1, 1, -1, -1, -1
  235. local a = mat4():shear(yx, zx, xy, zy, xz, yz)
  236. assert.is.equal( 1, a[2])
  237. assert.is.equal( 1, a[3])
  238. assert.is.equal( 1, a[5])
  239. assert.is.equal(-1, a[7])
  240. assert.is.equal(-1, a[9])
  241. assert.is.equal(-1, a[10])
  242. end)
  243. it("projects a matrix into screen space", function()
  244. local v = vec3(0, 0, 10)
  245. local a = mat4()
  246. local b = mat4.from_perspective(45, 1, 0.1, 1000)
  247. local vp = { 0, 0, 400, 400 }
  248. local c = mat4.project(v, a, b, vp)
  249. assert.is.equal(200, c.x)
  250. assert.is.equal(200, c.y)
  251. assert.is_true(utils.tolerance(1.0101-c.z, 0.001))
  252. end)
  253. it("unprojects a matrix into world space", function()
  254. local v = vec3(0, 0, 10)
  255. local a = mat4()
  256. local b = mat4.from_perspective(45, 1, 0.1, 1000)
  257. local vp = { 0, 0, 400, 400 }
  258. local c = mat4.project(v, a, b, vp)
  259. local d = mat4.unproject(c, a, b, vp)
  260. assert.is_true(utils.tolerance(v.x-d.x, 0.001))
  261. assert.is_true(utils.tolerance(v.y-d.y, 0.001))
  262. assert.is_true(utils.tolerance(v.z-d.z, 0.001))
  263. end)
  264. it("transforms a matrix to look at a point", function()
  265. local e = vec3(0, 0, 1.55)
  266. local c = vec3(4, 7, 1)
  267. local u = vec3(0, 0, 1)
  268. local a = mat4().look_at(e, c, u)
  269. assert.is_true(utils.tolerance( 0.868-a[1], 0.001))
  270. assert.is_true(utils.tolerance( 0.034-a[2], 0.001))
  271. assert.is_true(utils.tolerance(-0.495-a[3], 0.001))
  272. assert.is_true(utils.tolerance( 0 -a[4], 0.001))
  273. assert.is_true(utils.tolerance(-0.496-a[5], 0.001))
  274. assert.is_true(utils.tolerance( 0.059-a[6], 0.001))
  275. assert.is_true(utils.tolerance(-0.866-a[7], 0.001))
  276. assert.is_true(utils.tolerance( 0 -a[8], 0.001))
  277. assert.is_true(utils.tolerance( 0 -a[9], 0.001))
  278. assert.is_true(utils.tolerance( 0.998-a[10], 0.001))
  279. assert.is_true(utils.tolerance( 0.068-a[11], 0.001))
  280. assert.is_true(utils.tolerance( 0 -a[12], 0.001))
  281. assert.is_true(utils.tolerance( 0 -a[13], 0.001))
  282. assert.is_true(utils.tolerance(-1.546-a[14], 0.001))
  283. assert.is_true(utils.tolerance(-0.106-a[15], 0.001))
  284. assert.is_true(utils.tolerance( 1 -a[16], 0.001))
  285. end)
  286. it("converts a matrix to vec4s", function()
  287. local a = mat4()
  288. local v = a:to_vec4s()
  289. assert.is_true(type(v) == "table")
  290. assert.is_true(type(v[1]) == "table")
  291. assert.is_true(type(v[2]) == "table")
  292. assert.is_true(type(v[3]) == "table")
  293. assert.is_true(type(v[4]) == "table")
  294. assert.is.equal(1, v[1][1])
  295. assert.is.equal(0, v[1][2])
  296. assert.is.equal(0, v[1][3])
  297. assert.is.equal(0, v[1][4])
  298. assert.is.equal(0, v[2][1])
  299. assert.is.equal(1, v[2][2])
  300. assert.is.equal(0, v[2][3])
  301. assert.is.equal(0, v[2][4])
  302. assert.is.equal(0, v[3][1])
  303. assert.is.equal(0, v[3][2])
  304. assert.is.equal(1, v[3][3])
  305. assert.is.equal(0, v[3][4])
  306. assert.is.equal(0, v[4][1])
  307. assert.is.equal(0, v[4][2])
  308. assert.is.equal(0, v[4][3])
  309. assert.is.equal(1, v[4][4])
  310. end)
  311. it("converts a matrix to a quaternion", function()
  312. local q = mat4({
  313. 0, 0, 1, 0,
  314. 1, 0, 0, 0,
  315. 0, 1, 0, 0,
  316. 0, 0, 0, 0
  317. }):to_quat()
  318. assert.is.equal(-0.5, q.x)
  319. assert.is.equal(-0.5, q.y)
  320. assert.is.equal(-0.5, q.z)
  321. assert.is.equal( 0.5, q.w)
  322. end)
  323. it("converts a matrix to a frustum", function()
  324. local a = mat4()
  325. local b = mat4.from_perspective(45, 1, 0.1, 1000)
  326. local f = (b * a):to_frustum()
  327. assert.is_true(utils.tolerance( 0.9239-f.left.a, 0.001))
  328. assert.is_true(utils.tolerance( 0 -f.left.b, 0.001))
  329. assert.is_true(utils.tolerance(-0.3827-f.left.c, 0.001))
  330. assert.is_true(utils.tolerance( 0 -f.left.d, 0.001))
  331. assert.is_true(utils.tolerance(-0.9239-f.right.a, 0.001))
  332. assert.is_true(utils.tolerance( 0 -f.right.b, 0.001))
  333. assert.is_true(utils.tolerance(-0.3827-f.right.c, 0.001))
  334. assert.is_true(utils.tolerance( 0 -f.right.d, 0.001))
  335. assert.is_true(utils.tolerance( 0 -f.bottom.a, 0.001))
  336. assert.is_true(utils.tolerance( 0.9239-f.bottom.b, 0.001))
  337. assert.is_true(utils.tolerance(-0.3827-f.bottom.c, 0.001))
  338. assert.is_true(utils.tolerance( 0 -f.bottom.d, 0.001))
  339. assert.is_true(utils.tolerance( 0 -f.top.a, 0.001))
  340. assert.is_true(utils.tolerance(-0.9239-f.top.b, 0.001))
  341. assert.is_true(utils.tolerance(-0.3827-f.top.c, 0.001))
  342. assert.is_true(utils.tolerance( 0 -f.top.d, 0.001))
  343. assert.is_true(utils.tolerance( 0 -f.near.a, 0.001))
  344. assert.is_true(utils.tolerance( 0 -f.near.b, 0.001))
  345. assert.is_true(utils.tolerance(-1 -f.near.c, 0.001))
  346. assert.is_true(utils.tolerance(-0.1-f.near.d, 0.001))
  347. assert.is_true(utils.tolerance( 0 -f.far.a, 0.001))
  348. assert.is_true(utils.tolerance( 0 -f.far.b, 0.001))
  349. assert.is_true(utils.tolerance( 1 -f.far.c, 0.001))
  350. assert.is_true(utils.tolerance( 1000-f.far.d, 0.001))
  351. end)
  352. it("checks to see if data is a valid matrix (not a table)", function()
  353. assert.is_not_true(mat4.is_mat4(0))
  354. end)
  355. it("checks to see if data is a valid matrix (invalid data)", function()
  356. assert.is_not_true(mat4.is_mat4({}))
  357. end)
  358. it("gets a string representation of a matrix", function()
  359. local a = mat4():to_string()
  360. local z = "+0.000"
  361. local o = "+1.000"
  362. local s = string.format(
  363. "[ %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ]",
  364. o, z, z, z, z, o, z, z, z, z, o, z, z, z ,z, o
  365. )
  366. assert.is.equal(s, a)
  367. end)
  368. end)
  369. --[[
  370. from_angle_axis
  371. from_quaternion
  372. from_direction
  373. from_transform
  374. from_ortho
  375. --]]