mostly inlines + rand

This commit is contained in:
Ryan Oldenburg 2020-11-29 19:21:58 -06:00
parent 80a2b4dade
commit 1a5fbe202a

View file

@ -2,19 +2,19 @@ import hashes, math, random, strformat, strutils
export math export math
proc between*(value, min, max: float32): bool = proc between*(value, min, max: float32): bool {.inline.} =
## Returns true if value is between min and max or equal to them. ## Returns true if value is between min and max or equal to them.
(value >= min) and (value <= max) (value >= min) and (value <= max)
proc sign*(v: float32): float32 = proc sign*(v: float32): float32 {.inline.} =
## Returns the sign of a number, -1 or 1. ## Returns the sign of a number, -1 or 1.
if v >= 0: 1.0 else: -1.0 if v >= 0: 1.0 else: -1.0
proc quantize*(v: float32, n: float32): float32 = proc quantize*(v: float32, n: float32): float32 {.inline.} =
## Makes v be multipe of n. Rounding to integer quantize by 1.0. ## Makes v be multipe of n. Rounding to integer quantize by 1.0.
sign(v) * floor(abs(v) / n) * n sign(v) * floor(abs(v) / n) * n
proc lerp*(a: float32, b: float32, v: float32): float32 = proc lerp*(a: float32, b: float32, v: float32): float32 {.inline.} =
## Interpolates value between a and b. ## Interpolates value between a and b.
## * 0 -> a ## * 0 -> a
## * 1 -> b ## * 1 -> b
@ -189,17 +189,17 @@ type Vec3* = object
y*: float32 y*: float32
z*: float32 z*: float32
proc vec3*(x, y, z: float32): Vec3 = proc vec3*(x, y, z: float32): Vec3 {.inline.} =
result.x = x result.x = x
result.y = y result.y = y
result.z = z result.z = z
proc vec3*(v: float32): Vec3 = proc vec3*(v: float32): Vec3 {.inline.} =
result.x = v result.x = v
result.y = v result.y = v
result.z = v result.z = v
proc vec3*(a: Vec3): Vec3 = proc vec3*(a: Vec3): Vec3 {.inline.} =
result.x = a.x result.x = a.x
result.y = a.y result.y = a.y
result.z = a.z result.z = a.z
@ -208,103 +208,103 @@ const X_DIR* = vec3(1.0, 0.0, 0.0)
const Y_DIR* = vec3(0.0, 1.0, 0.0) const Y_DIR* = vec3(0.0, 1.0, 0.0)
const Z_DIR* = vec3(0.0, 0.0, 1.0) const Z_DIR* = vec3(0.0, 0.0, 1.0)
proc `+`*(a: Vec3, b: Vec3): Vec3 = proc `+`*(a: Vec3, b: Vec3): Vec3 {.inline.} =
result.x = a.x + b.x result.x = a.x + b.x
result.y = a.y + b.y result.y = a.y + b.y
result.z = a.z + b.z result.z = a.z + b.z
proc `-`*(a: Vec3, b: Vec3): Vec3 = proc `-`*(a: Vec3, b: Vec3): Vec3 {.inline.} =
result.x = a.x - b.x result.x = a.x - b.x
result.y = a.y - b.y result.y = a.y - b.y
result.z = a.z - b.z result.z = a.z - b.z
proc `-`*(a: Vec3): Vec3 = proc `-`*(a: Vec3): Vec3 {.inline.} =
result.x = -a.x result.x = -a.x
result.y = -a.y result.y = -a.y
result.z = -a.z result.z = -a.z
proc `*`*(a: Vec3, b: float32): Vec3 = proc `*`*(a: Vec3, b: float32): Vec3 {.inline.} =
result.x = a.x * b result.x = a.x * b
result.y = a.y * b result.y = a.y * b
result.z = a.z * b result.z = a.z * b
proc `*`*(a: float32, b: Vec3): Vec3 = proc `*`*(a: float32, b: Vec3): Vec3 {.inline.} =
b * a b * a
proc `/`*(a: Vec3, b: float32): Vec3 = proc `/`*(a: Vec3, b: float32): Vec3 {.inline.} =
result.x = a.x / b result.x = a.x / b
result.y = a.y / b result.y = a.y / b
result.z = a.z / b result.z = a.z / b
proc `/`*(a: float32, b: Vec3): Vec3 = proc `/`*(a: float32, b: Vec3): Vec3 {.inline.} =
result.x = a / b.x result.x = a / b.x
result.y = a / b.y result.y = a / b.y
result.z = a / b.z result.z = a / b.z
proc `+=`*(a: var Vec3, b: Vec3) = proc `+=`*(a: var Vec3, b: Vec3) {.inline.} =
a.x += b.x a.x += b.x
a.y += b.y a.y += b.y
a.z += b.z a.z += b.z
proc `-=`*(a: var Vec3, b: Vec3) = proc `-=`*(a: var Vec3, b: Vec3) {.inline.} =
a.x -= b.x a.x -= b.x
a.y -= b.y a.y -= b.y
a.z -= b.z a.z -= b.z
proc `*=`*(a: var Vec3, b: float32) = proc `*=`*(a: var Vec3, b: float32) {.inline.} =
a.x *= b a.x *= b
a.y *= b a.y *= b
a.z *= b a.z *= b
proc `/=`*(a: var Vec3, b: float32) = proc `/=`*(a: var Vec3, b: float32) {.inline.} =
a.x /= b a.x /= b
a.y /= b a.y /= b
a.z /= b a.z /= b
proc zero*(a: var Vec3) = proc zero*(a: var Vec3) {.inline.} =
a.x = 0 a.x = 0
a.y = 0 a.y = 0
a.z = 0 a.z = 0
proc `-`*(a: var Vec3): Vec3 = proc `-`*(a: var Vec3): Vec3 {.inline.} =
result.x = -a.x result.x = -a.x
result.y = -a.y result.y = -a.y
result.z = -a.z result.z = -a.z
proc hash*(a: Vec3): Hash = proc hash*(a: Vec3): Hash {.inline.} =
hash((a.x, a.y, a.z)) hash((a.x, a.y, a.z))
proc lengthSq*(a: Vec3): float32 = proc lengthSq*(a: Vec3): float32 {.inline.} =
a.x * a.x + a.y * a.y + a.z * a.z a.x * a.x + a.y * a.y + a.z * a.z
proc length*(a: Vec3): float32 = proc length*(a: Vec3): float32 {.inline.} =
sqrt(a.lengthSq) sqrt(a.lengthSq)
proc `length=`*(a: var Vec3, b: float32) = proc `length=`*(a: var Vec3, b: float32) {.inline.} =
a *= b / a.length a *= b / a.length
proc floor*(a: Vec3): Vec3 = proc floor*(a: Vec3): Vec3 {.inline.} =
vec3(floor(a.x), floor(a.y), floor(a.z)) vec3(floor(a.x), floor(a.y), floor(a.z))
proc round*(a: Vec3): Vec3 = proc round*(a: Vec3): Vec3 {.inline.} =
vec3(round(a.x), round(a.y), round(a.z)) vec3(round(a.x), round(a.y), round(a.z))
proc ceil*(a: Vec3): Vec3 = proc ceil*(a: Vec3): Vec3 {.inline.} =
vec3(ceil(a.x), ceil(a.y), ceil(a.z)) vec3(ceil(a.x), ceil(a.y), ceil(a.z))
proc normalize*(a: Vec3): Vec3 = proc normalize*(a: Vec3): Vec3 {.inline.} =
a / sqrt(a.x*a.x + a.y*a.y + a.z*a.z) a / sqrt(a.x * a.x + a.y * a.y + a.z * a.z)
proc cross*(a: Vec3, b: Vec3): Vec3 = proc cross*(a: Vec3, b: Vec3): Vec3 {.inline.} =
result.x = a.y*b.z - a.z*b.y result.x = a.y * b.z - a.z * b.y
result.y = a.z*b.x - a.x*b.z result.y = a.z * b.x - a.x * b.z
result.z = a.x*b.y - a.y*b.x result.z = a.x * b.y - a.y * b.x
proc computeNormal*(a, b, c: Vec3): Vec3 = proc computeNormal*(a, b, c: Vec3): Vec3 =
cross(c - b, b - a).normalize() cross(c - b, b - a).normalize()
proc dot*(a: Vec3, b: Vec3): float32 = proc dot*(a: Vec3, b: Vec3): float32 {.inline.} =
a.x*b.x + a.y*b.y + a.z*b.z a.x * b.x + a.y * b.y + a.z * b.z
proc dir*(at: Vec3, to: Vec3): Vec3 = proc dir*(at: Vec3, to: Vec3): Vec3 =
(at - to).normalize() (at - to).normalize()
@ -329,42 +329,44 @@ proc angleBetween*(a, b: Vec3): float32 =
arccos(dot) arccos(dot)
proc `[]`*(a: Vec3, i: int): float32 = proc `[]`*(a: Vec3, i: int): float32 =
assert(i == 0 or i == 1 or i == 2) if i > 2:
raise newException(IndexDefect, "Vec3 index out of bounds")
if i == 0: if i == 0:
return a.x a.x
elif i == 1: elif i == 1:
return a.y a.y
elif i == 2: else:
return a.z a.z
proc `[]=`*(a: var Vec3, i: int, b: float32) = proc `[]=`*(a: var Vec3, i: int, b: float32) =
assert(i == 0 or i == 1 or i == 2) if i > 2:
raise newException(IndexDefect, "Vec3 index out of bounds")
if i == 0: if i == 0:
a.x = b a.x = b
elif i == 1: elif i == 1:
a.y = b a.y = b
elif i == 2: else:
a.z = b a.z = b
proc xy*(a: Vec3): Vec2 = proc xy*(a: Vec3): Vec2 {.inline.} =
vec2(a.x, a.y) vec2(a.x, a.y)
proc xz*(a: Vec3): Vec2 = proc xz*(a: Vec3): Vec2 {.inline.} =
vec2(a.x, a.z) vec2(a.x, a.z)
proc yx*(a: Vec3): Vec2 = proc yx*(a: Vec3): Vec2 {.inline.} =
vec2(a.y, a.x) vec2(a.y, a.x)
proc yz*(a: Vec3): Vec2 = proc yz*(a: Vec3): Vec2 {.inline.} =
vec2(a.y, a.z) vec2(a.y, a.z)
proc zx*(a: Vec3): Vec2 = proc zx*(a: Vec3): Vec2 {.inline.} =
vec2(a.y, a.x) vec2(a.y, a.x)
proc zy*(a: Vec3): Vec2 = proc zy*(a: Vec3): Vec2 {.inline.} =
vec2(a.z, a.y) vec2(a.z, a.y)
proc almostEquals*(a, b: Vec3, precision = 1e-6): bool = proc almostEquals*(a, b: Vec3, precision = 1e-6): bool {.inline.} =
let c = a - b let c = a - b
abs(c.x) < precision and abs(c.y) < precision and abs(c.z) < precision abs(c.x) < precision and abs(c.y) < precision and abs(c.z) < precision
@ -392,129 +394,130 @@ type Vec4* = object
z*: float32 z*: float32
w*: float32 w*: float32
proc vec4*(x, y, z, w: float32): Vec4 = proc vec4*(x, y, z, w: float32): Vec4 {.inline.} =
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 vec4*(v: float32): Vec4 = proc vec4*(v: float32): Vec4 {.inline.} =
result.x = v result.x = v
result.y = v result.y = v
result.z = v result.z = v
result.w = v result.w = v
proc `+`*(a: Vec4, b: Vec4): Vec4 = proc `+`*(a: Vec4, b: Vec4): Vec4 {.inline.} =
result.x = a.x + b.x result.x = a.x + b.x
result.y = a.y + b.y result.y = a.y + b.y
result.z = a.z + b.z result.z = a.z + b.z
result.w = a.w + b.w result.w = a.w + b.w
proc `-`*(a: Vec4, b: Vec4): Vec4 = proc `-`*(a: Vec4, b: Vec4): Vec4 {.inline.} =
result.x = a.x - b.x result.x = a.x - b.x
result.y = a.y - b.y result.y = a.y - b.y
result.z = a.z - b.z result.z = a.z - b.z
result.w = a.w - b.w result.w = a.w - b.w
proc `-`*(a: Vec4): Vec4 = proc `-`*(a: Vec4): Vec4 {.inline.} =
result.x = -a.x result.x = -a.x
result.y = -a.y result.y = -a.y
result.z = -a.z result.z = -a.z
result.w = -a.w result.w = -a.w
proc `*`*(a: Vec4, b: float32): Vec4 = proc `*`*(a: Vec4, b: float32): Vec4 {.inline.} =
result.x = a.x * b result.x = a.x * b
result.y = a.y * b result.y = a.y * b
result.z = a.z * b result.z = a.z * b
result.w = a.w * b result.w = a.w * b
proc `*`*(a: float32, b: Vec4): Vec4 = proc `*`*(a: float32, b: Vec4): Vec4 {.inline.} =
b * a b * a
proc `/`*(a: Vec4, b: float32): Vec4 = proc `/`*(a: Vec4, b: float32): Vec4 {.inline.} =
result.x = a.x / b result.x = a.x / b
result.y = a.y / b result.y = a.y / b
result.z = a.z / b result.z = a.z / b
result.w = a.w / b result.w = a.w / b
proc `/`*(a: float32, b: Vec4): Vec4 = proc `/`*(a: float32, b: Vec4): Vec4 {.inline.}=
result.x = a / b.x result.x = a / b.x
result.y = a / b.y result.y = a / b.y
result.z = a / b.z result.z = a / b.z
result.w = a / b.w result.w = a / b.w
proc `+=`*(a: var Vec4, b: Vec4) = proc `+=`*(a: var Vec4, b: Vec4) {.inline.} =
a.x += b.x a.x += b.x
a.y += b.y a.y += b.y
a.z += b.z a.z += b.z
a.w += b.w a.w += b.w
proc `-=`*(a: var Vec4, b: Vec4) = proc `-=`*(a: var Vec4, b: Vec4) {.inline.} =
a.x -= b.x a.x -= b.x
a.y -= b.y a.y -= b.y
a.z -= b.z a.z -= b.z
a.w -= b.w a.w -= b.w
proc `*=`*(a: var Vec4, b: float32) = proc `*=`*(a: var Vec4, b: float32) {.inline.} =
a.x *= b a.x *= b
a.y *= b a.y *= b
a.z *= b a.z *= b
a.w *= b a.w *= b
proc `/=`*(a: var Vec4, b: float32) = proc `/=`*(a: var Vec4, b: float32) {.inline.} =
a.x /= b a.x /= b
a.y /= b a.y /= b
a.z /= b a.z /= b
a.w /= b a.w /= b
proc zero*(a: var Vec4) = proc zero*(a: var Vec4) {.inline.} =
a.x = 0 a.x = 0
a.y = 0 a.y = 0
a.z = 0 a.z = 0
a.w = 0 a.w = 0
proc hash*(a: Vec4): Hash = proc hash*(a: Vec4): Hash {.inline.} =
hash((a.x, a.y, a.z, a.w)) hash((a.x, a.y, a.z, a.w))
proc `[]`*(a: Vec4, i: int): float32 = proc `[]`*(a: Vec4, i: int): float32 =
assert(i == 0 or i == 1 or i == 2) if i > 3:
raise newException(IndexDefect, "Vec4 index out of bounds")
if i == 0: if i == 0:
return a.x a.x
elif i == 1: elif i == 1:
return a.y a.y
elif i == 2: elif i == 2:
return a.z a.z
elif i == 3: else:
return a.w a.w
proc `[]=`*(a: var Vec4, i: int, b: float32) = proc `[]=`*(a: var Vec4, i: int, b: float32) =
assert(i == 0 or i == 1 or i == 2) if i > 3:
raise newException(IndexDefect, "Vec4 index out of bounds")
if i == 0: if i == 0:
a.x = b a.x = b
elif i == 1: elif i == 1:
a.y = b a.y = b
elif i == 2: elif i == 2:
a.z = b a.z = b
elif i == 3: else:
a.w = b a.w = b
proc lerp*(a: Vec4, b: Vec4, v: float32): Vec4 = proc lerp*(a: Vec4, b: Vec4, v: float32): Vec4 =
a * (1.0 - v) + b * v a * (1.0 - v) + b * v
proc xyz*(a: Vec4): Vec3 = proc xyz*(a: Vec4): Vec3 {.inline.} =
vec3(a.x, a.y, a.z) vec3(a.x, a.y, a.z)
proc `$`*(a: Vec4): string = proc `$`*(a: Vec4): string =
&"({a.x:.8f}, {a.y:.8f}, {a.z:.8f}, {a.w:.8f})" &"({a.x:.8f}, {a.y:.8f}, {a.z:.8f}, {a.w:.8f})"
proc vec3*(a: Vec2, z = 0.0): Vec3 = proc vec3*(a: Vec2, z = 0.0): Vec3 {.inline.} =
vec3(a.x, a.y, z) vec3(a.x, a.y, z)
proc vec4*(a: Vec3, w = 0.0): Vec4 = proc vec4*(a: Vec3, w = 0.0): Vec4 {.inline.} =
vec4(a.x, a.y, a.z, w) vec4(a.x, a.y, a.z, w)
proc vec4*(a: Vec2, z = 0.0, w = 0.0): Vec4 = proc vec4*(a: Vec2, z = 0.0, w = 0.0): Vec4 {.inline.} =
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