Page MenuHome

Add variability to "Bounce" interpolation
Needs ReviewPublic

Authored by Daniel Stewart (mpc823) on Mar 31 2020, 6:00 PM.

Details

Summary

This patch adds two user definable parameters to the Bounce keyframe & Grease Pencil interpolation. It adds a parameter for "gravity" and a parameter for the "bounciness".

The "gravity" changes the force on the object, causing it to fall (or move) more quickly over the same distance. It is to simulate the actual gravity on an object. The "bounciness" changes the amount of energy an object has. It is a percentage (0.0 - 1.0 range) the object should bounce in relation to it's previous height. So a value of 50% should cause the object to bounce up to 50% of it's previous height on each bounce. The general strategy has changed from the previous implementation (see the various comments in this patch revision for details), though previously had an implementation that was a bit more similar to the previous implementation.

The original Bounce keyframe had hard-coded values which resulted in 3 bounces with a "bounciness" of 0.5. This current revision changes that to allow a more natural interaction, modifying both the gravity and bounciness and was suggested by Henrik Dick. The intention of this patch is to allow for quick, secondary animations that can get by with some fairly straightforward bouncing. The current, hard-coded values of 3 bounces didn't provide enough flexibility (at least for me) to be overly useful, but having this flexibility allows me to quickly add some bounces to background or secondary objects and I've found it useful for motion graphics in certain situations.

The way I would envision this being used (and the way I've used it) is to simply keyframe the start position of an object, move to the frame and position where the object should come to rest (or simply stop bouncing) and keyframe. The I go into the graph editor and choose the Bounce keyframe for the first keyframe. This gives a bouncing effect which can be modified with the parameters to get the desired effect.

Diff Detail

Repository
rB Blender

Event Timeline

Jacques Lucke (JacquesLucke) requested changes to this revision.Apr 21 2020, 3:57 PM

Please use clang-format before creating patches: https://wiki.blender.org/wiki/Tools/ClangFormat

There seems to be an off-by-one error with the number of bounces.

I'd expect this to have zero bounces


and this to have one bounce.

source/blender/blenlib/intern/easing.c
87

This does not compile for me on linux, because of the implicit conversion from int to float. Just use (float)i. Same below.

This revision now requires changes to proceed.Apr 21 2020, 3:57 PM

Changed the number of bounces to start at 0 instead of 1. Added a cast to allow compilation on Linux. And ran clang-format via Visual Studio.

Sergey Sharybin (sergey) requested changes to this revision.Apr 22 2020, 10:29 AM

I think there is missing code in the do_versions to keep existing files which use this feature working. Because of this marking as Requested Changes.

Personally, I feel weird about having bounce as an interpolation. Is not something I am aware of animators actually use and, if anything, it should have been done as a modifier. From all attempts to use it for anything it always behaves weirdly.

@Sybren A. Stüvel (sybren) , do you mind making a call here? Think you have more bigger picture overview.

This revision now requires changes to proceed.Apr 22 2020, 10:29 AM

Also not keen on this.

I tried using this patch and found the settings difficult to control usefully.

I'd rather have this kind of feature in f-curve modifiers.

I'll look at the do_versions, as I wasn't aware of that.

As far as usefulness, I'm surprised at that. At it's defaults, it behaves the same as it otherwise would. But given the requests for this feature when the bounciness interpolation was first added, I thought making the bounce interpolation as adjustable as the other Robert Penner interpolations would be advantageous to animators looking for quick background/secondary motion. (Which I've used myself.) It seemed that perhaps the only reason it wasn't adjustable was because the original instantiation was hard-coded and no one took the time to make it adjustable. I personally find having the adjustments available make the bounce interpolation more useful.

Added do_version support.

But I've realized I have no idea where the Grease Pencil Interpolation code is. I've searched the codebase numerous times and can't find where it actually makes the UI for the GP interpolation strokes. So although the core code appears to be there for adding parameters to bounciness, I don't know where in the code to make it actually show up in the UI. Any pointers would be greatly appreciated.

Daniel Stewart (mpc823) edited the summary of this revision. (Show Details)

Added the "num_bounces" and "bounciness" to the UI for Grease Pencil Interpolation.

I am unable to apply this patch to master on Windows.

Sybren A. Stüvel (sybren) requested changes to this revision.Jun 18 2020, 11:37 AM

I think this is a nice feature to have.

The interpolation type can be set per key, so I don't see how this functionality could be moved to an FCurve modifier. Unless the entire FCurve would get the same bouncyness, or unless the FCurve can keep track of parameters per key, that is, and I'm not a fan of either.

There are already properties to influence the elasticity of an elastic interpolation, so I don't see why this would be objectionable for bounce interpolation.

source/blender/blenlib/intern/easing.c
73

Don't use single-letter variables.

78

This changes time from actual time (which I assume is in frames) to a percentage of time. This should not be done with the same variable.

80–81

"width", "increment", and "interval" all mean the same thing: a space between two numbers. Please choose names that reflect their meaning better.

What is the difference between "interval" and "total_interval"? Why is the width expressed in squared units? Or is the rest also the result of squaring, but because 1.0² = 1.0 this is invisible?

85

It's rather unclear what this expression means, and why the loop can stop here. Also, what is here inside the if body is exactly what is executed after the for loop, so instead of repeating the code you could just use a break statement here.

87

This expression is quite complex now, and also has some unneeded parentheses. At least remove the ones around (width * time), as it actually hides the fact that time is squared here. I know, this was also used in the previous code, and no I'm not happy about that either.

It's also copied below, which is also not a good idea. If code is to be reused, place it in a function and call that from both places.

source/blender/blenloader/intern/versioning_280.c
753–754 ↗(On Diff #24501)

No need to declare everything at the top.

754 ↗(On Diff #24501)

Don't use single-letter variables.

1678 ↗(On Diff #24501)

2.90 should not be handled before 2.83, and probably also not in versioning_280.c.

There is an (almost) empty code block at the end of the function marked "Versioning code until next subversion bump goes here." Just put the versioning code there, and when a new version bump happens someone will take care of putting it in the right place.

source/blender/makesrna/intern/rna_fcurve.c
2080

If this is a percentage, replace PROP_NONE with PROP_PERCENTAGE so that it actually shows as a percentage in the UI.

2083

"should have" is inappropriately hedging. "Percentage of the energy that is passed from each bounce to the next" would be better.

This revision now requires changes to proceed.Jun 18 2020, 11:37 AM
source/blender/blenlib/intern/easing.c
78

Yes, this is the percentage of time. I'll add a new variable.

80–81

The width is essentially the coefficient (m) in the parabolic expression of y = m * x^2 + c. It so happens that the coefficient m can be expressed in this manner. I'll try to simplify this calculation and add some comments explaining the calculation. Essentially, the code is simply finding which parabola to calculate and then calculating the value at the current time position.

85

I'm refactoring to avoid the iterative loop.

87

I'm refactoring this code to not perform the calculations iteratively. This should simplify the code a bit and remove the extra calculation outside of the loop. The downside is the calculations appear a bit complicated, using log() and pow() functions to determine which "bounce" (parabola) should be calculated.

source/blender/makesrna/intern/rna_fcurve.c
2080

Thanks for telling me about that. I didn't realize the use of PROP_PERCENTAGE.

Removed iterative approach to calculating the bounces. Moved the versioning support to the versioning_290.c file.

Daniel Stewart (mpc823) marked 7 inline comments as done.

This addresses the comments made concerning the previous patch. I refactored the code such that I no longer use an iterative process to determine which bounce we are calculating nor how high the bounce should be. Moved the versioning code to versioning_290.c (hopefully in the right spot!).

I'm also not too fond of the way the bounces scale with the sliders and the keyframes. I setup a desmos graph with this function to play with it. I also added a function that I think could be more intuitive based on constant gravity.
https://www.desmos.com/calculator/h9eehcsdv8

you can slide the points around in the graph and see the immediate response.

Love the graphical interpretation of the equations - didn't know about desmos. Looks like there is essentially a tradeoff between either keeping the gravity constant in the proposed scheme or specifying the exact number of bounces in the current scheme. In the constant gravity scheme the last bounce may not be quite right as it has to be cut short in order to correctly fill the space, which may lead to odd-looking animations. On the other hand, a constant number of bounces leads to widely different gravity between two objects if you add another bounce to one of them. In either case, one would have to adjust the second keyframe in order to get the correct look.

I'm open to either approach. I'd be interested to hear what other animators thought the best approach was.

Love the graphical interpretation of the equations - didn't know about desmos. Looks like there is essentially a tradeoff between either keeping the gravity constant in the proposed scheme or specifying the exact number of bounces in the current scheme. In the constant gravity scheme the last bounce may not be quite right as it has to be cut short in order to correctly fill the space, which may lead to odd-looking animations. On the other hand, a constant number of bounces leads to widely different gravity between two objects if you add another bounce to one of them. In either case, one would have to adjust the second keyframe in order to get the correct look.

I'm open to either approach. I'd be interested to hear what other animators thought the best approach was.

Please overlook my ignorance if your comment about a tradeoff is meant to indicate that the two are mutually exclusive, but is it possible to let the user choose between a constant gravity and a defined number of bounces? If both can be done, I would prefer being able to choose either one if doing a bounce animation.

Unfortunately, the 2 approaches are mutually exclusive. You can see this more clearly if you go to the link Henrik provided and play with the "Bounciness" parameter. In one approach the number of bounces is fixed, and thus the gravity is adjusted to compensate. In the other approach the gravity is fixed and the number of bounces (and the size of the last bounce) is adjusted to compensate.

Thinking about why I originally wrote this patch and what I was trying to accomplish, I am actually leaning towards Henrik's approach. I didn't like the original, fixed 3 bounces because it ended too soon and looked odd. (I was looking at motion graphics as opposed to some physical ball.) So I wanted more bounces to play with. But in either case I would have to adjust something to get a more realistic animation. I tend to think Henrik's approach is more applicable across a wider range of animation types, because it fixes that first bounce position and because the last bounce is still somewhat believable.

Perhaps I'll try to create a patch with both approaches to test out inside Blender. I wouldn't be in favor of trying to have both approaches inside Blender as it makes this more complicated than it needs to be for the kind of thing it is trying to accomplish.

But I'm still interested in getting opinions about what others may find useful.

Thank you, Daniel. I did go to the desmos page and adjusted things prior to writing my message, and what I noticed was that it does indeed give two different results. That is exactly why I inquired about having both. If one could have a checkbox for 'Gravity Based', or (if no checkbox is allowed) even two bounce interpolations listed in the menu that has the other interpolation types, with one bounce-interpolation indicating that it is gravity based, and the other indicating that it is fixed by number of bounces, then this would give the user who has two set keyframes the option to see two different bounce options for the interpolation. What I saw from the desmos page is more options that me or another user could have at the disposal for a bounce interpolation type. If the work has already been done, why keep that from the user? I am not sure that it is safe to assume that everyone would always want the same type of bounce interpolation. Animation is often about what looks good, and in some cases, that may be a gravity-based interpolation, and in others, setting the number of bounces might be preferable to the animator.

@Paul Larson (GeorgiaPacific) The gravity based approach can reach any interpolation of the number based approach. Or in other words the set of curves that the gravity based approach has includes the set of curves of the number based approach.
That means if you have the gravity based curve, then there is no point in having the other, except for a different tweak feeling when setting the values, which is not worth the UI clutter
Also remember it is a rarely used feature, because you can just animate your bounce with a few bezier curves with free handles pointing a bit up and thats always more flexible.
Please don't insist on it further.

@Daniel Stewart (mpc823) I simplified the formula for the gravity bounce. I will post a new desmos graph when I am finished, so you can use that for reference when coding, if you decide that's the way to go.

@Paul Larson (GeorgiaPacific) The gravity based approach can reach any interpolation of the number based approach. Or in other words the set of curves that the gravity based approach has includes the set of curves of the number based approach.
That means if you have the gravity based curve, then there is no point in having the other, except for a different tweak feeling when setting the values, which is not worth the UI clutter
Also remember it is a rarely used feature, because you can just animate your bounce with a few bezier curves with free handles pointing a bit up and thats always more flexible.
Please don't insist on it further.

@Daniel Stewart (mpc823) I simplified the formula for the gravity bounce. I will post a new desmos graph when I am finished, so you can use that for reference when coding, if you decide that's the way to go.

Hello, Henrick! That just shows my ignorance. I am sorry for taking so much developer time and ask for you to overlook my doing so. Thank you for the clarification and for explaining it to me!

@Daniel Stewart (mpc823) I simplified the formula for the gravity bounce. I will post a new desmos graph when I am finished, so you can use that for reference when coding, if you decide that's the way to go.

That'd be great, Henrik! It will make coding this up much easier.

Henrik Dick (weasel) added a comment.EditedOct 8 2020, 1:47 AM

I did it. Here is the new graph with just the gravity solution.
https://www.desmos.com/calculator/1jqqwtt5tv (updated)

I dropped the unnecessary limits on the bounciness. The only thing left out in the graph are the trivial cases with b=1 and b=-1.
I would propose a ui range of bounciness from -1 or 0 to 1 and no hard limit range, so you can type in different values if you want.
Gravity would need to be >= 0 with a hard lower limit, but no hard upper limit.

I also wanted to mention, that if the right keyframe is far enough then with this solution the ball in fact bounces infinitly many times before settling, which I think is beautiful math.

@Daniel Stewart (mpc823) Could you update the patch description and include some screenshots & a description of how the feature would work from an animator's perspective?

Daniel Stewart (mpc823) edited the summary of this revision. (Show Details)Oct 17 2020, 3:23 PM

Here is the latest patch which implements a gravity-based method instead of a fixed number of bounces. It was suggested by Henrik Dick. There are still some issues I'm not sure how to address.

  1. Backwards compatibility. With this new method, in order to load old blender files and still have them behave the same, the gravity and bounciness would need to be adjusted for every single keyframe that has the Bounce keyframe applied. This would require access not only to the current keyframe, but the following keyframe as well. This was not an issue with the previous "fixed-bounce" approach, as older files could simply have a bounciness of 0.5 and a fixed number of 3 bounces applied.
  1. Grease Pencil does not seem to be working the way it used to work with the interpolation. I think I may need to play with this more, but I find it harder to adjust things using the grease pencil interpolation.

I'd appreciate thoughts and comments as to this "gravity-based" approach and the previous "fixed-bounce" approach.

Fixed missing files.

Looking at the Grease Pencil stuff some more, it appears that when I try to make two keyframes spread out in time and moving an object in-between, the duration is always 1.0. I'm not sure how this will work with the gravity approach. There will never be enough space to have any bounces. Currently the Grease Pencil interpolation just calls into the standard easing function. My previous approach did not have this issue because there was always a defined number of bounces.

Perhaps more discussion is needed on the various approaches. But I would like something which has more knobs than the current, hard-coded approach.

@Antonio Vazquez (antoniov) you want to add something to the grease pencil interpolation discussion? Always interpolating with a duration of 1.0 seems strange. That also affects the elastic dynamic effect with the period option (but that also has the problem that the defaults are both 0.0).