commit
4ad9fb081c
1 changed files with 22 additions and 77 deletions
|
@ -3,7 +3,6 @@ import strutils
|
||||||
import random
|
import random
|
||||||
export math
|
export math
|
||||||
|
|
||||||
|
|
||||||
proc clamp*(n, min, max: float32): float32 =
|
proc clamp*(n, min, max: float32): float32 =
|
||||||
## Clamps n to min, else returns max if n is higher.
|
## Clamps n to min, else returns max if n is higher.
|
||||||
if n < min:
|
if n < min:
|
||||||
|
@ -12,6 +11,10 @@ proc clamp*(n, min, max: float32): float32 =
|
||||||
return max
|
return max
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
proc between*(value, min, max: float32): bool =
|
||||||
|
## Returns true if value is between min and max or equal to them.
|
||||||
|
(value >= min) and (value <= max)
|
||||||
|
|
||||||
proc sign*(v: float32): float32 =
|
proc sign*(v: float32): float32 =
|
||||||
## Returns the sign of a number, -1 or 1.
|
## Returns the sign of a number, -1 or 1.
|
||||||
if v >= 0:
|
if v >= 0:
|
||||||
|
@ -184,7 +187,6 @@ proc turnAngle*(a, b, speed: float32): float32 =
|
||||||
turn = -speed
|
turn = -speed
|
||||||
return a + turn
|
return a + turn
|
||||||
|
|
||||||
|
|
||||||
type Vec3* = object
|
type Vec3* = object
|
||||||
## 3D vector
|
## 3D vector
|
||||||
x*: float32
|
x*: float32
|
||||||
|
@ -367,7 +369,6 @@ proc `$`*(a: Vec3): string =
|
||||||
a.y.formatfloat(ffDecimal,8) & ", " &
|
a.y.formatfloat(ffDecimal,8) & ", " &
|
||||||
a.z.formatfloat(ffDecimal,8) & ")"
|
a.z.formatfloat(ffDecimal,8) & ")"
|
||||||
|
|
||||||
|
|
||||||
type Vec4* = object
|
type Vec4* = object
|
||||||
## 4D Vector.
|
## 4D Vector.
|
||||||
x*: float32
|
x*: float32
|
||||||
|
@ -461,7 +462,6 @@ proc `$`*(a: Vec4): string =
|
||||||
a.z.formatfloat(ffDecimal,8) & ", " &
|
a.z.formatfloat(ffDecimal,8) & ", " &
|
||||||
a.w.formatfloat(ffDecimal,8) & ")"
|
a.w.formatfloat(ffDecimal,8) & ")"
|
||||||
|
|
||||||
|
|
||||||
proc vec3*(a: Vec2, z=0.0): Vec3 =
|
proc vec3*(a: Vec2, z=0.0): Vec3 =
|
||||||
vec3(a.x, a.y, z)
|
vec3(a.x, a.y, z)
|
||||||
|
|
||||||
|
@ -471,7 +471,6 @@ proc vec4*(a: Vec3, w=0.0): Vec4 =
|
||||||
proc vec4*(a: Vec2, z=0.0, w=0.0): Vec4 =
|
proc vec4*(a: Vec2, z=0.0, w=0.0): Vec4 =
|
||||||
vec4(a.x, a.y, z, w)
|
vec4(a.x, a.y, z, w)
|
||||||
|
|
||||||
|
|
||||||
type Mat3* = array[9, float32] ## 3x3 Matrix
|
type Mat3* = array[9, float32] ## 3x3 Matrix
|
||||||
|
|
||||||
proc mat3*(a, b, c, d, e, f, g, h, i: float32): Mat3 =
|
proc mat3*(a, b, c, d, e, f, g, h, i: float32): Mat3 =
|
||||||
|
@ -485,11 +484,9 @@ proc mat3*(a, b, c, d, e, f, g, h, i: float32): Mat3 =
|
||||||
result[7] = h
|
result[7] = h
|
||||||
result[8] = i
|
result[8] = i
|
||||||
|
|
||||||
|
|
||||||
proc mat3*(a: Mat3): Mat3 =
|
proc mat3*(a: Mat3): Mat3 =
|
||||||
result = a
|
result = a
|
||||||
|
|
||||||
|
|
||||||
proc identity*(a: var Mat3) =
|
proc identity*(a: var Mat3) =
|
||||||
a[0] = 1
|
a[0] = 1
|
||||||
a[1] = 0
|
a[1] = 0
|
||||||
|
@ -501,11 +498,9 @@ proc identity*(a: var Mat3) =
|
||||||
a[7] = 0
|
a[7] = 0
|
||||||
a[8] = 1
|
a[8] = 1
|
||||||
|
|
||||||
|
|
||||||
proc mat3*(): Mat3 =
|
proc mat3*(): Mat3 =
|
||||||
result.identity()
|
result.identity()
|
||||||
|
|
||||||
|
|
||||||
proc transpose*(a: Mat3): Mat3 =
|
proc transpose*(a: Mat3): Mat3 =
|
||||||
result[0] = a[0]
|
result[0] = a[0]
|
||||||
result[1] = a[3]
|
result[1] = a[3]
|
||||||
|
@ -517,7 +512,6 @@ proc transpose*(a: Mat3): Mat3 =
|
||||||
result[7] = a[5]
|
result[7] = a[5]
|
||||||
result[8] = a[8]
|
result[8] = a[8]
|
||||||
|
|
||||||
|
|
||||||
proc `$`*(a: Mat3): string =
|
proc `$`*(a: Mat3): string =
|
||||||
return "[" &
|
return "[" &
|
||||||
a[0].formatfloat(ffDecimal,4) & ", " &
|
a[0].formatfloat(ffDecimal,4) & ", " &
|
||||||
|
@ -564,13 +558,11 @@ proc `*`*(a: Mat3, b: Mat3): Mat3 =
|
||||||
result[7] = b20 * a01 + b21 * a11 + b22 * a21
|
result[7] = b20 * a01 + b21 * a11 + b22 * a21
|
||||||
result[8] = b20 * a02 + b21 * a12 + b22 * a22
|
result[8] = b20 * a02 + b21 * a12 + b22 * a22
|
||||||
|
|
||||||
|
|
||||||
proc `*`*(m: Mat3, v: Vec3): Vec3 =
|
proc `*`*(m: Mat3, v: Vec3): Vec3 =
|
||||||
result.x = m[0]*v.x + m[1]*v.y + m[2]*v.z
|
result.x = m[0]*v.x + m[1]*v.y + m[2]*v.z
|
||||||
result.y = m[3]*v.x + m[4]*v.y + m[5]*v.z
|
result.y = m[3]*v.x + m[4]*v.y + m[5]*v.z
|
||||||
result.z = m[6]*v.x + m[7]*v.y + m[8]*v.z
|
result.z = m[6]*v.x + m[7]*v.y + m[8]*v.z
|
||||||
|
|
||||||
|
|
||||||
proc scale*(a: Mat3, v: Vec2): Mat3 =
|
proc scale*(a: Mat3, v: Vec2): Mat3 =
|
||||||
result[0] = v.x * a[0]
|
result[0] = v.x * a[0]
|
||||||
result[1] = v.x * a[1]
|
result[1] = v.x * a[1]
|
||||||
|
@ -582,7 +574,6 @@ proc scale*(a: Mat3, v: Vec2): Mat3 =
|
||||||
result[7] = a[7]
|
result[7] = a[7]
|
||||||
result[8] = a[8]
|
result[8] = a[8]
|
||||||
|
|
||||||
|
|
||||||
proc scale*(a: Mat3, v: Vec3): Mat3 =
|
proc scale*(a: Mat3, v: Vec3): Mat3 =
|
||||||
result[0] = v.x * a[0]
|
result[0] = v.x * a[0]
|
||||||
result[1] = v.x * a[1]
|
result[1] = v.x * a[1]
|
||||||
|
@ -594,7 +585,6 @@ proc scale*(a: Mat3, v: Vec3): Mat3 =
|
||||||
result[7] = v.z * a[7]
|
result[7] = v.z * a[7]
|
||||||
result[8] = v.z * a[8]
|
result[8] = v.z * a[8]
|
||||||
|
|
||||||
|
|
||||||
proc rotationMat3*(angle: float32): Mat3 =
|
proc rotationMat3*(angle: float32): Mat3 =
|
||||||
# Create a matrix from an angle.
|
# Create a matrix from an angle.
|
||||||
let
|
let
|
||||||
|
@ -612,20 +602,16 @@ proc rotationMat3*(angle: float32): Mat3 =
|
||||||
result[7] = 0
|
result[7] = 0
|
||||||
result[8] = 1
|
result[8] = 1
|
||||||
|
|
||||||
|
|
||||||
proc rotate*(a: Mat3, angle: float32): Mat3 =
|
proc rotate*(a: Mat3, angle: float32): Mat3 =
|
||||||
# Rotates a matrix by an angle.
|
# Rotates a matrix by an angle.
|
||||||
a * rotationMat3(angle)
|
a * rotationMat3(angle)
|
||||||
|
|
||||||
|
|
||||||
proc `*`*(a: Mat3, b: Vec2): Vec2 =
|
proc `*`*(a: Mat3, b: Vec2): Vec2 =
|
||||||
result.x = a[0]*b.x + a[1]*b.y + a[6]
|
result.x = a[0]*b.x + a[1]*b.y + a[6]
|
||||||
result.y = a[3]*b.x + a[4]*b.y + a[7]
|
result.y = a[3]*b.x + a[4]*b.y + a[7]
|
||||||
|
|
||||||
|
|
||||||
type Mat4* = array[16, float32] ## 4x4 Matrix - OpenGL row order
|
type Mat4* = array[16, float32] ## 4x4 Matrix - OpenGL row order
|
||||||
|
|
||||||
|
|
||||||
proc mat4*(v0, v1, Vec2, Vec3, Vec4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15: float32): Mat4 =
|
proc mat4*(v0, v1, Vec2, Vec3, Vec4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15: float32): Mat4 =
|
||||||
result[0] = v0
|
result[0] = v0
|
||||||
result[1] = v1
|
result[1] = v1
|
||||||
|
@ -644,11 +630,9 @@ proc mat4*(v0, v1, Vec2, Vec3, Vec4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14
|
||||||
result[14] = v14
|
result[14] = v14
|
||||||
result[15] = v15
|
result[15] = v15
|
||||||
|
|
||||||
|
|
||||||
proc mat4*(a: Mat4): Mat4 =
|
proc mat4*(a: Mat4): Mat4 =
|
||||||
result = a
|
result = a
|
||||||
|
|
||||||
|
|
||||||
proc identity*(): Mat4 =
|
proc identity*(): Mat4 =
|
||||||
result[0] = 1
|
result[0] = 1
|
||||||
result[1] = 0
|
result[1] = 0
|
||||||
|
@ -667,11 +651,9 @@ proc identity*(): Mat4 =
|
||||||
result[14] = 0
|
result[14] = 0
|
||||||
result[15] = 1
|
result[15] = 1
|
||||||
|
|
||||||
|
|
||||||
proc mat4*(): Mat4 =
|
proc mat4*(): Mat4 =
|
||||||
return identity()
|
return identity()
|
||||||
|
|
||||||
|
|
||||||
proc transpose*(a: Mat4): Mat4 =
|
proc transpose*(a: Mat4): Mat4 =
|
||||||
result[0] = a[0]
|
result[0] = a[0]
|
||||||
result[1] = a[4]
|
result[1] = a[4]
|
||||||
|
@ -693,7 +675,6 @@ proc transpose*(a: Mat4): Mat4 =
|
||||||
result[14] = a[11]
|
result[14] = a[11]
|
||||||
result[15] = a[15]
|
result[15] = a[15]
|
||||||
|
|
||||||
|
|
||||||
proc determinant*(a: Mat4): float32 =
|
proc determinant*(a: Mat4): float32 =
|
||||||
var
|
var
|
||||||
a00 = a[0]
|
a00 = a[0]
|
||||||
|
@ -722,7 +703,6 @@ proc determinant*(a: Mat4): float32 =
|
||||||
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33
|
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
proc inverse*(a: Mat4): Mat4 =
|
proc inverse*(a: Mat4): Mat4 =
|
||||||
var
|
var
|
||||||
a00 = a[0]
|
a00 = a[0]
|
||||||
|
@ -776,7 +756,6 @@ proc inverse*(a: Mat4): Mat4 =
|
||||||
result[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet
|
result[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet
|
||||||
result[15] = ( a20*b03 - a21*b01 + a22*b00)*invDet
|
result[15] = ( a20*b03 - a21*b01 + a22*b00)*invDet
|
||||||
|
|
||||||
|
|
||||||
proc `*`*(a, b: Mat4): Mat4 =
|
proc `*`*(a, b: Mat4): Mat4 =
|
||||||
var
|
var
|
||||||
a00 = a[0]
|
a00 = a[0]
|
||||||
|
@ -831,66 +810,55 @@ proc `*`*(a, b: Mat4): Mat4 =
|
||||||
result[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32
|
result[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32
|
||||||
result[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33
|
result[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33
|
||||||
|
|
||||||
|
|
||||||
proc `*`*(a: Mat4, b: Vec3): Vec3 =
|
proc `*`*(a: Mat4, b: Vec3): Vec3 =
|
||||||
result.x = a[0]*b.x + a[4]*b.y + a[8]*b.z + a[12]
|
result.x = a[0]*b.x + a[4]*b.y + a[8]*b.z + a[12]
|
||||||
result.y = a[1]*b.x + a[5]*b.y + a[9]*b.z + a[13]
|
result.y = a[1]*b.x + a[5]*b.y + a[9]*b.z + a[13]
|
||||||
result.z = a[2]*b.x + a[6]*b.y + a[10]*b.z + a[14]
|
result.z = a[2]*b.x + a[6]*b.y + a[10]*b.z + a[14]
|
||||||
|
|
||||||
|
|
||||||
proc right*(a: Mat4): Vec3 =
|
proc right*(a: Mat4): Vec3 =
|
||||||
result.x = a[0]
|
result.x = a[0]
|
||||||
result.y = a[1]
|
result.y = a[1]
|
||||||
result.z = a[2]
|
result.z = a[2]
|
||||||
|
|
||||||
|
|
||||||
proc `right=`*(a: var Mat4, b: Vec3) =
|
proc `right=`*(a: var Mat4, b: Vec3) =
|
||||||
a[0] = b.x
|
a[0] = b.x
|
||||||
a[1] = b.y
|
a[1] = b.y
|
||||||
a[2] = b.z
|
a[2] = b.z
|
||||||
|
|
||||||
|
|
||||||
proc up*(a: Mat4): Vec3 =
|
proc up*(a: Mat4): Vec3 =
|
||||||
result.x = a[4]
|
result.x = a[4]
|
||||||
result.y = a[5]
|
result.y = a[5]
|
||||||
result.z = a[6]
|
result.z = a[6]
|
||||||
|
|
||||||
|
|
||||||
proc `up=`*(a: var Mat4, b: Vec3) =
|
proc `up=`*(a: var Mat4, b: Vec3) =
|
||||||
a[4] = b.x
|
a[4] = b.x
|
||||||
a[5] = b.y
|
a[5] = b.y
|
||||||
a[6] = b.z
|
a[6] = b.z
|
||||||
|
|
||||||
|
|
||||||
proc fov*(a: Mat4): Vec3 =
|
proc fov*(a: Mat4): Vec3 =
|
||||||
result.x = a[8]
|
result.x = a[8]
|
||||||
result.y = a[9]
|
result.y = a[9]
|
||||||
result.z = a[10]
|
result.z = a[10]
|
||||||
|
|
||||||
|
|
||||||
proc `fov=`*(a: var Mat4, b: Vec3) =
|
proc `fov=`*(a: var Mat4, b: Vec3) =
|
||||||
a[8] = b.x
|
a[8] = b.x
|
||||||
a[9] = b.y
|
a[9] = b.y
|
||||||
a[10] = b.z
|
a[10] = b.z
|
||||||
|
|
||||||
|
|
||||||
proc pos*(a: Mat4): Vec3 =
|
proc pos*(a: Mat4): Vec3 =
|
||||||
result.x = a[12]
|
result.x = a[12]
|
||||||
result.y = a[13]
|
result.y = a[13]
|
||||||
result.z = a[14]
|
result.z = a[14]
|
||||||
|
|
||||||
|
|
||||||
proc `pos=`*(a: var Mat4, b: Vec3) =
|
proc `pos=`*(a: var Mat4, b: Vec3) =
|
||||||
a[12] = b.x
|
a[12] = b.x
|
||||||
a[13] = b.y
|
a[13] = b.y
|
||||||
a[14] = b.z
|
a[14] = b.z
|
||||||
|
|
||||||
|
|
||||||
proc rotationOnly*(a: Mat4): Mat4 =
|
proc rotationOnly*(a: Mat4): Mat4 =
|
||||||
result = a
|
result = a
|
||||||
result.pos = vec3(0,0,0)
|
result.pos = vec3(0,0,0)
|
||||||
|
|
||||||
|
|
||||||
proc dist*(a, b: Mat4): float32 =
|
proc dist*(a, b: Mat4): float32 =
|
||||||
var
|
var
|
||||||
x = a[12] - b[12]
|
x = a[12] - b[12]
|
||||||
|
@ -933,7 +901,6 @@ proc translate*(a: Mat4, v: Vec3): Mat4 =
|
||||||
result[15] = a03*v.x + a13*v.y + a23*v.z + a[15]
|
result[15] = a03*v.x + a13*v.y + a23*v.z + a[15]
|
||||||
]#
|
]#
|
||||||
|
|
||||||
|
|
||||||
proc translate*(v: Vec3): Mat4 =
|
proc translate*(v: Vec3): Mat4 =
|
||||||
result[0] = 1
|
result[0] = 1
|
||||||
result[5] = 1
|
result[5] = 1
|
||||||
|
@ -943,21 +910,18 @@ proc translate*(v: Vec3): Mat4 =
|
||||||
result[13] = v.y
|
result[13] = v.y
|
||||||
result[14] = v.z
|
result[14] = v.z
|
||||||
|
|
||||||
|
|
||||||
proc scale*(v: Vec3): Mat4 =
|
proc scale*(v: Vec3): Mat4 =
|
||||||
result[0] = v.x
|
result[0] = v.x
|
||||||
result[5] = v.y
|
result[5] = v.y
|
||||||
result[10] = v.z
|
result[10] = v.z
|
||||||
result[15] = 1
|
result[15] = 1
|
||||||
|
|
||||||
|
|
||||||
proc close*(a: Mat4, b: Mat4): bool =
|
proc close*(a: Mat4, b: Mat4): bool =
|
||||||
for i in 0..15:
|
for i in 0..15:
|
||||||
if abs(a[i] - b[i]) > 0.001:
|
if abs(a[i] - b[i]) > 0.001:
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
proc hrp*(m: Mat4): Vec3 =
|
proc hrp*(m: Mat4): Vec3 =
|
||||||
var heading, pitch, roll: float32
|
var heading, pitch, roll: float32
|
||||||
if m[1] > 0.998: # singularity at north pole
|
if m[1] > 0.998: # singularity at north pole
|
||||||
|
@ -976,7 +940,6 @@ proc hrp*(m: Mat4): Vec3 =
|
||||||
result.y = pitch
|
result.y = pitch
|
||||||
result.z = roll
|
result.z = roll
|
||||||
|
|
||||||
|
|
||||||
proc frustum*(left, right, bottom, top, near, far: float32): Mat4 =
|
proc frustum*(left, right, bottom, top, near, far: float32): Mat4 =
|
||||||
var
|
var
|
||||||
rl = (right - left)
|
rl = (right - left)
|
||||||
|
@ -999,14 +962,12 @@ proc frustum*(left, right, bottom, top, near, far: float32): Mat4 =
|
||||||
result[14] = -(far*near*2) / fn
|
result[14] = -(far*near*2) / fn
|
||||||
result[15] = 0
|
result[15] = 0
|
||||||
|
|
||||||
|
|
||||||
proc perspective*(fovy, aspect, near, far: float32): Mat4 =
|
proc perspective*(fovy, aspect, near, far: float32): Mat4 =
|
||||||
var
|
var
|
||||||
top = near * tan(fovy*PI / 360.0)
|
top = near * tan(fovy*PI / 360.0)
|
||||||
right = top * aspect
|
right = top * aspect
|
||||||
return frustum(-right, right, -top, top, near, far)
|
return frustum(-right, right, -top, top, near, far)
|
||||||
|
|
||||||
|
|
||||||
proc ortho*(left, right, bottom, top, near, far: float32): Mat4 =
|
proc ortho*(left, right, bottom, top, near, far: float32): Mat4 =
|
||||||
var
|
var
|
||||||
rl = (right - left)
|
rl = (right - left)
|
||||||
|
@ -1029,7 +990,6 @@ proc ortho*(left, right, bottom, top, near, far: float32): Mat4 =
|
||||||
result[14] = -(far + near) / fn
|
result[14] = -(far + near) / fn
|
||||||
result[15] = 1
|
result[15] = 1
|
||||||
|
|
||||||
|
|
||||||
proc lookAt*(eye, center, up: Vec3): Mat4 =
|
proc lookAt*(eye, center, up: Vec3): Mat4 =
|
||||||
var
|
var
|
||||||
eyex = eye[0]
|
eyex = eye[0]
|
||||||
|
@ -1107,7 +1067,6 @@ proc lookAt*(eye, center, up: Vec3): Mat4 =
|
||||||
result[14] = -(z0*eyex + z1*eyey + z2*eyez)
|
result[14] = -(z0*eyex + z1*eyey + z2*eyez)
|
||||||
result[15] = 1
|
result[15] = 1
|
||||||
|
|
||||||
|
|
||||||
proc tofloat32*(m: Mat4): array[16, float32] =
|
proc tofloat32*(m: Mat4): array[16, float32] =
|
||||||
return [
|
return [
|
||||||
float32 m[0], float32 m[1], float32 m[2], float32 m[3],
|
float32 m[0], float32 m[1], float32 m[2], float32 m[3],
|
||||||
|
@ -1116,7 +1075,6 @@ proc tofloat32*(m: Mat4): array[16, float32] =
|
||||||
float32 m[12], float32 m[13], float32 m[14], float32 m[15]
|
float32 m[12], float32 m[13], float32 m[14], float32 m[15]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
proc `$`*(a: Mat4): string =
|
proc `$`*(a: Mat4): string =
|
||||||
return "[" &
|
return "[" &
|
||||||
a[0].formatfloat(ffDecimal, 5) & ", " &
|
a[0].formatfloat(ffDecimal, 5) & ", " &
|
||||||
|
@ -1136,28 +1094,24 @@ proc `$`*(a: Mat4): string =
|
||||||
a[14].formatfloat(ffDecimal, 5) & ", " &
|
a[14].formatfloat(ffDecimal, 5) & ", " &
|
||||||
a[15].formatfloat(ffDecimal, 5) & "]"
|
a[15].formatfloat(ffDecimal, 5) & "]"
|
||||||
|
|
||||||
|
|
||||||
type Quat* = object
|
type Quat* = object
|
||||||
x*: float32
|
x*: float32
|
||||||
y*: float32
|
y*: float32
|
||||||
z*: float32
|
z*: float32
|
||||||
w*: float32
|
w*: float32
|
||||||
|
|
||||||
|
|
||||||
proc quat*(x, y, z, w: float32): Quat =
|
proc quat*(x, y, z, w: float32): Quat =
|
||||||
result.x = x
|
result.x = x
|
||||||
result.y = y
|
result.y = y
|
||||||
result.z = z
|
result.z = z
|
||||||
result.w = w
|
result.w = w
|
||||||
|
|
||||||
|
|
||||||
proc conjugate*(q: Quat): Quat =
|
proc conjugate*(q: Quat): Quat =
|
||||||
result.w = q.w
|
result.w = q.w
|
||||||
result.x = -q.x
|
result.x = -q.x
|
||||||
result.y = -q.y
|
result.y = -q.y
|
||||||
result.z = -q.z
|
result.z = -q.z
|
||||||
|
|
||||||
|
|
||||||
proc length*(q: Quat): float32 =
|
proc length*(q: Quat): float32 =
|
||||||
return sqrt(
|
return sqrt(
|
||||||
q.w * q.w +
|
q.w * q.w +
|
||||||
|
@ -1165,7 +1119,6 @@ proc length*(q: Quat): float32 =
|
||||||
q.y * q.y +
|
q.y * q.y +
|
||||||
q.z * q.z)
|
q.z * q.z)
|
||||||
|
|
||||||
|
|
||||||
proc normalize*(q: Quat): Quat =
|
proc normalize*(q: Quat): Quat =
|
||||||
var m = q.length
|
var m = q.length
|
||||||
result.x = q.x / m
|
result.x = q.x / m
|
||||||
|
@ -1173,19 +1126,16 @@ proc normalize*(q: Quat): Quat =
|
||||||
result.z = q.z / m
|
result.z = q.z / m
|
||||||
result.w = q.w / m
|
result.w = q.w / m
|
||||||
|
|
||||||
|
|
||||||
proc xyz*(q: Quat): Vec3 =
|
proc xyz*(q: Quat): Vec3 =
|
||||||
result.x = q.x
|
result.x = q.x
|
||||||
result.y = q.y
|
result.y = q.y
|
||||||
result.z = q.z
|
result.z = q.z
|
||||||
|
|
||||||
|
|
||||||
proc `xyz=`*(q: var Quat, v: Vec3) =
|
proc `xyz=`*(q: var Quat, v: Vec3) =
|
||||||
q.x = v.x
|
q.x = v.x
|
||||||
q.y = v.y
|
q.y = v.y
|
||||||
q.z = v.z
|
q.z = v.z
|
||||||
|
|
||||||
|
|
||||||
proc `*`*(a, b: Quat): Quat =
|
proc `*`*(a, b: Quat): Quat =
|
||||||
## Multiply the quaternion by a quaternion.
|
## Multiply the quaternion by a quaternion.
|
||||||
#[
|
#[
|
||||||
|
@ -1211,7 +1161,6 @@ proc `*`*(q: Quat, v: float32): Quat =
|
||||||
result.z = q.z * v
|
result.z = q.z * v
|
||||||
result.w = q.w * v
|
result.w = q.w * v
|
||||||
|
|
||||||
|
|
||||||
proc `*`*(q: Quat, v: Vec3): Vec3 =
|
proc `*`*(q: Quat, v: Vec3): Vec3 =
|
||||||
## Multiply the quaternion by a vector.
|
## Multiply the quaternion by a vector.
|
||||||
var
|
var
|
||||||
|
@ -1233,7 +1182,6 @@ proc `*`*(q: Quat, v: Vec3): Vec3 =
|
||||||
result.y = iy * qw + iw * -qy + iz * -qx - ix * -qz
|
result.y = iy * qw + iw * -qy + iz * -qx - ix * -qz
|
||||||
result.z = iz * qw + iw * -qz + ix * -qy - iy * -qx
|
result.z = iz * qw + iw * -qz + ix * -qy - iy * -qx
|
||||||
|
|
||||||
|
|
||||||
proc mat3*(q: Quat): Mat3 =
|
proc mat3*(q: Quat): Mat3 =
|
||||||
var xx = q.x * q.x
|
var xx = q.x * q.x
|
||||||
var xy = q.x * q.y
|
var xy = q.x * q.y
|
||||||
|
@ -1259,8 +1207,6 @@ proc mat3*(q: Quat): Mat3 =
|
||||||
result[7] = 2 * ( yz + xw )
|
result[7] = 2 * ( yz + xw )
|
||||||
result[8] = 1 - 2 * ( xx + yy )
|
result[8] = 1 - 2 * ( xx + yy )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc mat4*(q: Quat): Mat4 =
|
proc mat4*(q: Quat): Mat4 =
|
||||||
var xx = q.x * q.x
|
var xx = q.x * q.x
|
||||||
var xy = q.x * q.y
|
var xy = q.x * q.y
|
||||||
|
@ -1294,11 +1240,9 @@ proc mat4*(q: Quat): Mat4 =
|
||||||
result[14] = 0
|
result[14] = 0
|
||||||
result[15] = 1.0
|
result[15] = 1.0
|
||||||
|
|
||||||
|
|
||||||
proc reciprocalSqrt*(x: float32): float32 =
|
proc reciprocalSqrt*(x: float32): float32 =
|
||||||
return 1.0/sqrt(x)
|
return 1.0/sqrt(x)
|
||||||
|
|
||||||
|
|
||||||
proc quat*(m: Mat4): Quat =
|
proc quat*(m: Mat4): Quat =
|
||||||
var
|
var
|
||||||
m00 = m[0]
|
m00 = m[0]
|
||||||
|
@ -1336,7 +1280,6 @@ proc quat*(m: Mat4): Quat =
|
||||||
assert abs(q.length - 1.0) < 0.001
|
assert abs(q.length - 1.0) < 0.001
|
||||||
return q
|
return q
|
||||||
|
|
||||||
|
|
||||||
proc fromAxisAngle*(axis: Vec3, angle: float32): Quat =
|
proc fromAxisAngle*(axis: Vec3, angle: float32): Quat =
|
||||||
var a = axis.normalize()
|
var a = axis.normalize()
|
||||||
var s = sin(angle / 2)
|
var s = sin(angle / 2)
|
||||||
|
@ -1345,7 +1288,6 @@ proc fromAxisAngle*(axis: Vec3, angle: float32): Quat =
|
||||||
result.z = a.z * s
|
result.z = a.z * s
|
||||||
result.w = cos(angle / 2)
|
result.w = cos(angle / 2)
|
||||||
|
|
||||||
|
|
||||||
proc toAxisAngle*(q: Quat, axis: var Vec3, angle: var float32) =
|
proc toAxisAngle*(q: Quat, axis: var Vec3, angle: var float32) =
|
||||||
var cosAngle = q.w
|
var cosAngle = q.w
|
||||||
angle = arccos(cosAngle) * 2.0
|
angle = arccos(cosAngle) * 2.0
|
||||||
|
@ -1358,7 +1300,6 @@ proc toAxisAngle*(q: Quat, axis: var Vec3, angle: var float32) =
|
||||||
axis.y = q.y / sinAngle
|
axis.y = q.y / sinAngle
|
||||||
axis.z = q.z / sinAngle
|
axis.z = q.z / sinAngle
|
||||||
|
|
||||||
|
|
||||||
proc quat*(heading, pitch, roll: float32): Quat =
|
proc quat*(heading, pitch, roll: float32): Quat =
|
||||||
var t0 = cos(heading * 0.5)
|
var t0 = cos(heading * 0.5)
|
||||||
var t1 = sin(heading * 0.5)
|
var t1 = sin(heading * 0.5)
|
||||||
|
@ -1371,7 +1312,6 @@ proc quat*(heading, pitch, roll: float32): Quat =
|
||||||
result.y = t0 * t2 * t5 + t1 * t3 * t4
|
result.y = t0 * t2 * t5 + t1 * t3 * t4
|
||||||
result.z = t1 * t2 * t4 - t0 * t3 * t5
|
result.z = t1 * t2 * t4 - t0 * t3 * t5
|
||||||
|
|
||||||
|
|
||||||
proc hrp*(q: Quat): Vec3 =
|
proc hrp*(q: Quat): Vec3 =
|
||||||
var ysqr = q.y * q.y
|
var ysqr = q.y * q.y
|
||||||
# roll
|
# roll
|
||||||
|
@ -1390,7 +1330,6 @@ proc hrp*(q: Quat): Vec3 =
|
||||||
var t4 = +1.0 - 2.0 * (ysqr + q.z * q.z)
|
var t4 = +1.0 - 2.0 * (ysqr + q.z * q.z)
|
||||||
result.x = arctan2(t3, t4)
|
result.x = arctan2(t3, t4)
|
||||||
|
|
||||||
|
|
||||||
proc `$`*(a: Quat): string =
|
proc `$`*(a: Quat): string =
|
||||||
return "q(" &
|
return "q(" &
|
||||||
a.x.formatfloat(ffDecimal,8) & ", " &
|
a.x.formatfloat(ffDecimal,8) & ", " &
|
||||||
|
@ -1398,35 +1337,27 @@ proc `$`*(a: Quat): string =
|
||||||
a.z.formatfloat(ffDecimal,8) & ", " &
|
a.z.formatfloat(ffDecimal,8) & ", " &
|
||||||
a.w.formatfloat(ffDecimal,8) & ")"
|
a.w.formatfloat(ffDecimal,8) & ")"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
proc rotate*(angle: float32, axis: Vec3): Mat4 =
|
proc rotate*(angle: float32, axis: Vec3): Mat4 =
|
||||||
fromAxisAngle(axis, angle).mat4()
|
fromAxisAngle(axis, angle).mat4()
|
||||||
|
|
||||||
|
|
||||||
proc rotateX*(angle: float32): Mat4 =
|
proc rotateX*(angle: float32): Mat4 =
|
||||||
return rotate(angle, vec3(1, 0, 0))
|
return rotate(angle, vec3(1, 0, 0))
|
||||||
|
|
||||||
|
|
||||||
proc rotateY*(angle: float32): Mat4 =
|
proc rotateY*(angle: float32): Mat4 =
|
||||||
return rotate(angle, vec3(0, 1, 0))
|
return rotate(angle, vec3(0, 1, 0))
|
||||||
|
|
||||||
|
|
||||||
proc rotateZ*(angle: float32): Mat4 =
|
proc rotateZ*(angle: float32): Mat4 =
|
||||||
return rotate(angle, vec3(0, 0, 1))
|
return rotate(angle, vec3(0, 0, 1))
|
||||||
|
|
||||||
|
|
||||||
proc scaleMat*(scale: Vec3): Mat4 =
|
proc scaleMat*(scale: Vec3): Mat4 =
|
||||||
result[0] = scale.x
|
result[0] = scale.x
|
||||||
result[5] = scale.y
|
result[5] = scale.y
|
||||||
result[10] = scale.z
|
result[10] = scale.z
|
||||||
result[15] = 1.0
|
result[15] = 1.0
|
||||||
|
|
||||||
|
|
||||||
proc scaleMat*(scale: float32): Mat4 =
|
proc scaleMat*(scale: float32): Mat4 =
|
||||||
return scaleMat(vec3(scale, scale, scale))
|
return scaleMat(vec3(scale, scale, scale))
|
||||||
|
|
||||||
|
|
||||||
type Rect* = object
|
type Rect* = object
|
||||||
x*: float32
|
x*: float32
|
||||||
y*: float32
|
y*: float32
|
||||||
|
@ -1471,10 +1402,12 @@ proc `/`*(r: Rect, v: float): Rect =
|
||||||
## / all elements of a Rect.
|
## / all elements of a Rect.
|
||||||
rect(r.x / v, r.y / v, r.w / v, r.h / v)
|
rect(r.x / v, r.y / v, r.w / v, r.h / v)
|
||||||
|
|
||||||
proc intersects*(rect: Rect, pos: Vec2): bool =
|
proc `+`*(a, b: Rect): Rect =
|
||||||
## Checks if pos is inside rect.
|
## Add two boxes together.
|
||||||
(rect.x <= pos.x and pos.x <= rect.x + rect.w) and (
|
result.x = a.x + b.x
|
||||||
rect.y <= pos.y and pos.y <= rect.y + rect.h)
|
result.y = a.y + b.y
|
||||||
|
result.w = a.w
|
||||||
|
result.h = a.h
|
||||||
|
|
||||||
proc `$`*(a: Rect): string =
|
proc `$`*(a: Rect): string =
|
||||||
return "(" &
|
return "(" &
|
||||||
|
@ -1482,3 +1415,15 @@ proc `$`*(a: Rect): string =
|
||||||
$a.y & ": " &
|
$a.y & ": " &
|
||||||
$a.w & " x " &
|
$a.w & " x " &
|
||||||
$a.h & ")"
|
$a.h & ")"
|
||||||
|
|
||||||
|
proc inside*(pos: Vec2, rect: Rect): bool =
|
||||||
|
## Checks if pos is inside rect.
|
||||||
|
(rect.x <= pos.x and pos.x <= rect.x + rect.w) and (
|
||||||
|
rect.y <= pos.y and pos.y <= rect.y + rect.h)
|
||||||
|
|
||||||
|
proc overlap*(a, b: Rect): bool =
|
||||||
|
## Returns true if box a overlaps box b.
|
||||||
|
let
|
||||||
|
xOverlap = between(a.x, b.x, b.x + b.w) or between(b.x, a.x, a.x + a.w)
|
||||||
|
yOverlap = between(a.y, b.y, b.y + b.h) or between(b.y, a.y, a.y + a.h)
|
||||||
|
return xOverlap and yOverlap
|
||||||
|
|
Loading…
Reference in a new issue