Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clarification] Convert bezier to cubic spline #1778

Open
jjcasmar opened this issue Mar 4, 2020 · 5 comments
Open

[Clarification] Convert bezier to cubic spline #1778

jjcasmar opened this issue Mar 4, 2020 · 5 comments

Comments

@jjcasmar
Copy link

jjcasmar commented Mar 4, 2020

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
Copy link

scurest commented Mar 5, 2020

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
Copy link
Author

jjcasmar commented Mar 5, 2020

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
Copy link
Contributor

bghgary commented Mar 6, 2020

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
Copy link

mrlooi commented Mar 8, 2020

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
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants