CNA-GAP-042: CUBICSPLINE bone and node channels are replayed linearly between samples taken at least every 1/60 s, an approximation of the authored curve
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 3b43bd86; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
BuildTrack samples each CUBICSPLINE interval at least every 1/60 s and AnimationPlayer lerps/slerps between the samples, so the curve between samples is approximated.
- Identifier
CNA-GAP-042- Category
- Functional gap
- Subsystem
- Models & glTF
- Status
- Narrowed (partially fixed; describes only what survives)
- Verified against
- CNA
3b43bd86(3b43bd8687ed46523d873f9bec4b32bd8481dcb5) - Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- AnimationPlayer and SkinnedModelEXT playback of glTF clips with CUBICSPLINE interpolation
Expected behaviour
glTF CUBICSPLINE channels define a Hermite curve between keys, which a player is expected to evaluate.
Actual behaviour at TARGET
BuildTrack in GltfImportCore.cpp resamples a bone's channels onto the union of their key times and, since a9d378c06, also samples every CUBICSPLINE interval at least every 1/60 s (four samples at the least) and adds a hold key 10 µs before each STEP key, each evaluated with the channel's own mode. SampleTrack in AnimationPlayer.cpp still interpolates linearly (Slerp for rotation) between those samples, so a CUBICSPLINE curve is piecewise-linear between samples rather than evaluated. gltf-limitations.md records the result: anim-cubicspline plays within 0.0021 units of its spline (it was 0.962 off), “a bound for that fixture, not a universal one, because authored tangents may bend a spline more sharply”. Morph-weight tracks keep their tangents and are evaluated as Hermite curves.
The dense sampling is CNA's fix for CNA-DEMOS-ISSUE-031 (STEP and CUBICSPLINE playing as LINEAR), which CNA closed on a complete checkpoint (6c8b042c4, 2026-10-24); the approximation between samples is what remains.
Source locations
modules/content/src/GltfImport/GltfImportCore.cpp— BuildTrack: union-of-key-times resamplingmodules/graphics/src/Xna/AnimationPlayer.cpp— SampleTrack: Lerp/Slerp between keysdocs/gltf-limitations.md— resampling row with the measured error
Evidence
Checked by reading at 3b43bd86; not executed. The error figures are CNA's own measurements on its anim-cubicspline fixture.
Re-verified at c6dec91f: a9d378c06 (CNA-DEMOS-ISSUE-031) added kStepHold and kCubicSpacing (1/60 s) sampling to BuildTrack and two linear-playback sampling tests; AnimationPlayer playback is unchanged. CNA_DEMOS_REPAIR_MATRIX.json lists ISSUE-031 as PENDING_VERIFICATION. Not executed.
Re-verified at 3b43bd86: GltfImportCore.cpp, AnimationPlayer.cpp and gltf-limitations.md are unchanged; CNA_DEMOS_REPAIR_MATRIX.json lists ISSUE-031 as FIXED_VALIDATED (accepted at a9d378c06). Not executed.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
GltfAnimationSamplingTests.cpp now plays STEP and CUBICSPLINE tracks linearly and checks the held step and the spline within its tolerance; GltfAnimationRobustnessTests.cpp covers resampling. No test bounds the between-sample error of an arbitrary, sharply bent spline.
Regression test
If Hermite playback is added, a mid-sample assertion on a sharply bent spline (large authored tangents), where the 1/60 s sampling still deviates.
Blast radius
Clips authored with CUBICSPLINE and large tangents (sharp overshoot or easing within one 1/60 s interval); typical clips play within CNA's measured bound, and LINEAR clips are unaffected.
Workaround
Bake animations densely at export time.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- Deep dives
- Skinning and animation: clips
- Known issues
- Functional gap index