finished deleting workflow stuff

This commit is contained in:
FatalErr42O 2023-09-09 11:50:03 -07:00
parent 68c210e60d
commit 00a01b5403
11 changed files with 0 additions and 2496 deletions

View File

@ -1,225 +0,0 @@
local bound2 = require "modules.bound2"
local vec2 = require "modules.vec2"
local DBL_EPSILON = require("modules.constants").DBL_EPSILON
describe("bound2:", function()
it("creates an empty bound2", function()
local a = bound2()
assert.is.equal(0, a.min.x)
assert.is.equal(0, a.min.y)
assert.is.equal(0, a.max.x)
assert.is.equal(0, a.max.y)
end)
it("creates a bound2 from vec2s", function()
local a = bound2(vec2(1,2), vec2(4,5))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
end)
it("creates a bound2 using new()", function()
local a = bound2.new(vec2(1,2), vec2(4,5))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
end)
it("creates a bound2 using at()", function()
local a = bound2.at(vec2(4,5), vec2(1,2))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
end)
it("clones a bound2", function()
local a = bound2(vec2(1,2), vec2(4,5))
local b = a:clone()
a.max = vec2.new(9,9)
assert.is.equal(a.min, b.min)
assert.is.not_equal(a.max, b.max)
end)
it("uses bound2 check()", function()
local a = bound2(vec2(4,2), vec2(1,5)):check()
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
end)
it("queries a bound2 size", function()
local a = bound2(vec2(1,2), vec2(4,6))
local v = a:size()
local r = a:radius()
assert.is.equal(3, v.x)
assert.is.equal(4, v.y)
assert.is.equal(1.5, r.x)
assert.is.equal(2, r.y)
end)
it("sets a bound2 size", function()
local a = bound2(vec2(1,2), vec2(4,5))
local b = a:with_size(vec2(1,1))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
assert.is.equal(1, b.min.x)
assert.is.equal(2, b.min.y)
assert.is.equal(2, b.max.x)
assert.is.equal(3, b.max.y)
end)
it("queries a bound2 center", function()
local a = bound2(vec2(1,2), vec2(3,4))
local v = a:center()
assert.is.equal(2, v.x)
assert.is.equal(3, v.y)
end)
it("sets a bound2 center", function()
local a = bound2(vec2(1,2), vec2(3,4))
local b = a:with_center(vec2(1,1))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.max.x)
assert.is.equal(4, a.max.y)
assert.is.equal(0, b.min.x)
assert.is.equal(0, b.min.y)
assert.is.equal(2, b.max.x)
assert.is.equal(2, b.max.y)
end)
it("sets a bound2 size centered", function()
local a = bound2(vec2(1,2), vec2(3,4))
local b = a:with_size_centered(vec2(4,4))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.max.x)
assert.is.equal(4, a.max.y)
assert.is.equal(0, b.min.x)
assert.is.equal(1, b.min.y)
assert.is.equal(4, b.max.x)
assert.is.equal(5, b.max.y)
end)
it("insets a bound2", function()
local a = bound2(vec2(1,2), vec2(5,10))
local b = a:inset(vec2(1,2))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(5, a.max.x)
assert.is.equal(10, a.max.y)
assert.is.equal(2, b.min.x)
assert.is.equal(4, b.min.y)
assert.is.equal(4, b.max.x)
assert.is.equal(8, b.max.y)
end)
it("outsets a bound2", function()
local a = bound2(vec2(1,2), vec2(5,6))
local b = a:outset(vec2(1,2))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(5, a.max.x)
assert.is.equal(6, a.max.y)
assert.is.equal(0, b.min.x)
assert.is.equal(0, b.min.y)
assert.is.equal(6, b.max.x)
assert.is.equal(8, b.max.y)
end)
it("offsets a bound2", function()
local a = bound2(vec2(1,2), vec2(5,6))
local b = a:offset(vec2(1,2))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(5, a.max.x)
assert.is.equal(6, a.max.y)
assert.is.equal(2, b.min.x)
assert.is.equal(4, b.min.y)
assert.is.equal(6, b.max.x)
assert.is.equal(8, b.max.y)
end)
it("tests for points inside bound2", function()
local a = bound2(vec2(1,2), vec2(4,5))
assert.is_true(a:contains(vec2(1,2)))
assert.is_true(a:contains(vec2(4,5)))
assert.is_true(a:contains(vec2(2,3)))
assert.is_not_true(a:contains(vec2(0,3)))
assert.is_not_true(a:contains(vec2(5,3)))
assert.is_not_true(a:contains(vec2(2,1)))
assert.is_not_true(a:contains(vec2(2,6)))
end)
it("rounds a bound2", function()
local a = bound2(vec2(1.1,1.9), vec2(3.9,5.1)):round()
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
end)
it("extends a bound2 with a point", function()
local min = vec2(1,2)
local max = vec2(4,5)
local downright = vec2(8,8)
local downleft = vec2(-4,8)
local top = vec2(2, 0)
local a = bound2(min, max)
local temp
temp = a:extend(downright)
assert.is_true(a.min == min and a.max == max)
assert.is_true(temp.min == min and temp.max == downright)
temp = a:extend(downleft)
assert.is_true(temp.min == vec2(-4,2) and temp.max == vec2(4,8))
temp = a:extend(top)
assert.is_true(temp.min == vec2(1,0) and temp.max == max)
end)
it("extends a bound with another bound", function()
local min = vec2(1,2)
local max = vec2(4,5)
local leftexpand = bound2.new(vec2(0,0), vec2(1.5, 6))
local rightexpand = bound2.new(vec2(1.5,0), vec2(5, 6))
local a = bound2(min, max)
local temp
temp = a:extend_bound(leftexpand)
assert.is_equal(temp.min, vec2(0,0))
assert.is_equal(temp.max, vec2(4,6))
temp = temp:extend_bound(rightexpand)
assert.is_equal(temp.min, vec2(0,0))
assert.is_equal(temp.max, vec2(5,6))
end)
it("checks for bound2.zero", function()
assert.is.equal(0, bound2.zero.min.x)
assert.is.equal(0, bound2.zero.min.y)
assert.is.equal(0, bound2.zero.max.x)
assert.is.equal(0, bound2.zero.max.y)
end)
end)

View File

@ -1,268 +0,0 @@
local bound3 = require "modules.bound3"
local vec3 = require "modules.vec3"
local DBL_EPSILON = require("modules.constants").DBL_EPSILON
describe("bound3:", function()
it("creates an empty bound3", function()
local a = bound3()
assert.is.equal(0, a.min.x)
assert.is.equal(0, a.min.y)
assert.is.equal(0, a.min.z)
assert.is.equal(0, a.max.x)
assert.is.equal(0, a.max.y)
assert.is.equal(0, a.max.z)
end)
it("creates a bound3 from vec3s", function()
local a = bound3(vec3(1,2,3), vec3(4,5,6))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
assert.is.equal(6, a.max.z)
end)
it("creates a bound3 using new()", function()
local a = bound3.new(vec3(1,2,3), vec3(4,5,6))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
assert.is.equal(6, a.max.z)
end)
it("creates a bound3 using at()", function()
local a = bound3.at(vec3(4,5,6), vec3(1,2,3))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
assert.is.equal(6, a.max.z)
end)
it("clones a bound3", function()
local a = bound3(vec3(1,2,3), vec3(4,5,6))
local b = a:clone()
a.max = vec3.new(9,9,9)
assert.is.equal(a.min, b.min)
assert.is.not_equal(a.max, b.max)
end)
it("uses bound3 check()", function()
local a = bound3(vec3(4,2,6), vec3(1,5,3)):check()
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
assert.is.equal(6, a.max.z)
end)
it("queries a bound3 size", function()
local a = bound3(vec3(1,2,3), vec3(4,6,8))
local v = a:size()
local r = a:radius()
assert.is.equal(3, v.x)
assert.is.equal(4, v.y)
assert.is.equal(5, v.z)
assert.is.equal(1.5, r.x)
assert.is.equal(2, r.y)
assert.is.equal(2.5, r.z)
end)
it("sets a bound3 size", function()
local a = bound3(vec3(1,2,3), vec3(4,5,6))
local b = a:with_size(vec3(1,1,1))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
assert.is.equal(6, a.max.z)
assert.is.equal(1, b.min.x)
assert.is.equal(2, b.min.y)
assert.is.equal(3, b.min.z)
assert.is.equal(2, b.max.x)
assert.is.equal(3, b.max.y)
assert.is.equal(4, b.max.z)
end)
it("queries a bound3 center", function()
local a = bound3(vec3(1,2,3), vec3(3,4,5))
local v = a:center()
assert.is.equal(2, v.x)
assert.is.equal(3, v.y)
assert.is.equal(4, v.z)
end)
it("sets a bound3 center", function()
local a = bound3(vec3(1,2,3), vec3(3,4,5))
local b = a:with_center(vec3(1,1,1))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(3, a.max.x)
assert.is.equal(4, a.max.y)
assert.is.equal(5, a.max.z)
assert.is.equal(0, b.min.x)
assert.is.equal(0, b.min.y)
assert.is.equal(0, b.min.z)
assert.is.equal(2, b.max.x)
assert.is.equal(2, b.max.y)
assert.is.equal(2, b.max.z)
end)
it("sets a bound3 size centered", function()
local a = bound3(vec3(1,2,3), vec3(3,4,5))
local b = a:with_size_centered(vec3(4,4,4))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(3, a.max.x)
assert.is.equal(4, a.max.y)
assert.is.equal(5, a.max.z)
assert.is.equal(0, b.min.x)
assert.is.equal(1, b.min.y)
assert.is.equal(2, b.min.z)
assert.is.equal(4, b.max.x)
assert.is.equal(5, b.max.y)
assert.is.equal(6, b.max.z)
end)
it("insets a bound3", function()
local a = bound3(vec3(1,2,3), vec3(5,10,11))
local b = a:inset(vec3(1,2,3))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(5, a.max.x)
assert.is.equal(10, a.max.y)
assert.is.equal(11, a.max.z)
assert.is.equal(2, b.min.x)
assert.is.equal(4, b.min.y)
assert.is.equal(6, b.min.z)
assert.is.equal(4, b.max.x)
assert.is.equal(8, b.max.y)
assert.is.equal(8, b.max.z)
end)
it("outsets a bound3", function()
local a = bound3(vec3(1,2,3), vec3(5,6,7))
local b = a:outset(vec3(1,2,3))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(5, a.max.x)
assert.is.equal(6, a.max.y)
assert.is.equal(7, a.max.z)
assert.is.equal(0, b.min.x)
assert.is.equal(0, b.min.y)
assert.is.equal(0, b.min.z)
assert.is.equal(6, b.max.x)
assert.is.equal(8, b.max.y)
assert.is.equal(10, b.max.z)
end)
it("offsets a bound3", function()
local a = bound3(vec3(1,2,3), vec3(5,6,7))
local b = a:offset(vec3(1,2,3))
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(5, a.max.x)
assert.is.equal(6, a.max.y)
assert.is.equal(7, a.max.z)
assert.is.equal(2, b.min.x)
assert.is.equal(4, b.min.y)
assert.is.equal(6, b.min.z)
assert.is.equal(6, b.max.x)
assert.is.equal(8, b.max.y)
assert.is.equal(10, b.max.z)
end)
it("tests for points inside bound3", function()
local a = bound3(vec3(1,2,3), vec3(4,5,6))
assert.is_true(a:contains(vec3(1,2,3)))
assert.is_true(a:contains(vec3(4,5,6)))
assert.is_true(a:contains(vec3(2,3,4)))
assert.is_not_true(a:contains(vec3(0,3,4)))
assert.is_not_true(a:contains(vec3(5,3,4)))
assert.is_not_true(a:contains(vec3(2,1,4)))
assert.is_not_true(a:contains(vec3(2,6,4)))
assert.is_not_true(a:contains(vec3(2,3,2)))
assert.is_not_true(a:contains(vec3(2,3,7)))
end)
it("rounds a bound3", function()
local a = bound3(vec3(1.1,1.9,3), vec3(3.9,5.1,6)):round()
assert.is.equal(1, a.min.x)
assert.is.equal(2, a.min.y)
assert.is.equal(3, a.min.z)
assert.is.equal(4, a.max.x)
assert.is.equal(5, a.max.y)
assert.is.equal(6, a.max.z)
end)
it("extends a bound3 with a point", function()
local min = vec3(1,2,6)
local max = vec3(4,5,9)
local downright = vec3(8,8,10)
local downleft = vec3(-4,8,10)
local top = vec3(2, 0, 7)
local a = bound3(min, max)
local temp
temp = a:extend(downright)
assert.is_true(a.min == min and a.max == max)
assert.is_true(temp.min == min and temp.max == downright)
temp = a:extend(downleft)
assert.is_true(temp.min == vec3(-4,2,6) and temp.max == vec3(4,8,10))
temp = a:extend(top)
assert.is_true(temp.min == vec3(1,0,6) and temp.max == max)
end)
it("extends a bound with another bound", function()
local min = vec3(1,2,3)
local max = vec3(4,5,6)
local leftexpand = bound3.new(vec3(0,0,4), vec3(1.5,6,5))
local rightexpand = bound3.new(vec3(1.5,0,1), vec3(5,6,7))
local a = bound3(min, max)
local temp
temp = a:extend_bound(leftexpand)
assert.is_equal(temp.min, vec3(0,0,3))
assert.is_equal(temp.max, vec3(4,6,6))
temp = temp:extend_bound(rightexpand)
assert.is_equal(temp.min, vec3(0,0,1))
assert.is_equal(temp.max, vec3(5,6,7))
end)
it("checks for bound3.zero", function()
assert.is.equal(0, bound3.zero.min.x)
assert.is.equal(0, bound3.zero.min.y)
assert.is.equal(0, bound3.zero.min.z)
assert.is.equal(0, bound3.zero.max.x)
assert.is.equal(0, bound3.zero.max.y)
assert.is.equal(0, bound3.zero.max.z)
end)
end)

View File

@ -1,184 +0,0 @@
local color = require "modules.color"
local DBL_EPSILON = require("modules.constants").DBL_EPSILON
local function assert_is_float_equal(a, b)
if math.abs(a - b) > DBL_EPSILON then
assert.is.equal(a, b)
end
end
local function assert_is_approx_equal(a, b)
if math.abs(a - b) > 0.001 then
assert.is.equal(a, b)
end
end
describe("color:", function()
it("operators: add, subract, multiply", function()
local c = color(1, 1, 1, 1)
assert.is_true(c:is_color())
local r = c + c
assert.is_true(r:is_color())
assert_is_float_equal(r[1], 2)
assert_is_float_equal(r[2], 2)
assert_is_float_equal(r[3], 2)
r = c - c
assert.is_true(r:is_color())
assert_is_float_equal(r[1], 0)
assert_is_float_equal(r[2], 0)
assert_is_float_equal(r[3], 0)
r = c * 5
assert.is_true(r:is_color())
assert_is_float_equal(r[1], 5)
assert_is_float_equal(r[2], 5)
assert_is_float_equal(r[3], 5)
end)
it("rgb -> hsv -> rgb", function()
local c = color(1,1,1,1)
local hsv = c:color_to_hsv_table()
local c1 = color.hsv_to_color_table(hsv)
local c2 = color.from_hsva(hsv[1], hsv[2], hsv[3], hsv[4])
local c3 = color.from_hsv(hsv[1], hsv[2], hsv[3])
c3[4] = c[4]
for i=1,4 do
assert_is_float_equal(c[i], c1[i])
assert_is_float_equal(c[i], c2[i])
assert_is_float_equal(c[i], c3[i])
end
assert.is_true(c:is_color())
assert.is_true(c1:is_color())
assert.is_true(c2:is_color())
assert.is_true(c3:is_color())
end)
it("hsv -> rgb -> hsv", function()
local hsv1 = { 0, 0.3, 0.8, 0.9 }
for h=0,1, 0.1 do
hsv1[1] = h
local cc = color.hsv_to_color_table(hsv1)
local hsv2 = cc:color_to_hsv_table()
for i=1,4 do
assert_is_approx_equal(hsv1[i], hsv2[i])
end
end
end)
it("unpack", function()
local c = color(122/255, 20/255, 122/255, 255/255)
local r, g, b, a = c:unpack()
assert_is_float_equal(c[1], r)
assert_is_float_equal(c[2], g)
assert_is_float_equal(c[3], b)
assert_is_float_equal(c[4], a)
r, g, b, a = c:as_255()
assert_is_float_equal(122, r)
assert_is_float_equal(20, g)
assert_is_float_equal(122, b)
assert_is_float_equal(255, a)
end)
it("set hsv", function()
-- hsv value conversion values from http://colorizer.org/
local c = color(122/255, 20/255, 122/255, 1)
local hsv = c:color_to_hsv_table()
assert_is_approx_equal(hsv[1], 300/360)
assert_is_approx_equal(hsv[2], 0.8361)
assert_is_approx_equal(hsv[3], 0.4784)
local r = c:hue(200/360)
assert_is_approx_equal(r[1], 20/255)
assert_is_approx_equal(r[2], 88/255)
assert_is_approx_equal(r[3], 122/255)
r = c:saturation(0.2)
assert_is_approx_equal(r[1], 122/255)
assert_is_approx_equal(r[2], 97.6/255)
assert_is_approx_equal(r[3], 122/255)
r = c:value(0.2)
assert_is_approx_equal(r[1], 51/255)
assert_is_approx_equal(r[2], 8.36/255)
assert_is_approx_equal(r[3], 51/255)
end)
it("lighten a color", function()
local c = color(0, 0, 0, 0)
local r = c:lighten(0.1)
assert.is.equal(r[1], 0.1)
r = c:lighten(1000)
assert.is.equal(r[1], 1)
end)
it("darken a color", function()
local c = color(1, 1, 1, 1)
local r = c:darken(0.04)
assert.is.equal(r[1], 0.96)
r = c:darken(1000)
assert.is.equal(r[1], 0)
end)
it("multiply a color by a scalar", function()
local c = color(1, 1, 1, 1)
local r = c:multiply(0.04)
assert.is.equal(r[1], 0.04)
r = c:multiply(0)
for i=1,3 do
assert.is.equal(0, r[i])
end
assert.is.equal(1, r[4])
end)
it("modify alpha", function()
local c = color(1, 1, 1, 1)
local r = c:alpha(0.1)
assert.is.equal(r[4], 0.1)
r = c:opacity(0.5)
assert.is.equal(r[4], 0.5)
r = c:opacity(0.5)
:opacity(0.5)
assert.is.equal(r[4], 0.25)
end)
it("invert", function()
local c = color(1, 0.6, 0.25, 1)
local r = c:invert()
assert_is_float_equal(r[1], 0)
assert_is_float_equal(r[2], 0.4)
assert_is_float_equal(r[3], 0.75)
assert_is_float_equal(r[4], 1)
r = c:invert()
:invert()
for i=1,4 do
assert.is.equal(c[i], r[i])
end
end)
it("lerp", function()
local a = color(1, 0.6, 0.25, 1)
local b = color(1, 0.8, 0.75, 0.5)
local r = a:lerp(b, 0.5)
assert_is_float_equal(r[1], 1)
assert_is_float_equal(r[2], 0.7)
assert_is_float_equal(r[3], 0.5)
assert_is_float_equal(r[4], 0.75)
local r_a = a:lerp(b, 0)
local r_b = a:lerp(b, 1)
for i=1,4 do
assert.is.equal(a[i], r_a[i])
assert.is.equal(b[i], r_b[i])
end
end)
it("linear_to_gamma -> gamma_to_linear round trip", function()
local c = color(0.25, 0.25, 0.25, 1)
local r = color.gamma_to_linear(c:linear_to_gamma())
for i=1,4 do
assert_is_approx_equal(c[i], r[i])
end
end)
end)
--[[
to_string(a)
--]]

View File

@ -1,277 +0,0 @@
local intersect = require "modules.intersect"
local vec3 = require "modules.vec3"
local mat4 = require "modules.mat4"
describe("intersect:", function()
it("intersects a point with a triangle", function()
local a = vec3()
local b = vec3(0, 0, 5)
local c = {
vec3(-1, -1, 0),
vec3( 1, -1, 0),
vec3( 0.5, 1, 0)
}
assert.is_true(intersect.point_triangle(a, c))
assert.is_not_true(intersect.point_triangle(b, c))
end)
it("intersects a point with an aabb", function()
local a = vec3()
local b = vec3(0, 0, 5)
local c = {
min = vec3(-1),
max = vec3( 1)
}
assert.is_true(intersect.point_aabb(a, c))
assert.is_not_true(intersect.point_aabb(b, c))
end)
it("intersects a point with a frustum", function()
pending("TODO")
end)
it("intersects a ray with a triangle", function()
local a = {
position = vec3(0.5, 0.5, -1),
direction = vec3(0, 0, 1)
}
local b = {
position = vec3(0.5, 0.5, -1),
direction = vec3(0, 0, -1)
}
local c = {
vec3(-1, -1, 0),
vec3( 1, -1, 0),
vec3( 0.5, 1, 0)
}
assert.is_true(vec3.is_vec3(intersect.ray_triangle(a, c)))
assert.is_not_true(intersect.ray_triangle(b, c))
end)
it("intersects a ray with a sphere", function()
local a = {
position = vec3(0, 0, -2),
direction = vec3(0, 0, 1)
}
local b = {
position = vec3(0, 0, -2),
direction = vec3(0, 0, -1)
}
local c = {
position = vec3(),
radius = 1
}
local w, x = intersect.ray_sphere(a, c)
local y, z = intersect.ray_sphere(b, c)
assert.is_true(vec3.is_vec3(w))
assert.is_not_true(y)
end)
it("intersects a ray with an aabb", function()
local a = {
position = vec3(0, 0, -2),
direction = vec3(0, 0, 1)
}
local b = {
position = vec3(0, 0, -2),
direction = vec3(0, 0, -1)
}
local c = {
min = vec3(-1),
max = vec3( 1)
}
local w, x = intersect.ray_aabb(a, c)
local y, z = intersect.ray_aabb(b, c)
assert.is_true(vec3.is_vec3(w))
assert.is_not_true(y)
end)
it("intersects a ray with a plane", function()
local a = {
position = vec3(0, 0, 1),
direction = vec3(0, 0, -1)
}
local b = {
position = vec3(0, 0, 1),
direction = vec3(0, 0, 1)
}
local c = {
position = vec3(),
normal = vec3(0, 0, 1)
}
local w, x = intersect.ray_plane(a, c)
local y, z = intersect.ray_plane(b, c)
assert.is_true(vec3.is_vec3(w))
assert.is_not_true(y)
end)
it("intersects a line with a line", function()
local a = {
vec3(0, 0, -1),
vec3(0, 0, 1)
}
local b = {
vec3(0, 0, -1),
vec3(0, 1, -1)
}
local c = {
vec3(-1, 0, 0),
vec3( 1, 0, 0)
}
local w, x = intersect.line_line(a, c, 0.001)
local y, z = intersect.line_line(b, c, 0.001)
local u, v = intersect.line_line(b, c)
assert.is_truthy(w)
assert.is_not_truthy(y)
assert.is_truthy(u)
end)
it("intersects a segment with a segment", function()
local a = {
vec3(0, 0, -1),
vec3(0, 0, 1)
}
local b = {
vec3(0, 0, -1),
vec3(0, 1, -1)
}
local c = {
vec3(-1, 0, 0),
vec3( 1, 0, 0)
}
local w, x = intersect.segment_segment(a, c, 0.001)
local y, z = intersect.segment_segment(b, c, 0.001)
local u, v = intersect.segment_segment(b, c)
assert.is_truthy(w)
assert.is_not_truthy(y)
assert.is_truthy(u)
end)
it("intersects an aabb with an aabb", function()
local a = {
min = vec3(-1),
max = vec3( 1)
}
local b = {
min = vec3(-5),
max = vec3(-3)
}
local c = {
min = vec3(),
max = vec3(2)
}
assert.is_true(intersect.aabb_aabb(a, c))
assert.is_not_true(intersect.aabb_aabb(b, c))
end)
it("intersects an aabb with an obb", function()
local r = mat4():rotate(mat4(), math.pi / 4, vec3.unit_z)
local a = {
position = vec3(),
extent = vec3(0.5)
}
local b = {
position = vec3(),
extent = vec3(0.5),
rotation = r
}
local c = {
position = vec3(0, 0, 2),
extent = vec3(0.5),
rotation = r
}
assert.is_true(vec3.is_vec3(intersect.aabb_obb(a, b)))
assert.is_not_true(intersect.aabb_obb(a, c))
end)
it("intersects an aabb with a sphere", function()
local a = {
min = vec3(-1),
max = vec3( 1)
}
local b = {
min = vec3(-5),
max = vec3(-3)
}
local c = {
position = vec3(0, 0, 3),
radius = 3
}
assert.is_true(intersect.aabb_sphere(a, c))
assert.is_not_true(intersect.aabb_sphere(b, c))
end)
it("intersects an aabb with a frustum", function()
pending("TODO")
end)
it("encapsulates an aabb", function()
local a = {
min = vec3(-1),
max = vec3( 1)
}
local b = {
min = vec3(-1.5),
max = vec3( 1.5)
}
local c = {
min = vec3(-0.5),
max = vec3( 0.5)
}
local d = {
min = vec3(-1),
max = vec3( 1)
}
assert.is_true(intersect.encapsulate_aabb(a, d))
assert.is_true(intersect.encapsulate_aabb(b, d))
assert.is_not_true(intersect.encapsulate_aabb(c, d))
end)
it("intersects a circle with a circle", function()
local a = {
position = vec3(0, 0, 6),
radius = 3
}
local b = {
position = vec3(0, 0, 7),
radius = 3
}
local c = {
position = vec3(),
radius = 3
}
assert.is_true(intersect.circle_circle(a, c))
assert.is_not_true(intersect.circle_circle(b, c))
end)
it("intersects a sphere with a sphere", function()
local a = {
position = vec3(0, 0, 6),
radius = 3
}
local b = {
position = vec3(0, 0, 7),
radius = 3
}
local c = {
position = vec3(),
radius = 3
}
assert.is_true(intersect.sphere_sphere(a, c))
assert.is_not_true(intersect.sphere_sphere(b, c))
end)
it("intersects a sphere with a frustum", function()
pending("TODO")
end)
it("intersects a capsule with another capsule", function()
pending("TODO")
end)
end)

View File

@ -1,533 +0,0 @@
local mat4 = require "modules.mat4"
local vec3 = require "modules.vec3"
local quat = require "modules.quat"
local utils = require "modules.utils"
local FLT_EPSILON = require("modules.constants").FLT_EPSILON
describe("mat4:", function()
it("creates an identity matrix", function()
local a = mat4()
assert.is.equal(1, a[1])
assert.is.equal(0, a[2])
assert.is.equal(0, a[3])
assert.is.equal(0, a[4])
assert.is.equal(0, a[5])
assert.is.equal(1, a[6])
assert.is.equal(0, a[7])
assert.is.equal(0, a[8])
assert.is.equal(0, a[9])
assert.is.equal(0, a[10])
assert.is.equal(1, a[11])
assert.is.equal(0, a[12])
assert.is.equal(0, a[13])
assert.is.equal(0, a[14])
assert.is.equal(0, a[15])
assert.is.equal(1, a[16])
assert.is_true(a:is_mat4())
end)
it("creates a filled matrix", function()
local a = mat4 {
3, 3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5,
6, 6, 6, 6
}
assert.is.equal(3, a[1])
assert.is.equal(3, a[2])
assert.is.equal(3, a[3])
assert.is.equal(3, a[4])
assert.is.equal(4, a[5])
assert.is.equal(4, a[6])
assert.is.equal(4, a[7])
assert.is.equal(4, a[8])
assert.is.equal(5, a[9])
assert.is.equal(5, a[10])
assert.is.equal(5, a[11])
assert.is.equal(5, a[12])
assert.is.equal(6, a[13])
assert.is.equal(6, a[14])
assert.is.equal(6, a[15])
assert.is.equal(6, a[16])
end)
it("creates a filled matrix from vec4s", function()
local a = mat4 {
{ 3, 3, 3, 3 },
{ 4, 4, 4, 4 },
{ 5, 5, 5, 5 },
{ 6, 6, 6, 6 }
}
assert.is.equal(3, a[1])
assert.is.equal(3, a[2])
assert.is.equal(3, a[3])
assert.is.equal(3, a[4])
assert.is.equal(4, a[5])
assert.is.equal(4, a[6])
assert.is.equal(4, a[7])
assert.is.equal(4, a[8])
assert.is.equal(5, a[9])
assert.is.equal(5, a[10])
assert.is.equal(5, a[11])
assert.is.equal(5, a[12])
assert.is.equal(6, a[13])
assert.is.equal(6, a[14])
assert.is.equal(6, a[15])
assert.is.equal(6, a[16])
end)
it("creates a filled matrix from a 3x3 matrix", function()
local a = mat4 {
3, 3, 3,
4, 4, 4,
5, 5, 5
}
assert.is.equal(3, a[1])
assert.is.equal(3, a[2])
assert.is.equal(3, a[3])
assert.is.equal(0, a[4])
assert.is.equal(4, a[5])
assert.is.equal(4, a[6])
assert.is.equal(4, a[7])
assert.is.equal(0, a[8])
assert.is.equal(5, a[9])
assert.is.equal(5, a[10])
assert.is.equal(5, a[11])
assert.is.equal(0, a[12])
assert.is.equal(0, a[13])
assert.is.equal(0, a[14])
assert.is.equal(0, a[15])
assert.is.equal(1, a[16])
end)
it("creates a matrix from perspective", function()
local a = mat4.from_perspective(45, 1, 0.1, 1000)
assert.is_true(utils.tolerance( 2.414-a[1], 0.001))
assert.is_true(utils.tolerance( 2.414-a[6], 0.001))
assert.is_true(utils.tolerance(-1 -a[11], 0.001))
assert.is_true(utils.tolerance(-1 -a[12], 0.001))
assert.is_true(utils.tolerance(-0.2 -a[15], 0.001))
end)
it("creates a matrix from HMD perspective", function()
local t = {
LeftTan = 2.3465312,
RightTan = 0.9616399,
UpTan = 2.8664987,
DownTan = 2.8664987
}
local a = mat4.from_hmd_perspective(t, 0.1, 1000, false, false)
assert.is_true(utils.tolerance(a[1] - 0.605, 0.001))
assert.is_true(utils.tolerance(a[6] - 0.349, 0.001))
assert.is_true(utils.tolerance(a[9] - -0.419, 0.001))
assert.is_true(utils.tolerance(a[11]- -1.000, 0.001))
assert.is_true(utils.tolerance(a[12]- -1.000, 0.001))
assert.is_true(utils.tolerance(a[15]- -0.200, 0.001))
end)
it("clones a matrix", function()
local a = mat4.identity()
local b = a:clone()
assert.is.equal(a, b)
end)
it("multiplies two 4x4 matrices", function()
local a = mat4 {
1, 5, 9, 13,
2, 6, 10, 14,
3, 7, 11, 15,
4, 8, 12, 16
}
local b = mat4 {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16
}
local c = mat4():mul(a, b)
local d = a * b
local e = mat4():mul{a, b}
assert.is.equal(30, c[1])
assert.is.equal(70, c[2])
assert.is.equal(110, c[3])
assert.is.equal(150, c[4])
assert.is.equal(70, c[5])
assert.is.equal(174, c[6])
assert.is.equal(278, c[7])
assert.is.equal(382, c[8])
assert.is.equal(110, c[9])
assert.is.equal(278, c[10])
assert.is.equal(446, c[11])
assert.is.equal(614, c[12])
assert.is.equal(150, c[13])
assert.is.equal(382, c[14])
assert.is.equal(614, c[15])
assert.is.equal(846, c[16])
assert.is.equal(c, d)
assert.is.equal(c, e)
end)
it("multiplies a matrix and a vec4", function()
local a = mat4 {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16
}
local b = { 10, 20, 30, 40 }
local c = mat4.mul_vec4(mat4(), a, b)
local d = a * b
assert.is.equal(900, c[1])
assert.is.equal(1000, c[2])
assert.is.equal(1100, c[3])
assert.is.equal(1200, c[4])
assert.is.equal(c[1], d[1])
assert.is.equal(c[2], d[2])
assert.is.equal(c[3], d[3])
assert.is.equal(c[4], d[4])
end)
it("verifies mat4 composition order", function()
local a = mat4 {
1, 5, 9, 13,
2, 6, 10, 14,
3, 7, 11, 15,
4, 8, 12, 16
}
local b = mat4 {
2, 3, 5, 7,
11, 13, 17, 19,
23, 29, 31, 37,
41, 43, 47, 53
}
local c = mat4():mul(a, b)
local d = a * b
local v = { 10, 20, 30, 40 }
local cv = c * v
local abv = a*(b*v)
assert.is.equal(cv.x, abv.x) -- Verify (a*b)*v == a*(b*v)
assert.is.equal(cv.y, abv.y)
assert.is.equal(cv.z, abv.z)
end)
it("scales a matrix", function()
local a = mat4():scale(mat4(), vec3(5, 5, 5))
assert.is.equal(5, a[1])
assert.is.equal(5, a[6])
assert.is.equal(5, a[11])
end)
it("rotates a matrix", function()
local a = mat4():rotate(mat4(), math.rad(45), vec3.unit_z)
assert.is_true(utils.tolerance( 0.7071-a[1], 0.001))
assert.is_true(utils.tolerance( 0.7071-a[2], 0.001))
assert.is_true(utils.tolerance(-0.7071-a[5], 0.001))
assert.is_true(utils.tolerance( 0.7071-a[6], 0.001))
end)
it("translates a matrix", function()
local a = mat4():translate(mat4(), vec3(5, 5, 5))
assert.is.equal(5, a[13])
assert.is.equal(5, a[14])
assert.is.equal(5, a[15])
end)
it("inverts a matrix", function()
local a = mat4()
a = a:rotate(a, math.pi/4, vec3.unit_y)
a = a:translate(a, vec3(4, 5, 6))
local b = mat4.invert(mat4(), a)
local c = a * b
assert.is.equal(mat4(), c)
local d = mat4()
d:rotate(d, math.pi/4, vec3.unit_y)
d:translate(d, vec3(4, 5, 6))
local e = -d
local f = d * e
assert.is.equal(mat4(), f)
end)
it("transposes a matrix", function()
local a = mat4({
1, 1, 1, 1,
2, 2, 2, 2,
3, 3, 3, 3,
4, 4, 4, 4
})
a = a:transpose(a)
assert.is.equal(1, a[1])
assert.is.equal(2, a[2])
assert.is.equal(3, a[3])
assert.is.equal(4, a[4])
assert.is.equal(1, a[5])
assert.is.equal(2, a[6])
assert.is.equal(3, a[7])
assert.is.equal(4, a[8])
assert.is.equal(1, a[9])
assert.is.equal(2, a[10])
assert.is.equal(3, a[11])
assert.is.equal(4, a[12])
assert.is.equal(1, a[13])
assert.is.equal(2, a[14])
assert.is.equal(3, a[15])
assert.is.equal(4, a[16])
end)
it("shears a matrix", function()
local yx, zx, xy, zy, xz, yz = 1, 1, 1, -1, -1, -1
local a = mat4():shear(mat4(), yx, zx, xy, zy, xz, yz)
assert.is.equal( 1, a[2])
assert.is.equal( 1, a[3])
assert.is.equal( 1, a[5])
assert.is.equal(-1, a[7])
assert.is.equal(-1, a[9])
assert.is.equal(-1, a[10])
end)
it("reflects a matrix along a plane", function()
local origin = vec3(5, 1, 0)
local normal = vec3(0, -1, 0):normalize()
local a = mat4():reflect(mat4(), origin, normal)
local p = a * vec3(-5, 2, 5)
assert.is.equal(p.x, -5)
assert.is.equal(p.y, 0)
assert.is.equal(p.z, 5)
end)
it("projects a point into screen space", function()
local znear = 0.1
local zfar = 1000
local proj = mat4.from_perspective(45, 1, znear, zfar)
local vp = { 0, 0, 400, 400 }
-- -z is away from the viewer into the far plane
local p1 = vec3(0, 0, -znear)
local c1 = mat4.project(p1, proj, vp)
assert.is.near(0, c1.z, 0.0001)
assert.is.equal(200, c1.x)
assert.is.equal(200, c1.y)
local p2 = vec3(0, 0, -zfar)
local c2 = mat4.project(p2, proj, vp)
assert.is.near(1, c2.z, 0.0001)
assert.is.equal(200, c2.x)
assert.is.equal(200, c2.y)
local p3 = vec3(0, 0, zfar)
local c3 = mat4.project(p3, proj, vp)
assert.is_true(c3.z < 0)
assert.is.equal(200, c3.x)
assert.is.equal(200, c3.y)
end)
it("unprojects a point into world space", function()
local p = vec3(0, 0, -10)
local proj = mat4.from_perspective(45, 1, 0.1, 1000)
local vp = { 0, 0, 400, 400 }
local c = mat4.project(p, proj, vp)
local d = mat4.unproject(c, proj, vp)
assert.is.near(0.0, p.x-d.x, 0.0001)
assert.is.near(0.0, p.y-d.y, 0.0001)
assert.is.near(0.0, p.z-d.z, 0.0001)
end)
it("transforms a matrix to look at a point", function()
local e = vec3(0, 0, 1.55)
local c = vec3(4, 7, 1)
local u = vec3(0, 0, 1)
local a = mat4():look_at(e, c, u)
assert.is_true(utils.tolerance( 0.868-a[1], 0.001))
assert.is_true(utils.tolerance( 0.034-a[2], 0.001))
assert.is_true(utils.tolerance(-0.495-a[3], 0.001))
assert.is_true(utils.tolerance( 0 -a[4], 0.001))
assert.is_true(utils.tolerance(-0.496-a[5], 0.001))
assert.is_true(utils.tolerance( 0.059-a[6], 0.001))
assert.is_true(utils.tolerance(-0.866-a[7], 0.001))
assert.is_true(utils.tolerance( 0 -a[8], 0.001))
assert.is_true(utils.tolerance( 0 -a[9], 0.001))
assert.is_true(utils.tolerance( 0.998-a[10], 0.001))
assert.is_true(utils.tolerance( 0.068-a[11], 0.001))
assert.is_true(utils.tolerance( 0 -a[12], 0.001))
assert.is_true(utils.tolerance( 0 -a[13], 0.001))
assert.is_true(utils.tolerance(-1.546-a[14], 0.001))
assert.is_true(utils.tolerance(-0.106-a[15], 0.001))
assert.is_true(utils.tolerance( 1 -a[16], 0.001))
end)
it("converts a matrix to vec4s", function()
local a = mat4 {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16
}
local v = a:to_vec4s()
assert.is_true(type(v) == "table")
assert.is_true(type(v[1]) == "table")
assert.is_true(type(v[2]) == "table")
assert.is_true(type(v[3]) == "table")
assert.is_true(type(v[4]) == "table")
assert.is.equal(1, v[1][1])
assert.is.equal(2, v[1][2])
assert.is.equal(3, v[1][3])
assert.is.equal(4, v[1][4])
assert.is.equal(5, v[2][1])
assert.is.equal(6, v[2][2])
assert.is.equal(7, v[2][3])
assert.is.equal(8, v[2][4])
assert.is.equal(9, v[3][1])
assert.is.equal(10, v[3][2])
assert.is.equal(11, v[3][3])
assert.is.equal(12, v[3][4])
assert.is.equal(13, v[4][1])
assert.is.equal(14, v[4][2])
assert.is.equal(15, v[4][3])
assert.is.equal(16, v[4][4])
end)
it("converts a matrix to vec4s, column-wise", function()
local a = mat4 {
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16
}
local v = a:to_vec4s_cols()
assert.is_true(type(v) == "table")
assert.is_true(type(v[1]) == "table")
assert.is_true(type(v[2]) == "table")
assert.is_true(type(v[3]) == "table")
assert.is_true(type(v[4]) == "table")
assert.is.equal(1, v[1][1])
assert.is.equal(5, v[1][2])
assert.is.equal(9, v[1][3])
assert.is.equal(13, v[1][4])
assert.is.equal(2, v[2][1])
assert.is.equal(6, v[2][2])
assert.is.equal(10, v[2][3])
assert.is.equal(14, v[2][4])
assert.is.equal(3, v[3][1])
assert.is.equal(7, v[3][2])
assert.is.equal(11, v[3][3])
assert.is.equal(15, v[3][4])
assert.is.equal(4, v[4][1])
assert.is.equal(8, v[4][2])
assert.is.equal(12, v[4][3])
assert.is.equal(16, v[4][4])
end)
it("converts a matrix to a quaternion", function()
local q = mat4({
0, 0, 1, 0,
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0, 0
}):to_quat()
assert.is.equal(-0.5, q.x)
assert.is.equal(-0.5, q.y)
assert.is.equal(-0.5, q.z)
assert.is.equal( 0.5, q.w)
end)
it("converts a matrix to a frustum", function()
local a = mat4()
local b = mat4.from_perspective(45, 1, 0.1, 1000)
local f = (b * a):to_frustum()
assert.is_true(utils.tolerance( 0.9239-f.left.a, 0.001))
assert.is_true(utils.tolerance( 0 -f.left.b, 0.001))
assert.is_true(utils.tolerance(-0.3827-f.left.c, 0.001))
assert.is_true(utils.tolerance( 0 -f.left.d, 0.001))
assert.is_true(utils.tolerance(-0.9239-f.right.a, 0.001))
assert.is_true(utils.tolerance( 0 -f.right.b, 0.001))
assert.is_true(utils.tolerance(-0.3827-f.right.c, 0.001))
assert.is_true(utils.tolerance( 0 -f.right.d, 0.001))
assert.is_true(utils.tolerance( 0 -f.bottom.a, 0.001))
assert.is_true(utils.tolerance( 0.9239-f.bottom.b, 0.001))
assert.is_true(utils.tolerance(-0.3827-f.bottom.c, 0.001))
assert.is_true(utils.tolerance( 0 -f.bottom.d, 0.001))
assert.is_true(utils.tolerance( 0 -f.top.a, 0.001))
assert.is_true(utils.tolerance(-0.9239-f.top.b, 0.001))
assert.is_true(utils.tolerance(-0.3827-f.top.c, 0.001))
assert.is_true(utils.tolerance( 0 -f.top.d, 0.001))
assert.is_true(utils.tolerance( 0 -f.near.a, 0.001))
assert.is_true(utils.tolerance( 0 -f.near.b, 0.001))
assert.is_true(utils.tolerance(-1 -f.near.c, 0.001))
assert.is_true(utils.tolerance(-0.1-f.near.d, 0.001))
assert.is_true(utils.tolerance( 0 -f.far.a, 0.001))
assert.is_true(utils.tolerance( 0 -f.far.b, 0.001))
assert.is_true(utils.tolerance( 1 -f.far.c, 0.001))
assert.is_true(utils.tolerance( 1000-f.far.d, 0.001))
end)
it("checks to see if data is a valid matrix (not a table)", function()
assert.is_not_true(mat4.is_mat4(0))
end)
it("checks to see if data is a valid matrix (invalid data)", function()
assert.is_not_true(mat4.is_mat4({}))
end)
it("gets a string representation of a matrix", function()
local a = mat4():to_string()
local z = "+0.000"
local o = "+1.000"
local s = string.format(
"[ %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ]",
o, z, z, z, z, o, z, z, z, z, o, z, z, z ,z, o
)
assert.is.equal(s, a)
end)
it("creates a matrix out of transform values", function()
local scale = vec3(1, 2, 3)
local rot = quat.from_angle_axis(math.pi * 0.5, vec3(0, 1, 0))
local trans = vec3(3, 4, 5)
local a = mat4.from_transform(trans, rot, scale)
local v = vec3(-2, 3, 4)
-- scaled, rotated, then translated
-- v * mT * mR * mS
local result = a * v
local expected = vec3(-9, 10, 3)
-- float margin is considered
assert.is_true(math.abs(expected.x - result.x) < FLT_EPSILON)
assert.is_true(math.abs(expected.y - result.y) < FLT_EPSILON)
assert.is_true(math.abs(expected.z - result.z) < FLT_EPSILON)
end)
end)
--[[
from_angle_axis
from_quaternion
from_direction
from_transform
from_ortho
--]]

View File

@ -1,12 +0,0 @@
local mesh = require "modules.mesh"
describe("mesh:", function()
end)
--[[
average(vertices)
normal(triangle)
plane_from_triangle(triangle)
is_front_facing(plane, direction)
signed_distance(point, plane)
--]]

View File

@ -1,34 +0,0 @@
local octree = require "modules.octree"
describe("octree:", function()
end)
--[[
local function new(initialWorldSize, initialWorldPos, minNodeSize, looseness)
function Octree:add(obj, objBounds)
function Octree:remove(obj)
function Octree:is_colliding(checkBounds)
function Octree:get_colliding(checkBounds)
function Octree:cast_ray(ray, func, out)
function Octree:draw_bounds(cube)
function Octree:draw_objects(cube, filter)
function Octree:grow(direction)
function Octree:shrink()
function Octree:get_root_pos_index(xDir, yDir, zDir)
function OctreeNode:add(obj, objBounds)
function OctreeNode:remove(obj)
function OctreeNode:is_colliding(checkBounds)
function OctreeNode:get_colliding(checkBounds, results)
function OctreeNode:cast_ray(ray, func, out, depth)
function OctreeNode:set_children(childOctrees)
function OctreeNode:shrink_if_possible(minLength)
function OctreeNode:set_values(baseLength, minSize, looseness, center)
function OctreeNode:split()
function OctreeNode:merge()
function OctreeNode:best_fit_child(objBounds)
function OctreeNode:should_merge()
function OctreeNode:has_any_objects()
function OctreeNode:draw_bounds(cube, depth)
function OctreeNode:draw_objects(cube, filter)
--]]

View File

@ -1,347 +0,0 @@
local quat = require "modules.quat"
local vec3 = require "modules.vec3"
local utils = require "modules.utils"
local constants = require "modules.constants"
describe("quat:", function()
it("creates an identity quaternion", function()
local a = quat()
assert.is.equal(0, a.x)
assert.is.equal(0, a.y)
assert.is.equal(0, a.z)
assert.is.equal(1, a.w)
assert.is_true(a:is_quat())
assert.is_true(a:is_real())
end)
it("creates a quaternion from numbers", function()
local a = quat(0, 0, 0, 0)
assert.is.equal(0, a.x)
assert.is.equal(0, a.y)
assert.is.equal(0, a.z)
assert.is.equal(0, a.w)
assert.is_true(a:is_zero())
assert.is_true(a:is_imaginary())
end)
it("creates a quaternion from a list", function()
local a = quat { 2, 3, 4, 1 }
assert.is.equal(2, a.x)
assert.is.equal(3, a.y)
assert.is.equal(4, a.z)
assert.is.equal(1, a.w)
end)
it("creates a quaternion from a record", function()
local a = quat { x=2, y=3, z=4, w=1 }
assert.is.equal(2, a.x)
assert.is.equal(3, a.y)
assert.is.equal(4, a.z)
assert.is.equal(1, a.w)
end)
it("creates a quaternion from a direction", function()
local v = vec3(-80, 80, -80):normalize()
local a = quat.from_direction(v, vec3.unit_z)
assert.is_true(utils.tolerance(-0.577-a.x, 0.001))
assert.is_true(utils.tolerance(-0.577-a.y, 0.001))
assert.is_true(utils.tolerance( 0 -a.z, 0.001))
assert.is_true(utils.tolerance( 0.423-a.w, 0.001))
end)
it("clones a quaternion", function()
local a = quat()
local b = a:clone()
assert.is.equal(a.x, b.x)
assert.is.equal(a.y, b.y)
assert.is.equal(a.z, b.z)
assert.is.equal(a.w, b.w)
end)
it("adds a quaternion to another", function()
local a = quat(2, 3, 4, 1)
local b = quat(3, 6, 9, 1)
local c = a:add(b)
local d = a + b
assert.is.equal(5, c.x)
assert.is.equal(9, c.y)
assert.is.equal(13, c.z)
assert.is.equal(2, c.w)
assert.is.equal(c, d)
end)
it("subtracts a quaternion from another", function()
local a = quat(2, 3, 4, 1)
local b = quat(3, 6, 9, 1)
local c = a:sub(b)
local d = a - b
assert.is.equal(-1, c.x)
assert.is.equal(-3, c.y)
assert.is.equal(-5, c.z)
assert.is.equal( 0, c.w)
assert.is.equal(c, d)
end)
it("multiplies a quaternion by another", function()
local a = quat(2, 3, 4, 1)
local b = quat(3, 6, 9, 1)
local c = a:mul(b)
local d = a * b
assert.is.equal( 8, c.x)
assert.is.equal( 3, c.y)
assert.is.equal( 16, c.z)
assert.is.equal(-59, c.w)
assert.is.equal(c, d)
end)
it("multiplies a quaternion by a scale factor", function()
local a = quat(2, 3, 4, 1)
local s = 3
local b = a:scale(s)
local c = a * s
assert.is.equal(6, b.x)
assert.is.equal(9, b.y)
assert.is.equal(12, b.z)
assert.is.equal(3, b.w)
assert.is.equal(b, c)
end)
it("inverts a quaternion", function()
local a = quat(2, 3, 4, 1)
local b = -a
assert.is.equal(-a.x, b.x)
assert.is.equal(-a.y, b.y)
assert.is.equal(-a.z, b.z)
assert.is.equal(-a.w, b.w)
end)
it("multiplies a quaternion by a vec3", function()
local a = quat(2, 3, 4, 1)
local v = vec3(3, 4, 5)
local b = a:mul_vec3(v)
local c = a * v
assert.is.equal(-21, c.x)
assert.is.equal( 4, c.y)
assert.is.equal( 17, c.z)
assert.is.equal(b, c)
end)
it("verifies quat composition order", function()
local a = quat(2, 3, 4, 1):normalize() -- Only the normal quaternions represent rotations
local b = quat(3, 6, 9, 1):normalize()
local c = a * b
local v = vec3(3, 4, 5)
local cv = c * v
local abv = a * (b * v)
assert.is_true((abv - cv):len() < 1e-07) -- Verify (a*b)*v == a*(b*v) within an epsilon
end)
it("multiplies a quaternion by an exponent of 0", function()
local a = quat(2, 3, 4, 1):normalize()
local e = 0
local b = a:pow(e)
local c = a^e
assert.is.equal(0, b.x)
assert.is.equal(0, b.y)
assert.is.equal(0, b.z)
assert.is.equal(1, b.w)
assert.is.equal(b, c)
end)
it("multiplies a quaternion by a positive exponent", function()
local a = quat(2, 3, 4, 1):normalize()
local e = 0.75
local b = a:pow(e)
local c = a^e
assert.is_true(utils.tolerance(-0.3204+b.x, 0.0001))
assert.is_true(utils.tolerance(-0.4805+b.y, 0.0001))
assert.is_true(utils.tolerance(-0.6407+b.z, 0.0001))
assert.is_true(utils.tolerance(-0.5059+b.w, 0.0001))
assert.is.equal( b, c)
end)
it("multiplies a quaternion by a negative exponent", function()
local a = quat(2, 3, 4, 1):normalize()
local e = -1
local b = a:pow(e)
local c = a^e
assert.is_true(utils.tolerance( 0.3651+b.x, 0.0001))
assert.is_true(utils.tolerance( 0.5477+b.y, 0.0001))
assert.is_true(utils.tolerance( 0.7303+b.z, 0.0001))
assert.is_true(utils.tolerance(-0.1826+b.w, 0.0001))
assert.is.equal(b, c)
end)
it("inverts a quaternion", function()
local a = quat(1, 1, 1, 1):inverse()
assert.is.equal(-0.5, a.x)
assert.is.equal(-0.5, a.y)
assert.is.equal(-0.5, a.z)
assert.is.equal( 0.5, a.w)
end)
it("normalizes a quaternion", function()
local a = quat(1, 1, 1, 1):normalize()
assert.is.equal(0.5, a.x)
assert.is.equal(0.5, a.y)
assert.is.equal(0.5, a.z)
assert.is.equal(0.5, a.w)
end)
it("dots two quaternions", function()
local a = quat(1, 1, 1, 1)
local b = quat(4, 4, 4, 4)
local c = a:dot(b)
assert.is.equal(16, c)
end)
it("dots two quaternions (negative)", function()
local a = quat(-1, 1, 1, 1)
local b = quat(4, 4, 4, 4)
local c = a:dot(b)
assert.is.equal(8, c)
end)
it("dots two quaternions (tiny)", function()
local a = quat(0.1, 0.1, 0.1, 0.1)
local b = quat(0.4, 0.4, 0.4, 0.4)
local c = a:dot(b)
assert.is_true(utils.tolerance(0.16-c, 0.001))
end)
it("gets the length of a quaternion", function()
local a = quat(2, 3, 4, 5):len()
assert.is.equal(math.sqrt(54), a)
end)
it("gets the square length of a quaternion", function()
local a = quat(2, 3, 4, 5):len2()
assert.is.equal(54, a)
end)
it("interpolates between two quaternions", function()
local a = quat(3, 3, 3, 3)
local b = quat(6, 6, 6, 6)
local s = 0.1
local c = a:lerp(b, s)
assert.is.equal(0.5, c.x)
assert.is.equal(0.5, c.y)
assert.is.equal(0.5, c.z)
assert.is.equal(0.5, c.w)
end)
it("interpolates between two quaternions (spherical)", function()
local a = quat(3, 3, 3, 3)
local b = quat(6, 6, 6, 6)
local s = 0.1
local c = a:slerp(b, s)
assert.is.equal(0.5, c.x)
assert.is.equal(0.5, c.y)
assert.is.equal(0.5, c.z)
assert.is.equal(0.5, c.w)
end)
it("unpacks a quaternion", function()
local x, y, z, w = quat(2, 3, 4, 1):unpack()
assert.is.equal(2, x)
assert.is.equal(3, y)
assert.is.equal(4, z)
assert.is.equal(1, w)
end)
it("converts quaternion to a vec3", function()
local v = quat(2, 3, 4, 1):to_vec3()
assert.is.equal(2, v.x)
assert.is.equal(3, v.y)
assert.is.equal(4, v.z)
end)
it("gets the conjugate quaternion", function()
local a = quat(2, 3, 4, 1):conjugate()
assert.is.equal(-2, a.x)
assert.is.equal(-3, a.y)
assert.is.equal(-4, a.z)
assert.is.equal( 1, a.w)
end)
it("gets the reciprocal quaternion", function()
local a = quat(1, 1, 1, 1)
local b = a:reciprocal()
local c = b:reciprocal()
assert.is_not.equal(a.x, b.x)
assert.is_not.equal(a.y, b.y)
assert.is_not.equal(a.z, b.z)
assert.is_not.equal(a.w, b.w)
assert.is.equal(a.x, c.x)
assert.is.equal(a.y, c.y)
assert.is.equal(a.z, c.z)
assert.is.equal(a.w, c.w)
end)
it("converts between a quaternion and angle/axis", function()
local a = quat.from_angle_axis(math.pi, vec3.unit_z)
local angle, axis = a:to_angle_axis()
assert.is.equal(math.pi, angle)
assert.is.equal(vec3.unit_z, axis)
end)
it("converts between a quaternion and angle/axis (specify by component)", function()
local a = quat.from_angle_axis(math.pi, vec3.unit_z.x, vec3.unit_z.y, vec3.unit_z.z)
local angle, axis = a:to_angle_axis()
assert.is.equal(math.pi, angle)
assert.is.equal(vec3.unit_z, axis)
end)
it("converts between a quaternion and angle/axis (w=2)", function()
local angle, axis = quat(1, 1, 1, 2):to_angle_axis()
assert.is_true(utils.tolerance(1.427-angle, 0.001))
assert.is_true(utils.tolerance(0.577-axis.x, 0.001))
assert.is_true(utils.tolerance(0.577-axis.y, 0.001))
assert.is_true(utils.tolerance(0.577-axis.z, 0.001))
end)
it("converts between a quaternion and angle/axis (w=2) (by component)", function()
local angle, x,y,z = quat(1, 1, 1, 2):to_angle_axis_unpack()
assert.is_true(utils.tolerance(1.427-angle, 0.001))
assert.is_true(utils.tolerance(0.577-x, 0.001))
assert.is_true(utils.tolerance(0.577-y, 0.001))
assert.is_true(utils.tolerance(0.577-z, 0.001))
end)
it("converts between a quaternion and angle/axis (w=1)", function()
local angle, axis = quat(1, 2, 3, 1):to_angle_axis()
assert.is.equal(0, angle)
assert.is.equal(1, axis.x)
assert.is.equal(2, axis.y)
assert.is.equal(3, axis.z)
end)
it("converts between a quaternion and angle/axis (identity quaternion) (by component)", function()
local angle, x,y,z = quat():to_angle_axis_unpack()
assert.is.equal(0, angle)
assert.is.equal(0, x)
assert.is.equal(0, y)
assert.is.equal(1, z)
end)
it("converts between a quaternion and angle/axis (identity quaternion with fallback)", function()
local angle, axis = quat():to_angle_axis(vec3(2,3,4))
assert.is.equal(0, angle)
assert.is.equal(2, axis.x)
assert.is.equal(3, axis.y)
assert.is.equal(4, axis.z)
end)
it("gets a string representation of a quaternion", function()
local a = quat():to_string()
assert.is.equal("(+0.000,+0.000,+0.000,+1.000)", a)
end)
end)

View File

@ -1,70 +0,0 @@
local vec3 = require "modules.vec3"
local utils = require "modules.utils"
local constants = require "modules.constants"
local function tolerance(v, t)
return math.abs(v - t) < 1e-6
end
describe("utils:", function()
it("interpolates between two numbers", function()
assert.is_true(tolerance(utils.lerp(0, 1, 0.5), 0.5))
end)
it("interpolates between two vectors", function()
local a = vec3(0, 0, 0)
local b = vec3(1, 1, 1)
local c = vec3(0.5, 0.5, 0.5)
assert.is.equal(utils.lerp(a, b, 0.5), c)
a = vec3(5, 5, 5)
b = vec3(0, 0, 0)
c = vec3(2.5, 2.5, 2.5)
assert.is.equal(utils.lerp(a, b, 0.5), c)
end)
it("decays exponentially", function()
local v = utils.decay(0, 1, 0.5, 1)
assert.is_true(tolerance(v, 0.39346934028737))
end)
it("checks a nan", function()
local a = 0/0
assert.is_true(utils.is_nan(a))
end)
it("rounds a number", function()
-- round up
local v = utils.round(1.3252525, 0.01)
assert.is_true(tolerance(v, 1.33))
-- round down
v = utils.round(1.3242525, 0.1)
assert.is_true(tolerance(v, 1.3))
-- no precision
v = utils.round(1.3242525)
assert.is_true(tolerance(v, 1))
end)
it("checks sign", function()
assert.is.equal(utils.sign(-9), -1)
assert.is.equal(utils.sign(0), 0)
assert.is.equal(utils.sign(12), 1)
end)
end)
--[[
clamp(value, min, max)
deadzone(value, size)
threshold(value, threshold)
tolerance(value, threshold)
map(value, min_in, max_in, min_out, max_out)
lerp(progress, low, high)
smoothstep(progress, low, high)
wrap(value, limit)
is_pot(value)
project_on(out, a, b)
project_from(out, a, b)
mirror_on(out, a, b)
reflect(out, i, n)
refract(out, i, n, ior)
--]]

View File

@ -1,285 +0,0 @@
local vec2 = require "modules.vec2"
local DBL_EPSILON = require("modules.constants").DBL_EPSILON
local abs, sqrt = math.abs, math.sqrt
describe("vec2:", function()
it("creates an empty vector", function()
local a = vec2()
assert.is.equal(0, a.x)
assert.is.equal(0, a.y)
assert.is_true(a:is_vec2())
assert.is_true(a:is_zero())
end)
it("creates a vector from a number", function()
local a = vec2(3)
assert.is.equal(3, a.x)
assert.is.equal(3, a.y)
end)
it("creates a vector from numbers", function()
local a = vec2(3, 5)
assert.is.equal(3, a.x)
assert.is.equal(5, a.y)
end)
it("creates a vector from a list", function()
local a = vec2 { 3, 5 }
assert.is.equal(3, a.x)
assert.is.equal(5, a.y)
end)
it("creates a vector from a record", function()
local a = vec2 { x=3, y=5 }
assert.is.equal(3, a.x)
assert.is.equal(5, a.y)
end)
it("creates a vector from nan", function()
local a = vec2(0/0)
assert.is_true(a:has_nan())
end)
it("clones a vector", function()
local a = vec2(3, 5)
local b = a:clone()
assert.is.equal(a, b)
end)
it("clones a vector using the constructor", function()
local a = vec2(3, 5)
local b = vec2(a)
assert.is.equal(a, b)
end)
it("adds a vector to another", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = a:add(b)
local d = a + b
assert.is.equal(10, c.x)
assert.is.equal(9, c.y)
assert.is.equal(c, d)
end)
it("subracts a vector from another", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = a:sub(b)
local d = a - b
assert.is.equal(-4, c.x)
assert.is.equal( 1, c.y)
assert.is.equal( c, d)
end)
it("multiplies a vector by a scale factor", function()
local a = vec2(3, 5)
local s = 2
local c = a:scale(s)
local d = a * s
assert.is.equal(6, c.x)
assert.is.equal(10, c.y)
assert.is.equal(c, d)
end)
it("divides a vector by another vector", function()
local a = vec2(3, 5)
local s = vec2(2, 2)
local c = a:div(s)
local d = a / s
assert.is.equal(1.5, c.x)
assert.is.equal(2.5, c.y)
assert.is.equal(c, d)
end)
it("inverts a vector", function()
local a = vec2(3, -5)
local b = -a
assert.is.equal(-a.x, b.x)
assert.is.equal(-a.y, b.y)
end)
it("gets the length of a vector", function()
local a = vec2(3, 5)
assert.is.equal(sqrt(34), a:len())
end)
it("gets the square length of a vector", function()
local a = vec2(3, 5)
assert.is.equal(34, a:len2())
end)
it("normalizes a vector", function()
local a = vec2(3, 5)
local b = a:normalize()
assert.is_true(abs(b:len()-1) < DBL_EPSILON)
end)
it("trims the length of a vector", function()
local a = vec2(3, 5)
local b = a:trim(0.5)
assert.is_true(abs(b:len()-0.5) < DBL_EPSILON)
end)
it("gets the distance between two vectors", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = a:dist(b)
assert.is.equal(sqrt(17), c)
end)
it("gets the square distance between two vectors", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = a:dist2(b)
assert.is.equal(17, c)
end)
it("crosses two vectors", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = a:cross(b)
assert.is.equal(-23, c)
end)
it("dots two vectors", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local c = a:dot(b)
assert.is.equal(41, c)
end)
it("interpolates between two vectors", function()
local a = vec2(3, 5)
local b = vec2(7, 4)
local s = 0.1
local c = a:lerp(b, s)
assert.is.equal(3.4, c.x)
assert.is.equal(4.9, c.y)
end)
it("unpacks a vector", function()
local a = vec2(3, 5)
local x, y = a:unpack()
assert.is.equal(3, x)
assert.is.equal(5, y)
end)
it("rotates a vector", function()
local a = vec2(3, 5)
local b = a:rotate( math.pi)
local c = b:rotate(-math.pi)
assert.is_not.equal(a, b)
assert.is.equal(a, c)
end)
it("converts between polar and cartesian coordinates", function()
local a = vec2(3, 5)
local r, t = a:to_polar()
local b = vec2.from_cartesian(r, t)
assert.is_true(abs(a.x - b.x) <= DBL_EPSILON*2) -- Allow 2X epsilon error because there were 2 operations.
assert.is_true(abs(a.y - b.y) <= DBL_EPSILON*2)
end)
it("gets a perpendicular vector", function()
local a = vec2(3, 5)
local b = a:perpendicular()
assert.is.equal(-5, b.x)
assert.is.equal( 3, b.y)
end)
it("gets a string representation of a vector", function()
local a = vec2()
local b = a:to_string()
assert.is.equal("(+0.000,+0.000)", b)
end)
it("rounds a 2-vector", function()
local a = vec2(1.1,1.9):round()
assert.is.equal(a.x, 1)
assert.is.equal(a.y, 2)
end)
it("flips a 2-vector", function()
local a = vec2(1,2)
local temp = a:flip_x()
assert.is.equal(temp, vec2(-1, 2))
temp = temp:flip_y()
assert.is.equal(temp, vec2(-1, -2))
end)
it("finds angle from one 2-vector to another", function()
local d = {
right = vec2(1, 0),
down = vec2(0, -1),
left = vec2(-1, 0),
up = vec2(0, 1),
}
assert.is.equal(math.deg(d.right:angle_to(d.right)), 0.0)
assert.is.equal(math.deg(d.right:angle_to(d.down)), -90.0)
assert.is.equal(math.deg(d.right:angle_to(d.left)), 180.0)
assert.is.equal(math.deg(d.right:angle_to(d.up)), 90.0)
assert.is.equal(math.deg(d.down:angle_to(d.right)), 90.0)
assert.is.equal(math.deg(d.down:angle_to(d.down)), 0.0)
assert.is.equal(math.deg(d.down:angle_to(d.left)), -90.0)
assert.is.equal(math.deg(d.down:angle_to(d.up)), 180.0)
assert.is.equal(math.deg(d.left:angle_to(d.right)), 180.0)
assert.is.equal(math.deg(d.left:angle_to(d.down)), 90.0)
assert.is.equal(math.deg(d.left:angle_to(d.left)), 0.0)
assert.is.equal(math.deg(d.left:angle_to(d.up)), -90.0)
assert.is.equal(math.deg(d.up:angle_to(d.right)), -90.0)
assert.is.equal(math.deg(d.up:angle_to(d.down)), 180.0)
assert.is.equal(math.deg(d.up:angle_to(d.left)), 90.0)
assert.is.equal(math.deg(d.up:angle_to(d.up)), 0.0)
end)
it("finds angle between two 2-vectors", function()
local d = {
right = vec2(1, 0),
down = vec2(0, -1),
left = vec2(-1, 0),
up = vec2(0, 1),
}
assert.is.equal(math.deg(d.right:angle_between(d.right)), 0.0)
assert.is.equal(math.deg(d.right:angle_between(d.down)), 90.0)
assert.is.equal(math.deg(d.right:angle_between(d.left)), 180.0)
assert.is.equal(math.deg(d.right:angle_between(d.up)), 90.0)
assert.is.equal(math.deg(d.down:angle_between(d.right)), 90.0)
assert.is.equal(math.deg(d.down:angle_between(d.down)), 0.0)
assert.is.equal(math.deg(d.down:angle_between(d.left)), 90.0)
assert.is.equal(math.deg(d.down:angle_between(d.up)), 180.0)
assert.is.equal(math.deg(d.left:angle_between(d.right)), 180.0)
assert.is.equal(math.deg(d.left:angle_between(d.down)), 90.0)
assert.is.equal(math.deg(d.left:angle_between(d.left)), 0.0)
assert.is.equal(math.deg(d.left:angle_between(d.up)), 90.0)
assert.is.equal(math.deg(d.up:angle_between(d.right)), 90.0)
assert.is.equal(math.deg(d.up:angle_between(d.down)), 180.0)
assert.is.equal(math.deg(d.up:angle_between(d.left)), 90.0)
assert.is.equal(math.deg(d.up:angle_between(d.up)), 0.0)
end)
-- Do this last, to insulate tests from accidental state contamination
-- Do vec3 tests last, to insulate tests from accidental state contamination
it("converts a 2-vector to a 3-vector", function()
local vec3 = require "modules.vec3"
local a = vec2(1,2)
local b = a:to_vec3()
local c = a:to_vec3(3)
assert.is.equal(b, vec3(1,2,0))
assert.is.equal(c, vec3(1,2,3))
end)
it("converts a vec3 to vec2 using the constructor", function()
local vec3 = require "modules.vec3"
local a = vec2(3, 5)
local b = vec3(3, 5, 7)
local c = vec2(b)
assert.is.equal(a, c)
end)
end)

View File

@ -1,261 +0,0 @@
local vec3 = require "modules.vec3"
local DBL_EPSILON = require("modules.constants").DBL_EPSILON
local abs, sqrt = math.abs, math.sqrt
describe("vec3:", function()
it("creates an empty vector", function()
local a = vec3()
assert.is.equal(0, a.x)
assert.is.equal(0, a.y)
assert.is.equal(0, a.z)
assert.is_true(a:is_vec3())
assert.is_true(a:is_zero())
end)
it("creates a vector from a number", function()
local a = vec3(3)
assert.is.equal(3, a.x)
assert.is.equal(3, a.y)
assert.is.equal(3, a.z)
end)
it("creates a vector from numbers", function()
local a = vec3(3, 5, 7)
assert.is.equal(3, a.x)
assert.is.equal(5, a.y)
assert.is.equal(7, a.z)
end)
it("creates a vector from a list", function()
local a = vec3 { 3, 5, 7 }
assert.is.equal(3, a.x)
assert.is.equal(5, a.y)
assert.is.equal(7, a.z)
end)
it("creates a vector from a record", function()
local a = vec3 { x=3, y=5, z=7 }
assert.is.equal(3, a.x)
assert.is.equal(5, a.y)
assert.is.equal(7, a.z)
end)
it("creates a vector from nan", function()
local a = vec3(0/0)
assert.is_true(a:has_nan())
end)
it("clones a vector", function()
local a = vec3(3, 5, 7)
local b = a:clone()
assert.is.equal(a, b)
end)
it("clones a vector using the constructor", function()
local a = vec3(3, 5, 7)
local b = vec3(a)
assert.is.equal(a, b)
end)
it("adds a vector to another", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = a:add(b)
local d = a + b
assert.is.equal(10, c.x)
assert.is.equal(9, c.y)
assert.is.equal(8, c.z)
assert.is.equal(c, d)
end)
it("subracts a vector from another", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = a:sub(b)
local d = a - b
assert.is.equal(-4, c.x)
assert.is.equal( 1, c.y)
assert.is.equal( 6, c.z)
assert.is.equal( c, d)
end)
it("multiplies a vector by a scale factor", function()
local a = vec3(3, 5, 7)
local s = 2
local c = a:scale(s)
local d = a * s
assert.is.equal(6, c.x)
assert.is.equal(10, c.y)
assert.is.equal(14, c.z)
assert.is.equal(c, d)
end)
it("divides a vector by another vector", function()
local a = vec3(3, 5, 7)
local s = vec3(2, 2, 2)
local c = a:div(s)
local d = a / s
assert.is.equal(1.5, c.x)
assert.is.equal(2.5, c.y)
assert.is.equal(3.5, c.z)
assert.is.equal(c, d)
end)
it("inverts a vector", function()
local a = vec3(3, -5, 7)
local b = -a
assert.is.equal(-a.x, b.x)
assert.is.equal(-a.y, b.y)
assert.is.equal(-a.z, b.z)
end)
it("gets the length of a vector", function()
local a = vec3(3, 5, 7)
assert.is.equal(sqrt(83), a:len())
end)
it("gets the square length of a vector", function()
local a = vec3(3, 5, 7)
assert.is.equal(83, a:len2())
end)
it("normalizes a vector", function()
local a = vec3(3, 5, 7)
local b = a:normalize()
assert.is_true(abs(b:len()-1) < DBL_EPSILON)
end)
it("normalizes a vector and gets the length", function()
local a = vec3(3, 5, 7)
local b, l = a:normalize_len()
assert.is_true(abs(b:len()-1) < DBL_EPSILON)
assert.is.equal(sqrt(83), l)
end)
it("trims the length of a vector", function()
local a = vec3(3, 5, 7)
local b = a:trim(0.5)
assert.is_true(abs(b:len()-0.5) < DBL_EPSILON)
end)
it("gets the distance between two vectors", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = a:dist(b)
assert.is.equal(sqrt(53), c)
end)
it("gets the square distance between two vectors", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = a:dist2(b)
assert.is.equal(53, c)
end)
it("crosses two vectors", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = a:cross(b)
assert.is.equal(-23, c.x)
assert.is.equal( 46, c.y)
assert.is.equal(-23, c.z)
end)
it("dots two vectors", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local c = a:dot(b)
assert.is.equal(48, c)
end)
it("interpolates between two vectors", function()
local a = vec3(3, 5, 7)
local b = vec3(7, 4, 1)
local s = 0.1
local c = a:lerp(b, s)
assert.is.equal(3.4, c.x)
assert.is.equal(4.9, c.y)
assert.is.equal(6.4, c.z)
end)
it("unpacks a vector", function()
local a = vec3(3, 5, 7)
local x, y, z = a:unpack()
assert.is.equal(3, x)
assert.is.equal(5, y)
assert.is.equal(7, z)
end)
it("rotates a vector", function()
local a = vec3(3, 5, 7)
local b = a:rotate( math.pi, vec3.unit_z)
local c = b:rotate(-math.pi, vec3.unit_z)
assert.is_not.equal(a, b)
assert.is.equal(7, b.z)
assert.is.equal(a, c)
end)
it("cannot rotate a vector without a valis axis", function()
local a = vec3(3, 5, 7)
local b = a:rotate(math.pi, 0)
assert.is_equal(a, b)
end)
it("gets a perpendicular vector", function()
local a = vec3(3, 5, 7)
local b = a:perpendicular()
assert.is.equal(-5, b.x)
assert.is.equal( 3, b.y)
assert.is.equal( 0, b.z)
end)
it("gets a string representation of a vector", function()
local a = vec3()
local b = a:to_string()
assert.is.equal("(+0.000,+0.000,+0.000)", b)
end)
it("rounds a 3-vector", function()
local a = vec3(1.1,1.9,3):round()
assert.is.equal(a.x, 1)
assert.is.equal(a.y, 2)
assert.is.equal(a.z, 3)
end)
it("flips a 3-vector", function()
local a = vec3(1,2,3)
local temp = a:flip_x()
assert.is.equal(temp, vec3(-1, 2, 3))
temp = temp:flip_y()
assert.is.equal(temp, vec3(-1, -2, 3))
temp = temp:flip_z()
assert.is.equal(temp, vec3(-1, -2, -3))
end)
it("get two 3-vectors angle", function()
local angle_to = function(a, b)
local deg = math.deg(a:angle_to(b))
return string.format('%.2f', deg)
end
local a = vec3(1,2,3)
assert.is.equal(angle_to(a, vec3(3, 2, 1)), '44.42')
assert.is.equal(angle_to(a, vec3(0, 10, 0)), '57.69')
assert.is.equal(angle_to(a, vec3(0, -12, -10)), '157.51')
a = vec3.unit_z
assert.is.equal(angle_to(a, vec3(0, 10, 0)), '90.00')
assert.is.equal(angle_to(a, vec3(-123, 10, 0)), '90.00')
assert.is.equal(angle_to(a, vec3(-10, 0, 10)), '45.00')
assert.is.equal(angle_to(a, vec3(-10, 0, -10)), '135.00')
assert.is.equal(angle_to(a, vec3(0, -10, -10)), '135.00')
assert.is.equal(angle_to(a, vec3(0, 0, -10)), '180.00')
assert.is.equal(angle_to(a, vec3(0, 0, 100)), '0.00')
a = vec3(100, 100, 0)
assert.is.equal(angle_to(a, vec3(0, 0, 100)), '90.00')
assert.is.equal(angle_to(a, vec3(0, 0, -100)), '90.00')
assert.is.equal(angle_to(a, vec3(-10, -10, 0)), '180.00')
assert.is.equal(angle_to(a, vec3.unit_z), '90.00')
end)
end)