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