sampling.test.js 1.83 KB
import { describe, it, expect } from 'vitest'
import { sampleProp, clipPhase, sampleClip, blendOffset } from '../src/sampling.js'

describe('sampling 关键帧采样', () => {
  const keys = [{ t: 0, drot: 0 }, { t: 0.5, drot: 10 }, { t: 1, drot: 30 }]

  it('sampleProp 前/中/后/单帧取值', () => {
    expect(sampleProp([], 0.5, 'drot')).toBe(0) // 空 → 默认
    expect(sampleProp(keys, -0.1, 'drot')).toBe(0) // 前夹首帧
    expect(sampleProp(keys, 1.5, 'drot')).toBe(30) // 后夹末帧
    expect(sampleProp(keys, 0.25, 'drot')).toBeCloseTo(5, 9) // 区间内线性
    expect(sampleProp(keys, 0.75, 'drot')).toBeCloseTo(20, 9)
    expect(sampleProp([{ t: 0, drot: 7 }], 0.9, 'drot')).toBe(7) // 单帧
  })

  it('未给属性回落默认(dscale=1)', () => {
    expect(sampleProp(keys, 0.5, 'dscale')).toBe(1)
    expect(sampleProp(keys, 0.5, 'dx')).toBe(0)
  })

  it('clipPhase:pose=0、loop 取模、oneshot 夹 1', () => {
    expect(clipPhase({ kind: 'pose', duration: 0 }, 999)).toBe(0)
    expect(clipPhase({ kind: 'loop', duration: 1000 }, 1500)).toBeCloseTo(0.5, 9)
    expect(clipPhase({ kind: 'oneshot', duration: 400 }, 600)).toBe(1)
    expect(clipPhase({ kind: 'oneshot', duration: 400 }, 200)).toBeCloseTo(0.5, 9)
  })

  it('sampleClip 输出每根 bone 的四属性', () => {
    const clip = { kind: 'loop', duration: 100, bones: { head: keys } }
    const out = sampleClip(clip, 50) // phase=0.5 → 命中 t=0.5 关键帧 drot=10
    expect(out.head).toEqual({ drot: 10, dx: 0, dy: 0, dscale: 1 })
  })

  it('blendOffset 权重 0/0.5/1', () => {
    const a = { drot: 0, dx: 0, dy: 0, dscale: 1 }
    const b = { drot: 10, dx: 4, dy: -2, dscale: 2 }
    expect(blendOffset(a, b, 0)).toEqual(a)
    expect(blendOffset(a, b, 1)).toEqual(b)
    expect(blendOffset(a, b, 0.5)).toEqual({ drot: 5, dx: 2, dy: -1, dscale: 1.5 })
  })
})