CLOSES #1590, CLOSES #1592, CLOSES #1625, CLOSES #1657, CLOSES #1698, CLOSES #1699, CLOSES #1700, CLOSES #1843, CLOSES #1875, CLOSES #1898, CLOSES #1902, CLOSES #1905, CLOSES #1906, CLOSES #1907, CLOSES #1908, CLOSES #1909, CLOSES #1912, CLOSES #1915, CLOSES #1917, CLOSES #1919, CLOSES #1920, CLOSES #1921, CLOSES #1922, CLOSES #1923, CLOSES #1924, CLOSES #1925, CLOSES #1926, CLOSES #1927

This commit is contained in:
bryanthaboi
2026-08-29 06:59:38 -04:00
parent 71200f21dc
commit 36ad59bdbb
116 changed files with 6157 additions and 426 deletions
+44 -1
View File
@@ -22,11 +22,37 @@ local STEP_EPS = 1 / 60 * 0.02
-- warps go through Transition instead (issue #487).
local RESEED_PHASE = 0.5
FixedStep.refreshPeriod = nil
local PHASE_PROBE = 600
local function phaseOffset(period, step)
local residuals, seen, accum = {}, {}, 0
for _ = 1, PHASE_PROBE do
accum = accum + period
while accum >= step - STEP_EPS do accum = accum - step end
local key = math.floor(accum / step * 1e6 + 0.5)
if seen[key] then break end
seen[key] = true
residuals[#residuals + 1] = accum
end
if #residuals == 0 then return 0 end
table.sort(residuals)
local bestGap, bestCentre = -1, 0
for i = 1, #residuals do
local a = residuals[i]
local b = (i < #residuals) and residuals[i + 1] or (residuals[1] + step)
if b - a > bestGap then bestGap, bestCentre = b - a, (a + b) * 0.5 end
end
return (step - bestCentre) % step
end
function FixedStep:init(callback)
self.accum = 0
self.callback = callback
self.suppressCatchup = false
self.dtHistory, self.dtSum = nil, 0
self.phasedFor = nil
end
-- The anti-spiral clamp doubles as a steps-per-frame ceiling (0.25s = 15
@@ -48,7 +74,19 @@ function FixedStep:update(dt)
self.callback(self.STEP)
return
end
if dt > 0 and dt <= SMOOTH_MAX then
local period = self.refreshPeriod
local snapped = false
if period and dt > 0 then
local frames = math.floor(dt / period + 0.5)
if frames >= 1 and frames * period <= SMOOTH_MAX
and math.abs(frames * period - dt) < period * 0.25 then
dt = frames * period
snapped = true
end
end
if snapped then
self.dtHistory, self.dtSum = nil, 0
elseif dt > 0 and dt <= SMOOTH_MAX then
local hist = self.dtHistory
if not hist then hist = {}; self.dtHistory = hist; self.dtSum = 0 end
hist[#hist + 1] = dt
@@ -61,6 +99,11 @@ function FixedStep:update(dt)
else
self.dtHistory, self.dtSum = nil, 0
end
if period and self.phasedFor ~= period then
self.phasedFor = period
local target = phaseOffset(period, self.STEP)
self.accum = self.accum - self.accum % self.STEP + target
end
self.accum = math.min(self.accum + dt, self.maxAccum or MAX_ACCUM)
while self.accum >= self.STEP - STEP_EPS do
self.accum = self.accum - self.STEP