mirror of
https://github.com/centau/vide.git
synced 2026-10-20 17:34:08 +00:00
Fix springs not finishing when moving to zero (#98)
This commit is contained in:
parent
b010497a01
commit
86dee3c87c
2 changed files with 37 additions and 2 deletions
|
|
@ -10,6 +10,7 @@ local push_scope_as_child_of = graph.push_scope_as_child_of
|
||||||
|
|
||||||
local UPDATE_RATE = 120
|
local UPDATE_RATE = 120
|
||||||
local TOLERANCE_FACTOR = 10_000
|
local TOLERANCE_FACTOR = 10_000
|
||||||
|
local MIN_TOLERANCE = vector.create(1e-6, 1e-6, 1e-6)
|
||||||
|
|
||||||
type Animatable = number | CFrame | Color3 | UDim | UDim2 | Vector2 | Vector3
|
type Animatable = number | CFrame | Color3 | UDim | UDim2 | Vector2 | Vector3
|
||||||
|
|
||||||
|
|
@ -170,6 +171,7 @@ local function spring<T>(source: () -> T, period: number?, damping_ratio: number
|
||||||
|
|
||||||
local function updater_effect()
|
local function updater_effect()
|
||||||
local value = source()
|
local value = source()
|
||||||
|
data.x0_123, data.x0_456 = data.x_123, data.x_456
|
||||||
data.x1_123, data.x1_456 = type_to_vec6[typeof(value)](value)
|
data.x1_123, data.x1_456 = type_to_vec6[typeof(value)](value)
|
||||||
data.source_value = value
|
data.source_value = value
|
||||||
springs[data] = output
|
springs[data] = output
|
||||||
|
|
@ -219,6 +221,7 @@ local function spring<T>(source: () -> T, period: number?, damping_ratio: number
|
||||||
-- set current position to value
|
-- set current position to value
|
||||||
local v = ... :: T
|
local v = ... :: T
|
||||||
data.x_123, data.x_456 = type_to_vec6[typeof(v)](v)
|
data.x_123, data.x_456 = type_to_vec6[typeof(v)](v)
|
||||||
|
data.x0_123, data.x0_456 = data.x_123, data.x_456
|
||||||
|
|
||||||
-- reset velocity
|
-- reset velocity
|
||||||
data.v_123 = vector.zero
|
data.v_123 = vector.zero
|
||||||
|
|
@ -246,6 +249,12 @@ local function get_min_vector_step(direction: vector): vector
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- relative to the distance travelled, with a floor so springs can still settle at zero and large goals
|
||||||
|
local function get_tolerance(x0: vector, x1: vector): vector
|
||||||
|
local distance = vector.max(vector.abs(x0 - x1), vector.abs(x1))
|
||||||
|
return vector.max(get_min_vector_step(distance), MIN_TOLERANCE)
|
||||||
|
end
|
||||||
|
|
||||||
local function step_springs(dt: number)
|
local function step_springs(dt: number)
|
||||||
for s in springs do
|
for s in springs do
|
||||||
local k = s.k
|
local k = s.k
|
||||||
|
|
@ -290,8 +299,8 @@ local function update_spring_sources()
|
||||||
local x1_123, x1_456 = data.x1_123, data.x1_456
|
local x1_123, x1_456 = data.x1_123, data.x1_456
|
||||||
local v_123, v_456 = data.v_123, data.v_456
|
local v_123, v_456 = data.v_123, data.v_456
|
||||||
|
|
||||||
local tol_123 = vector.abs(get_min_vector_step(x0_123 - x1_123))
|
local tol_123 = get_tolerance(x0_123, x1_123)
|
||||||
local tol_456 = vector.abs(get_min_vector_step(x0_456 - x1_456))
|
local tol_456 = get_tolerance(x0_456, x1_456)
|
||||||
|
|
||||||
if
|
if
|
||||||
-- position is at goal (within tolerance)
|
-- position is at goal (within tolerance)
|
||||||
|
|
|
||||||
|
|
@ -2121,6 +2121,32 @@ TEST("spring()", wrap_root(function()
|
||||||
CHECK(count == 1) -- check spring was rescheduled correctly
|
CHECK(count == 1) -- check spring was rescheduled correctly
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do CASE "spring finished at zero"
|
||||||
|
local input = source(1)
|
||||||
|
local output, control = spring(input)
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
effect(function()
|
||||||
|
output()
|
||||||
|
count += 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
input(0)
|
||||||
|
step(10)
|
||||||
|
CHECK(output() == 0)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
step(1)
|
||||||
|
CHECK(count == 0) -- check spring is finished
|
||||||
|
|
||||||
|
control { impulse = 1 }
|
||||||
|
step(10)
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
step(1)
|
||||||
|
CHECK(count == 0) -- check spring is finished after impulse at rest
|
||||||
|
end
|
||||||
|
|
||||||
do CASE "spring control"
|
do CASE "spring control"
|
||||||
local input = source(1)
|
local input = source(1)
|
||||||
local output, control = spring(input)
|
local output, control = spring(input)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue