修正时间轴末帧,导出补阶跃与循环段边界关键帧
- 时间轴:末帧按时长实际覆盖的整数帧计算,修掉 Spine 时长小数舍入多出的一帧,B 端与回放自动停在最后一帧 - 导出:粒子死亡、骨骼池复用、拖尾假死复活处统一写 curve: stepped 硬切,避免死区插值出滑动轨迹 - 导出:循环持续在开始/循环/结束段边界(如 30f/110f)对所有动画通道补关键帧,便于在 Spine 中直接拆分 - 精简器支持阶跃段,阶跃区间内不再补出过渡关键帧 - 补充 test:spine-json 回归用例:骨骼池复用阶跃边界、循环段边界
This commit is contained in:
1 parent
f249c019bc
commit
d6232c9d66
9 files changed
+290
-82
No files matched your search
@@ -1,5 +1,27 @@
|
||||
export type PlaybackRange = { start: number; end: number }
|
||||
|
||||
/**
|
||||
* 动画时长允许的舍入误差(秒)。
|
||||
* Spine 等来源把 80 帧在 30fps 下的时长写成 2.667(保留小数),
|
||||
* 乘回 fps 会得到 80.01 帧。误差必须小于一帧,仅用于吸收这种舍入。
|
||||
*/
|
||||
const DURATION_ROUNDING_TOLERANCE_SECONDS = 1e-3
|
||||
|
||||
/**
|
||||
* 把一段时长换算成时间轴上的“末帧索引”。
|
||||
*
|
||||
* 末帧索引 = 该时长实际覆盖到的最后一个整数帧,因此:
|
||||
* 80 帧的时长 → 末帧 80(而不是 81)。若直接对秒数×fps 取 ceil,
|
||||
* Spine 的小数舍入会让 80 帧被算成 81 帧,回放时末帧后多停一帧。
|
||||
* 这里改用向下取整,并对接近整数帧的舍入误差做补偿。
|
||||
*/
|
||||
export function lastFrameOfDuration(seconds: number, fps: number) {
|
||||
const safeFps = Math.max(1, Number(fps) || 30)
|
||||
const durationSeconds = Math.max(0, Number(seconds) || 0)
|
||||
const frames = durationSeconds * safeFps + DURATION_ROUNDING_TOLERANCE_SECONDS * safeFps
|
||||
return Math.max(0, Math.floor(frames))
|
||||
}
|
||||
|
||||
export function normalizePlaybackRange(start: unknown, end: unknown, totalFrames: number): PlaybackRange {
|
||||
const last = Math.max(1, Math.floor(totalFrames) - 1)
|
||||
const safeStart = Math.min(last - 1, Math.max(0, Math.floor(Number(start) || 0)))
|
||||
|
||||
Reference in new issue
Block a user