Currently, babylon.js supports cubic hermite and step interpolation in animations.
The cubic hermite interpolation takes a number as a tangent value as a parameter, while the cubic bazier takes a 2D vector value, meaning that not only the tangent but also the length of the vector is involved in the interpolation.
Most 3D software now supports cubic beziers in animation. This means that you will need to implement cubic bezier interpolation to properly load animation assets from other software. For personal reasons, I need a cubic bezier to load animation data from the MMD into the Animation container in babylon.js.
The animation I’m dealing with is 3 minutes long and has thousands of tracks, so sampling it is not feasible.
I’m going to force the animation to support cubic bezier via an implementation that overrides an internal function,
and also provide a sampling method,
and a way to convert only the tangent values of the cubic bezier to cubic hermite parameters.
However, I’ve already overridden several internal functions and would like to avoid this risky approach if possible. so if I add the cubic bezier feature as a PR in babylon.js, will that be accepted? Or is this a useless add-on that would just increase the bundle size?
If the community is positive about this feature at all, I’d like to implement it.
By itself, I think it’s always good to have a new feature, as long as it is not a perf / memory usage regression for existing code.
But for this one I’m not really sure, because even if we add this support, it will be difficult for users to leverage it because it’s not used by any file format we support: you will have to create your own animation data by code. So, I fear that the feature won’t really be used (except by you!), but once it’s in Babylon we would have to support it forever…
First, there was a slight misunderstanding in our conversation: it is possible to implement a cubic hermite to receive a weighted tangent, and in the end, this gives the same degrees of freedom as a cubic bezier. What I’m essentially asking for is any interpolation method that has the same degrees of freedom as cubic bezier.
and it’s hard to agree that cubic bezier interpolation is an uncommon method. The various software I’ve used all support tangents with weights (a.k.a. 2d vector tangents).
In the case of AfterEffects, the tangent is also represented as a 2D vector, so we can assume that it will use either a cubic bezier or a cubic hermite that takes a weight.
And as you said, backward compatibility is very important in babylon.js and performance is also sensitive,
so I think we need to have enough discussions and the right people to implement such an important feature like adding an animation interpolation method (and there are many people in babylon.js who are much more professional than me),
so for the above reasons, I appeal to the need for this feature.
and it’s hard to agree that cubic bezier interpolation is an uncommon method
I don’t think I said that? I said that among the file formats we support for import, none support Bezier curves.
So, for most of the users, they won’t be able to use the feature because only a few fraction of people will be able to create their animation tracks by code.
But I do agree that the feature by itself could be good to have.
That’s why I cc @sebavan on this topic, and I should probably also cc @Deltakosh, who is the mastermind behind the current animation system!
I am puzzled by this thread. I understand the point that no-one puts this on their export files. This could be implemented outside an import context though. I have my own animation system, mostly build right into my base Mesh class. I interpolate everything right in JS, except base finger bone matrices. Importing animation is stupid, IMO.
I also did some minor stealing of all those methods BJS uses to smooth out in-between animations, Easing, and made each of them one of my own Pace sub-classes with only minor arg switches (maybe cannot remember back to 2014).
Here is one which looks to me could be fashioned to work without the framework adding anything.
export class BezierCurvePace extends Pace {
constructor(public x1: number= 0, public y1: number= 0, public x2: number= 1, public y2: number= 1, mode = Pace.MODE_IN) {
super(mode);
}
/** @override */
protected _compute(currentDurationRatio : number): number {
return BABYLON.BezierCurve.Interpolate(currentDurationRatio, this.x1, this.y1, this.x2, this.y2);
}
public getClassName(): string { return "BezierCurvePace"; }
}
Just call BABYLON.BezierCurve.Interpolate() somewhere.
I am not opposed to it as long as there are some easy way to export/import it. If not it becomes a feature only for your local system and in this case I would be more open to allow any kind of interpolation from external code. By this I mean you could provide the framework with what you are currently overriding. And when this gets more traction/tooling we can easily integrate back your overrides in the code.
I’ve thought about having babylon.js provide an interface to allow users to implement custom interpolations themselves.
However, it seems difficult for the Animation Curve Editor to provide a UI for custom interpolation, so it seems better to embed bezier in babylon.js to support full functionality.
Which implementation do you think would be better?
I typically fall into the camp of needing to import animations through glTF so while I am authoring animation with cubic bezier in Maya, I typically have to bake my animation frames to keep the authored intention of the animation as passing through our exporter to glTF I tend to have not-great interpretation of the timeline. I get that in a super long animation baking frames can become very heavy in terms of file size, but this is the current limitation of glTF and so I need to make that tradeoff.
Maybe its a chicken and egg problem, bc dcc tools wont export if no consumers and no consumer going to account for it when parsing to scene format if noone exporting it.
@PatrickRyanAnimation.setEasingFunction applies a specific easing function to every keyframe, and if you apply a bezier to it, you can perform the bezier with a fixed tangent parameter for every frame.
The cubic bezier interpolation support here means that each keyframe can have a 2D vector as its tangent value, allowing for different shapes of bezier interpolation for each keyframe.
I think a glTF extension would be best, but it would have to be an official extension, otherwise it won’t be implemented by the DCC tools. And if it’s not supported by the DCC tools, there won’t be an easy way to generate content using it…
I’m late to the party, but I’m not sure I’m following the thread well.
Babylon.js supports cubic spline interpolation in Hermite form. This form is more or less interchangeable with Bezier because it is easy to convert between the two forms.
Regardless of which form the cubic spline takes in the code / serialized data, the editing of the spline is the same in the UI and depends on the user experience.
glTF is not required to store 1/3 tangent lengths. I’m not sure where the information from the answer comes from.
Given what I said, I can’t see a reason why we need another form to store cubic splines in a glTF extension. glTF tries to store only one way to make it easier on the runtime to load.
cubic hermite and bezier are interchangeable, but this is only possible when the cubic hermite is a weighted tangent. Currently, the cubic hermite interpolation in babylon.js does not support taking the weight (a.k.a. length of vector) of a tangent.
I don’t think there’s any real difference in functionality between handling beziers or supporting hermite interpolation for weighted tangents.