KhronosGroup / glTF

glTF – Runtime 3D Asset Delivery
Other
7.05k stars 1.13k forks source link

[Clarification] Convert bezier to cubic spline #1778

Open jjcasmar opened 4 years ago

jjcasmar commented 4 years ago

Hi,

in some 3d design software (Blender) and in some 3d engines, animation data use bezier keyframes. These keyframes basically consist on the sampled value (time and value) and two handles (time and value)

Consider how this fcurve change when I modify the left handle value of a keyframe: image

image

glTF supports cubic splines, but they can't represent all the space spanned by bezier curves; in particular, a glTF cubic spline consist on a timestamp, a value and two tangents, 4 degrees of freedom, while bezier support up to 6 keyframes (3 timestamps, and 3 values).

How should we convert from bezier to cubicsplines and viceversa? A clarification about this may be useful in the spec.

scurest commented 4 years ago

Labeling the graph like this

out

You can convert glTF to this form with (notation is from Appendix C)

W0 = (tk, vk)
W1 = ((2/3) tk + (1/3) tk+1, vk + (1/3) m0)
W2 = ((1/3) tk + (2/3) tk+1, vk+1 - (1/3) m1)
W3 = (tk+1, vk+1)

Sympy proof of this (assuming I understand what Blender is doing correctly).

jjcasmar commented 4 years ago

If I understand correctly, you have matched the expression of both curves (cubic hermite spline and bezier curve) and found the equivalence of the control points, no?

Actually I have this same result when I implement Kuesa importer.

It would be nice to have this equivalences in an implementation note, and also some implementation note on how we should convert from bezier to glTF (completely related with the glTF-Blender-IO issue I also opened)

Thanks for having a look @scurest

bghgary commented 4 years ago

I believe there are ways to convert between the different forms of a cubic spline, but is that the intent of this issue?

The question about the time part of the input is addressed in an implementation note in the spec:

Under the https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations section:

Implementation Note: Animations with non-linear time inputs, such as time warps in Autodesk 3ds Max or Maya, are not directly representable with glTF animations. glTF is a runtime format and non-linear time inputs are expensive to compute at runtime. Exporter implementations should sample a non-linear time animation into linear inputs and outputs for an accurate representation.

mrlooi commented 4 years ago

Is there a way to include inTangentWeights and outTangentWeights for GLTF export? Otherwise we would have to stick to default 2/3 and 1/3 respectively

jo-chemla commented 2 months ago

Animations with non-linear time inputs, such as time warps in Autodesk 3ds Max or Maya, are not directly representable with glTF animations

Thanks for this excerpt of the gltf-spec as well as the note regarding the rule of constraining keyframes handles timings to 1/3-2/3 of the interval for bezier<-> cubic-spline equivalence. See another discussion for bezier support within gltf and blender thread with the same thirds rule conclusion.

Is support for bezier curve within gltf something that could be added as an extension rather than the core spec? Which would means DCC/tools that do support bezier could import real keyframed props values and handles rather than interpolate curve values between keyframes for every frame.