Update spring solver

This commit is contained in:
Aaron Smith 2023-08-24 18:09:40 +01:00
parent fdc72a17f0
commit 8ef2d0b190
5 changed files with 280 additions and 120 deletions

View file

@ -256,6 +256,40 @@ local Vector2 = { __type = "Vector2" } :: any do
end
end
local Vector3 = { __type = "Vector3" } :: any do
local function new(x, y, z)
return setmetatable({ X = x, Y = y, Z = z }, Vector3)
end
function Vector3.new(x, y, z)
return new(x or 0, y or 0, z or 0)
end
function Vector3.__add(a, b)
return new(a.X + b.X, a.Y + b.Y, a.Z + b.Z)
end
function Vector3.__sub(a, b)
return new(a.X - b.X, a.Y - b.Y, a.Z - b.Z)
end
function Vector3.__mul(a, b)
return new(a.X * b, a.Y * b, a.Z * b)
end
function Vector3.__unm(v)
return new(-v.X, -v.Y, -v.Z)
end
function Vector3.__eq(a, b)
return a.X == b.X and a.Y == b.Y
end
function Vector3.__index(v)
return (v.X^2 + v.Y^2 + v.Z^2)^0.5
end
end
local UDim2 = { __type = "UDim2" } :: any do
function UDim2.new(sx, ox, sy, oy)
return table_to_proxy(setmetatable({ x = { scale = sx, offset = ox }, y = { scale = sy, offset = oy } }, UDim2))
@ -294,8 +328,8 @@ return {
Signal = Signal,
Instance = Instance :: typeof(Instance),
Color3 = Color3 :: typeof(Color3),
Vector3 = Vector3 :: typeof(Vector3),
Vector2 = Vector2 :: typeof(Vector2),
Vector3 = Vector3 :: typeof(Vector3),
UDim2 = UDim2 :: typeof(UDim2),
Enum = Enum :: typeof(Enum),
typeof = typeof :: typeof(typeof)

71
test/spring-test.luau Normal file
View file

@ -0,0 +1,71 @@
local vide = require "src/init"
local testkit = require("test/testkit")
local program_time = os.clock()
local function step(): number
local FPS = 60
local DT = 1/FPS
repeat until os.clock() - program_time >= DT
program_time += DT
return DT
end
local function main()
local source = vide.source
local spring = vide.spring
local watch = vide.watch
local TERMINAL_HEIGHT = 73 --* REDUCE IF BAR DOES NOT FIT IN TERMINAL
local MIN_ALPHA = 0.3
local MAX_ALPHA = 0.7
local MIN = TERMINAL_HEIGHT * MIN_ALPHA
local MAX = TERMINAL_HEIGHT * MAX_ALPHA
local OFFSET = TERMINAL_HEIGHT - MAX
local BLOCK = ""
local function remainder_to_block(x)
return
if x > 7/8 then ""
elseif x > 6/8 then ""
elseif x > 5/8 then ""
elseif x > 4/8 then ""
elseif x > 3/8 then ""
elseif x > 2/8 then ""
elseif x > 1/8 then ""
else ""
end
local value = source(MAX)
local sprung = spring(value, 1, 0.3)
watch(function()
local v = sprung()
local fv = math.floor(v)
local reset = "\27[H\27[2J" -- ANSI clear terminal
local offset = string.rep("\n", MAX - fv + OFFSET)
local bar = testkit.color.gray(remainder_to_block(v - fv) .. "\n" .. string.rep(BLOCK .. "\n", fv))
print(reset .. offset .. bar)
end)
local elapsed = 0
repeat local dt = step()
vide.step(dt)
local T = 3
elapsed += dt
while elapsed >= T do
elapsed -= T
value(value() == MAX and MIN or MAX)
end
until false
end
main()

View file

@ -1240,7 +1240,7 @@ TEST("spring()", function()
input(1)
vide.step(0.05)
CHECK(output() ~= input()) -- check spring is moving
vide.step(6) -- spring finished, should be internally removed from queue
vide.step(10) -- spring finished, should be internally removed from queue
CHECK(output() == input()) -- check spring is at target
local count = -1
@ -1250,13 +1250,13 @@ TEST("spring()", function()
end)
vide.step(1) -- attempt to cause another spring update
CHECK(count == 1) -- check no update occurs as spring is finished
CHECK(count == 0) -- check no update occurs as spring is finished
--
gc() -- perform full gc
input(2) -- spring should be re-added to spring queue
vide.step(0) -- process spring queue
CHECK(count == 2) -- check spring was rescheduled correctly
CHECK(count == 1) -- check spring was rescheduled correctly
end
end)