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