Mercurial > games > semicongine
comparison src/zamikongine/math/matrix.nim @ 38:c3c963e7c1a6
did: tons of stuff, input, refactoring, fix some errors, some template improvment, sorry for super-commit
author | Sam <sam@basx.dev> |
---|---|
date | Wed, 18 Jan 2023 09:52:03 +0700 |
parents | 71bbe11d8de8 |
children |
comparison
equal
deleted
inserted
replaced
37:6859bcfabc62 | 38:c3c963e7c1a6 |
---|---|
3 import std/random | 3 import std/random |
4 import std/strutils | 4 import std/strutils |
5 import std/typetraits | 5 import std/typetraits |
6 | 6 |
7 import ./vector | 7 import ./vector |
8 | |
9 export math | |
8 | 10 |
9 type | 11 type |
10 # layout is row-first | 12 # layout is row-first |
11 # having an object instead of directly aliasing the array seems a bit ugly at | 13 # having an object instead of directly aliasing the array seems a bit ugly at |
12 # first, but is necessary to be able to work correctly with distinguished | 14 # first, but is necessary to be able to work correctly with distinguished |
13 # types (i.e. Mat23 and Mat32 would be an alias for the same type array[6, T] | 15 # types (i.e. Mat23 and Mat32 would be an alias for the same type array[6, T] |
14 # which prevents the type system from identifying the correct type at times) | 16 # which prevents the type system from identifying the correct type at times) |
15 # | 17 # |
16 # Though, great news is that objects have zero overhead! | 18 # Though, great news is that objects have zero overhead! |
17 Mat22*[T: SomeNumber] = object | 19 Mat22*[T: SomeNumber] = object |
18 data: array[4, T] | 20 data*: array[4, T] |
19 Mat23*[T: SomeNumber] = object | 21 Mat23*[T: SomeNumber] = object |
20 data: array[6, T] | 22 data*: array[6, T] |
21 Mat32*[T: SomeNumber] = object | 23 Mat32*[T: SomeNumber] = object |
22 data: array[6, T] | 24 data*: array[6, T] |
23 Mat33*[T: SomeNumber] = object | 25 Mat33*[T: SomeNumber] = object |
24 data: array[9, T] | 26 data*: array[9, T] |
25 Mat34*[T: SomeNumber] = object | 27 Mat34*[T: SomeNumber] = object |
26 data: array[12, T] | 28 data*: array[12, T] |
27 Mat43*[T: SomeNumber] = object | 29 Mat43*[T: SomeNumber] = object |
28 data: array[12, T] | 30 data*: array[12, T] |
29 Mat44*[T: SomeNumber] = object | 31 Mat44*[T: SomeNumber] = object |
30 data: array[16, T] | 32 data*: array[16, T] |
31 MatMM* = Mat22|Mat33|Mat44 | 33 MatMM* = Mat22|Mat33|Mat44 |
32 MatMN* = Mat23|Mat32|Mat34|Mat43 | 34 MatMN* = Mat23|Mat32|Mat34|Mat43 |
33 Mat* = MatMM|MatMN | 35 Mat* = MatMM|MatMN |
34 | 36 |
35 func unit22[T: SomeNumber](): auto {.compiletime.} = Mat22[T](data:[ | 37 func unit22[T: SomeNumber](): auto {.compiletime.} = Mat22[T](data:[ |
341 ]) | 343 ]) |
342 func rotate3d*[T](angle: T, a: Vec3[T]): Mat44[T] = | 344 func rotate3d*[T](angle: T, a: Vec3[T]): Mat44[T] = |
343 let | 345 let |
344 cosa = cos(angle) | 346 cosa = cos(angle) |
345 sina = sin(angle) | 347 sina = sin(angle) |
346 x = a.x | 348 x = a[0] |
347 y = a.y | 349 y = a[1] |
348 z = a.z | 350 z = a[2] |
349 Mat44[T](data: [ | 351 Mat44[T](data: [ |
350 x * x * (1 - cosa) + cosa, y * x * (1 - cosa) - z * sina, z * x * (1 - cosa) + y * sina, T(0), | 352 x * x * (1 - cosa) + cosa, y * x * (1 - cosa) - z * sina, z * x * (1 - cosa) + y * sina, T(0), |
351 x * y * (1 - cosa) + z * sina, y * y * (1 - cosa) + cosa, z * y * (1 - cosa) - x * sina, T(0), | 353 x * y * (1 - cosa) + z * sina, y * y * (1 - cosa) + cosa, z * y * (1 - cosa) - x * sina, T(0), |
352 x * z * (1 - cosa) - y * sina, y * z * (1 - cosa) + x * sina, z * z * (1 - cosa) + cosa, T(0), | 354 x * z * (1 - cosa) - y * sina, y * z * (1 - cosa) + x * sina, z * z * (1 - cosa) + cosa, T(0), |
353 T(0), T(0), T(0), 1, | 355 T(0), T(0), T(0), T(1), |
354 ]) | 356 ]) |
355 | 357 |
356 | 358 |
357 # call e.g. Mat32[int]().randomized() to get a random matrix | 359 # call e.g. Mat32[int]().randomized() to get a random matrix |
358 template makeRandomInit(mattype: typedesc) = | 360 template makeRandomInit(mattype: typedesc) = |
368 makeRandomInit(Mat32) | 370 makeRandomInit(Mat32) |
369 makeRandomInit(Mat33) | 371 makeRandomInit(Mat33) |
370 makeRandomInit(Mat34) | 372 makeRandomInit(Mat34) |
371 makeRandomInit(Mat43) | 373 makeRandomInit(Mat43) |
372 makeRandomInit(Mat44) | 374 makeRandomInit(Mat44) |
375 | |
376 func perspective*[T: SomeFloat](fovy, aspect, zNear, zFar: T): Mat44[T] = | |
377 let tanHalfFovy = tan(fovy / T(2)) | |
378 return Mat44[T](data:[ | |
379 T(1) / (aspect * tanHalfFovy), T(0), T(0), T(0), | |
380 T(0), T(1) / tanHalfFovy, T(0), T(0), | |
381 T(0), T(0), T(zFar / (zFar - zNear)), T(-(zFar * zNear) / (zFar - zNear)), | |
382 T(0), T(0), T(1), T(1), | |
383 ]) | |
384 | |
385 func ortho*[T: SomeFloat](left, right, bottom, top, zNear, zFar: T): Mat44[T] = | |
386 Mat44[T](data:[ | |
387 T(2) / (right - left), T(0), T(0), -(right + left) / (right - left), | |
388 T(0), T(2) / (top - bottom), T(0), -(top + bottom) / (top - bottom), | |
389 T(0), T(0), T(1) / (zFar - zNear), -zNear / (zFar - zNear), | |
390 T(0), T(0), T(1), T(1), | |
391 ]) |