Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ quat(1.0, 2.0, 3.0, 4.0) ~= quat(1.0, 2.0, 3.0, 4.0)
* `sign` - Returns the sign of a number, -1 or 1.
* `quantize` - Makes v be a multiple of n. Rounding to integer quantizes by 1.0.
* `lerp` - Interpolates value between a and b.
* `step` - Returns 0.0 if x is less than edge, otherwise 1.0.
* `smoothstep` - Performs smooth Hermite interpolation between 0.0 and 1.0.

## Angle functions

Expand Down
69 changes: 69 additions & 0 deletions src/vmath.nim
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,15 @@ proc mix*[T: SomeFloat](a, b, v: T): T =
## * 0.5 -> between a and b
v * (b - a) + a

proc step*[T: SomeFloat](edge, x: T): T =
## Returns 0.0 if x is less than edge, otherwise 1.0.
if x < edge: T(0) else: T(1)

proc smoothstep*[T: SomeFloat](edge0, edge1, x: T): T =
## Performs smooth Hermite interpolation between 0.0 and 1.0.
let t = clamp((x - edge0) / (edge1 - edge0), T(0), T(1))
t * t * (T(3) - T(2) * t)

proc fixAngle*[T: SomeFloat](angle: T): T =
## Normalize the angle to be from -PI to PI radians.
result = angle
Expand Down Expand Up @@ -953,6 +962,66 @@ proc mix*[T: SomeFloat](a, b, v: GVec4[T]): type(a) =
result.z = a.z * (1.0 - v.z) + b.z * v.z
result.w = a.w * (1.0 - v.w) + b.w * v.w

proc step*[T: SomeFloat](edge, x: GVec2[T]): type(x) =
result.x = step(edge.x, x.x)
result.y = step(edge.y, x.y)

proc step*[T: SomeFloat](edge, x: GVec3[T]): type(x) =
result.x = step(edge.x, x.x)
result.y = step(edge.y, x.y)
result.z = step(edge.z, x.z)

proc step*[T: SomeFloat](edge, x: GVec4[T]): type(x) =
result.x = step(edge.x, x.x)
result.y = step(edge.y, x.y)
result.z = step(edge.z, x.z)
result.w = step(edge.w, x.w)

proc step*[T: SomeFloat](edge: T, x: GVec2[T]): type(x) =
result.x = step(edge, x.x)
result.y = step(edge, x.y)

proc step*[T: SomeFloat](edge: T, x: GVec3[T]): type(x) =
result.x = step(edge, x.x)
result.y = step(edge, x.y)
result.z = step(edge, x.z)

proc step*[T: SomeFloat](edge: T, x: GVec4[T]): type(x) =
result.x = step(edge, x.x)
result.y = step(edge, x.y)
result.z = step(edge, x.z)
result.w = step(edge, x.w)

proc smoothstep*[T: SomeFloat](edge0, edge1, x: GVec2[T]): type(x) =
result.x = smoothstep(edge0.x, edge1.x, x.x)
result.y = smoothstep(edge0.y, edge1.y, x.y)

proc smoothstep*[T: SomeFloat](edge0, edge1, x: GVec3[T]): type(x) =
result.x = smoothstep(edge0.x, edge1.x, x.x)
result.y = smoothstep(edge0.y, edge1.y, x.y)
result.z = smoothstep(edge0.z, edge1.z, x.z)

proc smoothstep*[T: SomeFloat](edge0, edge1, x: GVec4[T]): type(x) =
result.x = smoothstep(edge0.x, edge1.x, x.x)
result.y = smoothstep(edge0.y, edge1.y, x.y)
result.z = smoothstep(edge0.z, edge1.z, x.z)
result.w = smoothstep(edge0.w, edge1.w, x.w)

proc smoothstep*[T: SomeFloat](edge0, edge1: T, x: GVec2[T]): type(x) =
result.x = smoothstep(edge0, edge1, x.x)
result.y = smoothstep(edge0, edge1, x.y)

proc smoothstep*[T: SomeFloat](edge0, edge1: T, x: GVec3[T]): type(x) =
result.x = smoothstep(edge0, edge1, x.x)
result.y = smoothstep(edge0, edge1, x.y)
result.z = smoothstep(edge0, edge1, x.z)

proc smoothstep*[T: SomeFloat](edge0, edge1: T, x: GVec4[T]): type(x) =
result.x = smoothstep(edge0, edge1, x.x)
result.y = smoothstep(edge0, edge1, x.y)
result.z = smoothstep(edge0, edge1, x.z)
result.w = smoothstep(edge0, edge1, x.w)

proc cross*[T](a, b: GVec3[T]): GVec3[T] =
gvec3(
a.y * b.z - a.z * b.y,
Expand Down
21 changes: 21 additions & 0 deletions tests/tests.nim
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ suite "scalar utilities":
check mix(0.0, 10.0, 0.5) ~= 5.0
check mix(-1.0, 1.0, 0.25) ~= -0.5

test "step":
check step(0.5, 0.25) ~= 0.0
check step(0.5, 0.5) ~= 1.0
check step(0.5'f32, 1.0'f32) ~= 1.0'f32

test "smoothstep":
check smoothstep(0.0, 1.0, -1.0) ~= 0.0
check smoothstep(0.0, 1.0, 0.5) ~= 0.5
check smoothstep(0.0, 1.0, 2.0) ~= 1.0
check smoothstep(0.0'f32, 1.0'f32, 0.25'f32) ~= 0.15625'f32

test "fixAngle":
check fixAngle(0.1) ~= 0.1
check fixAngle(3.1) ~= 3.1
Expand Down Expand Up @@ -622,6 +633,16 @@ suite "vector operations":
check mix(vec2(0, 0), vec2(10, 20), vec2(0.5, 1.0)) ~= vec2(5, 20)
check mix(vec3(0, 0, 0), vec3(10, 20, 30), vec3(0.0, 0.5, 1.0)) ~= vec3(0, 10, 30)

test "step (vector)":
check step(vec2(0.5, 0.5), vec2(0.25, 0.5)) == vec2(0, 1)
check step(0.5'f32, vec3(0.25, 0.5, 0.75)) == vec3(0, 1, 1)
check step(dvec2(-1, 2), dvec2(-2, 3)) == dvec2(0, 1)

test "smoothstep (vector)":
check smoothstep(0.0'f32, 1.0'f32, vec3(-1, 0.5, 2)) ~= vec3(0, 0.5, 1)
check smoothstep(vec3(0, 0, 0), vec3(1, 2, 4), vec3(0.5, 1, 2)) ~= vec3(0.5, 0.5, 0.5)
check smoothstep(dvec2(0, 0), dvec2(1, 1), dvec2(0.25, 0.75)) ~= dvec2(0.15625, 0.84375)

test "clamp (vector bounds)":
check clamp(vec2(5, -5), vec2(0, 0), vec2(3, 3)) == vec2(3, 0)
check clamp(vec3(5, -5, 1), vec3(0, 0, 0), vec3(3, 3, 3)) == vec3(3, 0, 1)
Expand Down
Loading