Robert Penner easing equasions for f-curves
Closed, ResolvedPublic

Description

This adds a few more interpolation types aside from constant, linear, and bezier to the interpolation mode menu, a new sub-menu in the graph editor 'Key' menu, one new operator (GRAPH_OT_easing_type) and a couple extra properties to the python 'Keyframe' object.

The (optional) extra parameters for Back and Elastic don't have a UI method to set them but they can be set through python.

Threw in a cheezy animated gif demoing the bounce, circle and elastic functions.

Details

Type
Patch

Quick code review:
1) Code organisation: yuck!
In C, we do NOT implement functions in headers. That is a bad C++ practice.

If you must, you could include this as a separate C file. However, a better alternative would be to just add within fcurve.c, like

/* ******************************* */
<... license info ...>

<... code ...>
/* ******************************* */

(see math libs in blenlib, and also dual quaternion stuff in blenkernel/intern/armature.c for examples of code that's been included like this)

2) Division by zero errors - it seems that these are likely to occur. Duration between keyframes CAN get quite small in some cases (i.e. if user turned off time snapping and moved keyframes quite close to each other unintentionally). Be careful about this.

3) Small nitpick - try to follow the existing code styles around these areas a bit (with regards to brackets/braces), thanks.

----

Functionality:
Currently, the relationship between easing and interpolation is not immediately clear. Could you please include a user-level description of the functionality provided by this patch too, including basic info on usage. Next time, it'd be nice to have such a summary at the start of the patch description so that it's easier for everybody to get on the same page regarding the functionality :)

Also the interpolation types could probably do with some descriptions, since some of these appear quite cryptic (e.g. "Quart" and "Quint"?!). Names like "Expo" and "Quad" probably should be written out in full (e.g. "Exponential" and "Quadratic") for the UI; see RNA guidelines for more info.


Probably after seeing this, we can better evaluate how to present those other parameters for "Back" and "Elastic". It'd be nice to try and present this via familiar 'handle' widgets like for Bezier curves. Probably it is even possible to derive the needed values from the lengths or relative positions of these handles from the keyframes as needed? Or perhaps there are also other nicer possibilities. I would personally prefer though that we try and keep this as visual as possible (i.e. avoid resorting to just showing a few number fields where users have to guess the numeric values, especially not as an operator popup too, or restricting this to being python-backend only since this is something that all artists should be able to have direct and easy control over).

---

If you can make these changes, then we can try and get some user testing going on this. This certainly looks like useful functionality for speeding up the animation workflow, in particular for "motion-graphics" types, so it'd be great to see this in action.

Cheers!

Ok, fixed it up a bit.

1. took the functions out of the header but left them in their own file because they may be useful somewhere else later like maybe with the 'easing operator' someone is bound to eventually write or wrapped up in python goodness.

2. the most obvious case already had a check (duration == 0) and I'm pretty sure that the only other one I could find (time and/or begin == 0) can't lead to divide by zero


Changed the names to reflect the underlying function -- not that it makes it much clearer though...WTF is a quintic? Aside from providing the mathematical formula don't know what else can be done about that.

Maybe it would be better to just have the Exponential function take an extra parameter that tells it how many times to square it?

For access to the extra function parameters for "Back" and "Elastic" I'm thinking that the 'N' property pane needs to have an 'Active Key' panel that is similar to the already existing 'Active F-Curve' section. Easy enough to do in python (once the animation API is a bit more stable) and tacked on to space_graph.py.

Setting the in/out and interpolation function using the menu is a bit clunky where an N-key panel would have all the settings with a click and a glance.

There's a website http://ianhaigh.com/easeandwizz/ (with fancy videos even) that shows end usage of these that explains it a *lot* better than I ever could.

Missed an #include in the last patch.

Also added in a property sub-panel for "Active Key" (which is really just the first selected one it finds) to demonstrate what I was saying about property access.

...and a screenshot of the new sub-panel.

Getting the curves to display properly (screenshot) was amazingly easy so another quick update.

Think this is functionally complete now.

Comments on the Drawing Updates:
I was going to ask about this earlier, but I'm glad that you've picked up that it's needed. However, the way that you've implemented it now will only work in simple test cases where the first keyframe already uses one of the new interpolation modes. If you can't find any easier way, we might just resort to always sampling the curves, though this carries performance consequences for general cases.

Comments on the Active Key Panel:
- While you're doing this, you could add numeric inputs for the other two handles (if they're used) too, since it appears that animators still like to manually tweak these directly.
- Also, to test if a keyframe is selected, you could use the BEZSELECTED(bezt) macro instead of (bezt->f1 || bezt->f2 || bezt->f3)
- While it might be nice to have a true 'active keyframe', I think just taking the first selected might be sufficient for now. Doing any more there can be left for a later date.

Ok, got this thing finished I hope.

Added a flag to draw the (pretty) easing curves or to default to the (bland) bezier curves.

Added context sensitivity in the 'Active Key' panel and also inputs for the handles and control point.

Sorry, that flag is a really ugly hack (usability wise). This is an example of something that users should not have to worry about explicitly.

What is all that +/- 11.272 stuff about? Where does it come from, and why is it needed?

The code for checking the previous keyframe (for Active Key -> Handle 1) is dangerous. What you've got there should fail when called on the first keyframe (i.e. bezt-- = who knows what!).

Removed the offending code and fixed the pointer math issue.

Hi,

Just thought I'd give a status update on this FYI.

Due to the delicate state of the Durian pipeline at this stage, I'm somewhat reluctant to push such radical changes into trunk at this stage. Probably will have to wait till after Durian.

Also, just committed a active-key panel based on the one in the patch here. Thanks.

Updated the patch to reflect the new active-key panel in trunk.

Updated for current svn (42717)

Ok, a quick updated code review to see if we can get this into trunk :)

------------

1) It appears that the operator to set easing mode works on a per-keyframe basis? If that's the case, it needs to go in the Key menu not the Channels menu

2) There are a few code formatting quirks that should be resolved before this goes into trunk (though I could fix this up later/post commit as well).
a) Switch statement formatting
b) Brace placement on function-level for fcurve_easing.c
c) Line 408 of patch - keep the existing code style there! i.e. Explicitly surround each case there.
See http://aligorith.blogspot.com/2011/12/avoiding-degenerative-coding-practices.html

3) ANIM_editkeyframes_easing() - double check the comments beside each case ;)

4) Line 451 of patch (BEZT_IPO_BEZ eval case) - why the break statement inside the if here. IMO it's redundant and just confuses matters.

5) Ideally it'd be nice to see if we could hack up some optimised interpolation for drawing routines instead of relying on the curve sampling method for drawing everything. This approach does have some downsides, such as some aliasing issues arising from sampling frequency vs drawing everything that we didn't have in the past for the common bezier-interpolation case that the majority of animators use. However, in the interests of not complicating things and just having a sane reference implementation for now, we'll just go with what's there :)

---------

In response to earlier comments
- Ah, I see the check for duration==0 now. Cool, that should be fine now I guess :)

Thanks @Joshua Leung (aligorith) for noticing me - It seems that is exactly what I searched for!

As we assumed @Joshua Leung (aligorith) this patch didn't work in master anymore, so I manually added all changes to a clean master and diff'ed it. This is the newest patch.

I'm still testing it but here are already a few things I think about it:

  1. It's great for motion graphics work and adds many features I am doing manually atm
  2. If this makes it to trunk we should consider adding control points for the generated curves - many things are quite there, but I need some manual tweaking (with handles) still.
  3. Can't say something codwise as my PC just started working again and I wanted to share the patch, but I will!

Apart from that I will keep testing it now to look for more optimizations and better UI - but it is of great help already.
And last but not least: Thanks @Dan Eicher (dna) for the initial implementation - I love this feature already!

Greetings, Thomas

I would love to see this get integrated into Blender.

Thanks for the heads up plasmasolutions I really miss this kind of automation when adding detail in a limited time. It really saves me lots of clicking. However I would appreciate some KF handles and a variable for bounce (number of rebounds for example).

Very useful for motion graphics and animated infographics. I really hope this will soon be added to a main Blender release, or at least become available as an add-on, if possible.

As David mentioned, an input option for the number of bounces would be great.

I find this feature handy and a great time saver. I look forward to seeing it added into the release.

WOW! How it did take 4 years to come to life? Thank you so much @Thomas Beck (plasmasolutions) for recovering and updating this great patch! I've been doing this bounce effect by hand for a long time! You can't imagine how it will help me in my work.

@Paulo José Oliveira Amaro (pauloup) :) You're welcome,... but the real work is now starting. After the release @Joshua Leung (aligorith), @Dan Eicher (dna) and me have to find the best possible way to implement that in Blender - I really hope that we will find a way to make that happen.
@Joshua Leung (aligorith) what is the next step we should take here?

Greetings, Thomas

@Thomas Beck (plasmasolutions): I guess we shall start with a code review of the patch :) In recent months, I've also been considering whether to set up a temporary "animation staging branch" to test and prepare a few pending patches.

  1. The "Easing Mode" menu entry in space_graph.py would be better in the keyframes menu. That's because, just like with the interpolation settings, it's a per-keyframe setting instead of a whole-curve thing (which extrapolation is).
  2. Looking at this again now, it seems that the easing code (fcurve_easing.c/h) should probably go into blenlib instead of blenkernel. That's because it doesn't actually touch any specific Blender data structures; the code is simply called from other code as if they were library functions (like most of the math library functions). In fact, we may as well call that module BLI_math_easing or something similar?
  3. The formatting in the editors code (i.e. "mode= RNA_..." should become "mode = RNA_...") needs some tidying up for the new style guides
  4. Some tooltips on the ease in/out properties would be good. Currently IMO it doesn't seem entirely obvious at times which one of these you'd want/need to use...

@david mcsween (davidmcsween): As always, having visual "in-place" controls always beats having just numeric fields to edit. However, coming up with a suitable design for these and then integrating these with the rest of the transform system here (EEK!) is not exactly a trivial feat. I'd consider this as a bit of a nice add-on/followup patch for this, once we get it in.

@Joshua Leung (aligorith) I agree on all your points and I will talk with @Dan Eicher (dna) about wether he likes to alter the code. If he does not, I will. Especially since we can now show tooltips in enums it should help new users a lot if we got meaningful tooltips there.

As I prepare some speed measuring website for Brecht for the Cycles CPU optimization task and writing a comprehensive handbook about Blender atm, I will work some hours a week on it, so don't expect immeditate updates in a day or so... but as the release is at least 3 weeks away and this feature won't make it into 2.70 we'll have enough time to tackle those minor issues.

I agree on your follow up idea too. Let's get this in first and then make it even nicer :)

@Thomas Beck (plasmasolutions), I'm very excited, but I'll be patient. I'm sure all of you will do a great job for this feature! :-)
About the tooltips, I think some icons also could help to make easier the recognition. Simple icons created just to spread the idea:

@Paulo José Oliveira Amaro (pauloup) Great icons! I like them very much and will use them once I will work on this...

Hi guys,

I've unsubscribed from the discussion, but my interest in the plug-in is still as great as before. Keep up the good work, and I'm eagerly awaiting the Blender implementation!

Thanks,

Metin

I didn't know that tooltips could have icons? Could you select the type of curve in place from the icon list?

@david mcsween (davidmcsween): Tooltips cannot have icons. Menus/dropdowns however can.

@david mcsween (davidmcsween), my suggestion was to add icons to Set Key Interpolation menu (trigged by pressing "T"). Something like that:


The same options would be showed in Interpolation menu from N panel, if I'm understanding correctly.

@Thomas Beck (plasmasolutions), thank you! :-) When you need the SVG, just tell me.

With 2.70 now frozen and about to be released, and development opening up again, I'd like to look into getting this into master within the next week or so (barring any major distractions which may crop up) :)

@Joshua Leung (aligorith), Great news Joshua! Are you willing to look into features like "bounce count", "manual adjustment handles" and things like this before merging it? Or do you like to get it in and then improve it?

Greetings, Thomas

Manual adjustment handles and icons will have to wait till after the merge. From the looks of things, bounce count is somewhat baked into the code.

Joshua Leung (aligorith) closed this task as Resolved.Mar 21 2014, 3:08 PM

Hi all,

I've just committed this patch to master (daccaa713b6e66af4b958fa373b31d557a4caa33). Congrats to Dan and Thomas for all the work they've put in to getting this to this stage!

I ended up making a few formatting tweaks, tooltips, and a few other things (like some variable shadowing that was going on).

@Paulo José Oliveira Amaro (pauloup): It'd be nice to get a copy of that svg (or even better, a patch which adds icon support for these) :)

Hi @Joshua Leung (aligorith) : I don't know how to make a patch, and I could give you the svg file right now, but I think I could help in making the icons that are actually needed. The icons I did they was just to show the idea and they may be not enough.

Tell me exactly what icons are needed and I'll create them. And what is better, to create them in the actuall blender icons file or in a separated svg?

@Joshua Leung (aligorith), I would like to know exactly which icons are needed so I can create them, if you still need them.

@Paulo José Oliveira Amaro (pauloup) : Ah, thanks for the reminder. I've added a separate design task for this discussion. See T39855