Add control over spring solver step

This commit is contained in:
aaron 2023-08-26 14:59:19 +01:00
parent 5ab76a434e
commit 38f8e8d9c5
2 changed files with 39 additions and 29 deletions

View file

@ -2,7 +2,7 @@
## spring()
Returns a new source with a dynamically animated value of the input source.
Returns a new source with a value always moving torwards the input source value.
- **Type**
@ -13,19 +13,19 @@ Returns a new source with a dynamically animated value of the input source.
damping_ratio: number = 1
): () -> T
type Animatable = number | CFrame | Color3 | UDim | UDim2 | Vector2 | Vector3
type Animatable = number | CFrame | Color3 | UDim | UDim2 | Vector2 | Vector3 | Rect
```
- **Details**
The output source value is updated every frame based on the input source
The output source value is updated every step based on the input source
value.
The output is physically simulated according to a
The movement is physically simulated according to a
[spring](https://en.wikipedia.org/wiki/Simple_harmonic_motion).
`period` is the amount of time in seconds it takes for the spring to
complete one full oscillation.
complete one full cycle if undamped.
`damping_ratio` is the amount of resistance applied to the spring.
@ -34,4 +34,8 @@ Returns a new source with a dynamically animated value of the input source.
- <1 = Underdamped - reaches target with some overshoot.
- 0 = Undamped - never stabilizes, oscillates forever.
Velocity is conserved between source updates for smooth animation.
By default, the spring solver is ran at 120 Hz in
[`Heartbeat`](https://create.roblox.com/docs/reference/engine/classes/RunService#Heartbeat).
You can change when the solver runs by calling `vide.step(dt)`, which will
advance the simulation time by `dt` seconds and automatically stop the
solver running in heartbeat.

View file

@ -20,6 +20,31 @@ local flags = require(script.flags)
export type Source<T> = source.Source<T>
local function step(dt: number)
if game then
debug.profilebegin("VIDE STEP")
debug.profilebegin("VIDE SPRING")
end
update_springs(dt)
if game then
debug.profileend()
debug.profilebegin("VIDE GARBAGE CLEANUP")
end
clean_garbage()
if game then
debug.profileend()
debug.profileend()
end
end
local stepped = game and game:GetService("RunService").Heartbeat:Connect(function(dt: number)
task.defer(step, dt)
end)
local vide = {
-- core
create = create,
@ -52,24 +77,11 @@ local vide = {
-- runtime
step = function(dt: number)
if game then
debug.profilebegin("VIDE STEP")
debug.profilebegin("VIDE SPRING")
end
update_springs(dt)
if game then
debug.profileend()
debug.profilebegin("VIDE GARBAGE CLEANUP")
end
clean_garbage()
if game then
debug.profileend()
debug.profileend()
if stepped then
stepped:Disconnect()
stepped = nil
end
step(dt)
end
}
@ -97,10 +109,4 @@ do
})
end
if game then
game:GetService("RunService").Heartbeat:Connect(function(dt: number)
task.defer(vide.step, dt)
end)
end
return vide