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 ]) |
