Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_graph.py1
-rw-r--r--source/blender/blenkernel/intern/fcurve.c227
-rw-r--r--source/blender/blenlib/BLI_math_easing.h78
-rw-r--r--source/blender/blenlib/CMakeLists.txt2
-rw-r--r--source/blender/blenlib/intern/math_easing.c312
-rw-r--r--source/blender/editors/animation/keyframes_edit.c133
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h1
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c21
-rw-r--r--source/blender/editors/space_graph/graph_draw.c7
-rw-r--r--source/blender/editors/space_graph/graph_edit.c66
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c2
-rw-r--r--source/blender/makesdna/DNA_curve_types.h31
-rw-r--r--source/blender/makesrna/RNA_enum_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_curve.c22
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c32
16 files changed, 895 insertions, 42 deletions
diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py
index e4fb53805b6..67fc2867536 100644
--- a/release/scripts/startup/bl_ui/space_graph.py
+++ b/release/scripts/startup/bl_ui/space_graph.py
@@ -227,6 +227,7 @@ class GRAPH_MT_key(Menu):
layout.separator()
layout.operator_menu_enum("graph.handle_type", "type", text="Handle Type")
layout.operator_menu_enum("graph.interpolation_type", "type", text="Interpolation Mode")
+ layout.operator_menu_enum("graph.easing_type", "type", text="Easing Type")
layout.separator()
layout.operator("graph.clean")
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index c6b64a112c7..e496513131f 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -45,6 +45,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_math_easing.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -2080,49 +2081,199 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
}
/* evaltime occurs within the interval defined by these two keyframes */
else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
+ const float begin = prevbezt->vec[1][1];
+ const float change = bezt->vec[1][1] - prevbezt->vec[1][1];
+ const float duration = bezt->vec[1][0] - prevbezt->vec[1][0];
+ const float time = evaltime - prevbezt->vec[1][0];
+ const float amplitude = prevbezt->amplitude;
+ const float period = prevbezt->period;
+
/* value depends on interpolation mode */
- if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES)) {
+ if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES) || (duration == 0)) {
/* constant (evaltime not relevant, so no interpolation needed) */
cvalue = prevbezt->vec[1][1];
}
- else if (prevbezt->ipo == BEZT_IPO_LIN) {
- /* linear - interpolate between values of the two keyframes */
- fac = bezt->vec[1][0] - prevbezt->vec[1][0];
-
- /* prevent division by zero */
- if (fac) {
- fac = (evaltime - prevbezt->vec[1][0]) / fac;
- cvalue = prevbezt->vec[1][1] + (fac * (bezt->vec[1][1] - prevbezt->vec[1][1]));
- }
- else {
- cvalue = prevbezt->vec[1][1];
- }
- }
else {
- /* bezier interpolation */
- /* (v1, v2) are the first keyframe and its 2nd handle */
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- v2[0] = prevbezt->vec[2][0];
- v2[1] = prevbezt->vec[2][1];
- /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
- v3[0] = bezt->vec[0][0];
- v3[1] = bezt->vec[0][1];
- v4[0] = bezt->vec[1][0];
- v4[1] = bezt->vec[1][1];
-
- /* adjust handles so that they don't overlap (forming a loop) */
- correct_bezpart(v1, v2, v3, v4);
-
- /* try to get a value for this position - if failure, try another set of points */
- b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
- if (b) {
- berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
- cvalue = opl[0];
- /* break; */
- }
- else {
- if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]);
+ switch (prevbezt->ipo) {
+ /* interpolation ...................................... */
+ case BEZT_IPO_BEZ:
+ /* bezier interpolation */
+ /* (v1, v2) are the first keyframe and its 2nd handle */
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ v2[0] = prevbezt->vec[2][0];
+ v2[1] = prevbezt->vec[2][1];
+ /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
+ v3[0] = bezt->vec[0][0];
+ v3[1] = bezt->vec[0][1];
+ v4[0] = bezt->vec[1][0];
+ v4[1] = bezt->vec[1][1];
+
+ /* adjust handles so that they don't overlap (forming a loop) */
+ correct_bezpart(v1, v2, v3, v4);
+
+ /* try to get a value for this position - if failure, try another set of points */
+ b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
+ if (b) {
+ berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
+ cvalue = opl[0];
+ /* break; */
+ }
+ else {
+ if (G.debug & G_DEBUG) printf(" ERROR: findzero() failed at %f with %f %f %f %f\n", evaltime, v1[0], v2[0], v3[0], v4[0]);
+ }
+ break;
+
+ case BEZT_IPO_LIN:
+ /* linear - simply linearly interpolate between values of the two keyframes */
+ cvalue = LinearEase(time, begin, change, duration);
+ break;
+
+ /* easing ............................................ */
+ case BEZT_IPO_BACK:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BackEaseIn(time, begin, change, duration, prevbezt->back);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BackEaseOut(time, begin, change, duration, prevbezt->back);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BackEaseInOut(time, begin, change, duration, prevbezt->back);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_BOUNCE:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = BounceEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = BounceEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = BounceEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_CIRC:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = CircEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = CircEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = CircEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_CUBIC:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = CubicEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = CubicEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = CubicEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_ELASTIC:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = ElasticEaseIn(time, begin, change, duration, amplitude, period);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = ElasticEaseOut(time, begin, change, duration, amplitude, period);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = ElasticEaseInOut(time, begin, change, duration, amplitude, period);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_EXPO:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = ExpoEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = ExpoEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = ExpoEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_QUAD:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = QuadEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = QuadEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = QuadEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_QUART:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = QuartEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = QuartEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = QuartEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_QUINT:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = QuintEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = QuintEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = QuintEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+ case BEZT_IPO_SINE:
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN:
+ cvalue = SineEaseIn(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_OUT:
+ cvalue = SineEaseOut(time, begin, change, duration);
+ break;
+ case BEZT_IPO_EASE_IN_OUT:
+ cvalue = SineEaseInOut(time, begin, change, duration);
+ break;
+ }
+ break;
+
+
+ default:
+ cvalue = prevbezt->vec[1][1];
+ break;
}
}
}
diff --git a/source/blender/blenlib/BLI_math_easing.h b/source/blender/blenlib/BLI_math_easing.h
new file mode 100644
index 00000000000..c6518491bb3
--- /dev/null
+++ b/source/blender/blenlib/BLI_math_easing.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the author nor the names of contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BLI_MATH_EASING_H__
+#define __BLI_MATH_EASING_H__
+
+/** \file BLI_math_easing.h
+ * \ingroup bli
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+float BackEaseIn(float time, float begin, float change, float duration, float overshoot);
+float BackEaseOut(float time, float begin, float change, float duration, float overshoot);
+float BackEaseInOut(float time, float begin, float change, float duration, float overshoot);
+float BounceEaseOut(float time, float begin, float change, float duration);
+float BounceEaseIn(float time, float begin, float change, float duration);
+float BounceEaseInOut(float time, float begin, float change, float duration);
+float CircEaseIn(float time, float begin, float change, float duration);
+float CircEaseOut(float time, float begin, float change, float duration);
+float CircEaseInOut(float time, float begin, float change, float duration);
+float CubicEaseIn(float time, float begin, float change, float duration);
+float CubicEaseOut(float time, float begin, float change, float duration);
+float CubicEaseInOut(float time, float begin, float change, float duration);
+float ElasticEaseIn(float time, float begin, float change, float duration, float amplitude, float period);
+float ElasticEaseOut(float time, float begin, float change, float duration, float amplitude, float period);
+float ElasticEaseInOut(float time, float begin, float change, float duration, float amplitude, float period);
+float ExpoEaseIn(float time, float begin, float change, float duration);
+float ExpoEaseOut(float time, float begin, float change, float duration);
+float ExpoEaseInOut(float time, float begin, float change, float duration);
+float LinearEase(float time, float begin, float change, float duration);
+float QuadEaseIn(float time, float begin, float change, float duration);
+float QuadEaseOut(float time, float begin, float change, float duration);
+float QuadEaseInOut(float time, float begin, float change, float duration);
+float QuartEaseIn(float time, float begin, float change, float duration);
+float QuartEaseOut(float time, float begin, float change, float duration);
+float QuartEaseInOut(float time, float begin, float change, float duration);
+float QuintEaseIn(float time, float begin, float change, float duration);
+float QuintEaseOut(float time, float begin, float change, float duration);
+float QuintEaseInOut(float time, float begin, float change, float duration);
+float SineEaseIn(float time, float begin, float change, float duration);
+float SineEaseOut(float time, float begin, float change, float duration);
+float SineEaseInOut(float time, float begin, float change, float duration);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __BLI_MATH_EASING_H__
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 9194bb5a54c..24973cece91 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -72,6 +72,7 @@ set(SRC
intern/math_color.c
intern/math_color_blend_inline.c
intern/math_color_inline.c
+ intern/math_easing.c
intern/math_geom.c
intern/math_geom_inline.c
intern/math_interp.c
@@ -141,6 +142,7 @@ set(SRC
BLI_math_base.h
BLI_math_color.h
BLI_math_color_blend.h
+ BLI_math_easing.h
BLI_math_geom.h
BLI_math_inline.h
BLI_math_interp.h
diff --git a/source/blender/blenlib/intern/math_easing.c b/source/blender/blenlib/intern/math_easing.c
new file mode 100644
index 00000000000..bec4e0b228a
--- /dev/null
+++ b/source/blender/blenlib/intern/math_easing.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright © 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the author nor the names of contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** \file blender/blenlib/intern/math_easing.c
+ * \ingroup bli
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "BLI_math_easing.h"
+
+
+float BackEaseIn(float time, float begin, float change, float duration, float overshoot)
+{
+ if (overshoot == 0)
+ overshoot = 1.70158f;
+ time /= duration;
+ return change * time * time * ((overshoot + 1) * time - overshoot) + begin;
+}
+
+float BackEaseOut(float time, float begin, float change, float duration, float overshoot)
+{
+ if (overshoot == 0)
+ overshoot = 1.70158f;
+ time = time / duration - 1;
+ return change * (time * time * ((overshoot + 1) * time + overshoot) + 1) + begin;
+}
+
+float BackEaseInOut(float time, float begin, float change, float duration, float overshoot)
+{
+ if (overshoot == 0)
+ overshoot = 1.70158f;
+ overshoot *= 1.525f;
+ if ((time /= duration / 2) < 1) {
+ return change / 2 * (time * time * ((overshoot + 1) * time - overshoot)) + begin;
+ }
+ time -= 2;
+ return change / 2 * (time * time * ((overshoot + 1) * time + overshoot) + 2) + begin;
+
+}
+
+float BounceEaseOut(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ if (time < (1 / 2.75f)) {
+ return change * (7.5625f * time * time) + begin;
+ }
+ else if (time < (2 / 2.75f)) {
+ time -= (1.5f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.75f) + begin;
+ }
+ else if (time < (2.5f / 2.75f)) {
+ time -= (2.25f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.9375f) + begin;
+ }
+ else {
+ time -= (2.625f / 2.75f);
+ return change * ((7.5625f * time) * time + .984375f) + begin;
+ }
+}
+
+float BounceEaseIn(float time, float begin, float change, float duration)
+{
+ return change - BounceEaseOut(duration - time, 0, change, duration) + begin;
+}
+
+float BounceEaseInOut(float time, float begin, float change, float duration)
+{
+ if (time < duration / 2)
+ return BounceEaseIn(time * 2, 0, change, duration) * 0.5f + begin;
+ else
+ return BounceEaseOut(time * 2 - duration, 0, change, duration) * 0.5f + change * 0.5f + begin;
+}
+
+float CircEaseIn(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return -change * (sqrt(1 - time * time) - 1) + begin;
+}
+
+float CircEaseOut(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return change * sqrt(1 - time * time) + begin;
+}
+
+float CircEaseInOut(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1)
+ return -change / 2 * (sqrt(1 - time * time) - 1) + begin;
+ time -= 2;
+ return change / 2 * (sqrt(1 - time * time) + 1) + begin;
+}
+
+float CubicEaseIn(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time * time + begin;
+}
+
+float CubicEaseOut(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return change * (time * time * time + 1) + begin;
+}
+
+float CubicEaseInOut(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1)
+ return change / 2 * time * time * time + begin;
+ time -= 2;
+ return change / 2 * (time * time * time + 2) + begin;
+}
+
+float ElasticEaseIn(float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+
+ if (time == 0)
+ return begin;
+
+ if ((time /= duration) == 1)
+ return begin + change;
+
+ if (!period)
+ period = duration * 0.3f;
+
+ if (!amplitude || amplitude < abs(change)) {
+ amplitude = change;
+ s = period / 4;
+ }
+ else
+ s = period / (2 * M_PI) * asin(change / amplitude);
+
+ time -= 1;
+ return -(amplitude * pow(2, 10 * time) * sin((time * duration - s) * (2 * M_PI) / period)) + begin;
+}
+
+float ElasticEaseOut(float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+
+ if (time == 0)
+ return begin;
+ if ((time /= duration) == 1)
+ return begin + change;
+ if (!period)
+ period = duration * 0.3f;
+ if (!amplitude || amplitude < abs(change)) {
+ amplitude = change;
+ s = period / 4;
+ }
+ else
+ s = period / (2 * M_PI) * asin(change / amplitude);
+
+ return (amplitude * pow(2, -10 * time) * sin((time * duration - s) * (2 * M_PI) / period ) + change + begin);
+}
+
+float ElasticEaseInOut(float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+
+ if (time == 0)
+ return begin;
+ if ((time /= duration / 2) == 2)
+ return begin + change;
+ if (!period)
+ period = duration * (0.3f * 1.5f);
+ if (!amplitude || amplitude < abs(change)) {
+ amplitude = change;
+ s = period / 4;
+ }
+ else
+ s = period / ( 2 * M_PI) * asin(change / amplitude);
+ if (time < 1) {
+ time -= 1;
+ return -0.5f * (amplitude * pow(2, 10 * time) * sin((time * duration - s) * (2 * M_PI) / period)) + begin;
+ }
+
+ time -= 1;
+ return amplitude * pow(2, -10 * time) * sin((time * duration - s) * (2 * M_PI) / period) * 0.5f + change + begin;
+}
+
+float ExpoEaseIn(float time, float begin, float change, float duration)
+{
+ return (time == 0) ? begin : change * pow(2, 10 * (time / duration - 1)) + begin;
+}
+
+float ExpoEaseOut(float time, float begin, float change, float duration)
+{
+ return (time == duration) ? begin + change : change * (-pow(2, -10 * time / duration) + 1) + begin;
+}
+
+float ExpoEaseInOut(float time, float begin, float change, float duration)
+{
+ if (time == 0)
+ return begin;
+ if (time == duration)
+ return begin + change;
+ if ((time /= duration / 2) < 1)
+ return change/2 * pow(2, 10 * (time - 1)) + begin;
+ --time;
+ return change / 2 * (-pow(2, -10 * time) + 2) + begin;
+}
+
+float LinearEase(float time, float begin, float change, float duration)
+{
+ return change * time / duration + begin;
+}
+
+float QuadEaseIn(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time + begin;
+}
+
+float QuadEaseOut(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return -change * time * (time - 2) + begin;
+}
+
+float QuadEaseInOut(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1)
+ return change / 2 * time * time + begin;
+ --time;
+ return -change / 2 * (time * (time - 2) - 1) + begin;
+}
+
+
+float QuartEaseIn(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time * time * time + begin;
+}
+
+float QuartEaseOut(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return -change * (time * time * time * time - 1) + begin;
+}
+
+float QuartEaseInOut(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1)
+ return change / 2 * time * time * time * time + begin;
+ time -= 2;
+ return -change/2 * ( time * time * time * time - 2) + begin;
+}
+
+float QuintEaseIn(float time, float begin, float change, float duration)
+{
+ time /= duration;
+ return change * time * time * time * time * time + begin;
+}
+float QuintEaseOut(float time, float begin, float change, float duration)
+{
+ time = time / duration - 1;
+ return change * (time * time * time * time * time + 1) + begin;
+}
+float QuintEaseInOut(float time, float begin, float change, float duration)
+{
+ if ((time /= duration / 2) < 1)
+ return change/2 * time * time * time * time * time + begin;
+ time -= 2;
+ return change / 2 * (time * time * time * time * time + 2) + begin;
+}
+
+float SineEaseIn(float time, float begin, float change, float duration)
+{
+ return -change * cos(time / duration * M_PI_2) + change + begin;
+}
+
+float SineEaseOut(float time, float begin, float change, float duration)
+{
+ return change * sin(time / duration * M_PI_2) + begin;
+}
+
+float SineEaseInOut(float time, float begin, float change, float duration)
+{
+ return -change / 2 * (cos(M_PI * time / duration) - 1) + begin;
+}
+
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 6b294c93b42..b14bbe821e8 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -922,15 +922,109 @@ static short set_bezt_bezier(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
return 0;
}
+static short set_bezt_back(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_BACK;
+ return 0;
+}
+
+static short set_bezt_bounce(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_BOUNCE;
+ return 0;
+}
+
+static short set_bezt_circle(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_CIRC;
+ return 0;
+}
+
+static short set_bezt_cubic(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_CUBIC;
+ return 0;
+}
+
+static short set_bezt_elastic(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_ELASTIC;
+ return 0;
+}
+
+static short set_bezt_expo(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_EXPO;
+ return 0;
+}
+
+static short set_bezt_quad(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUAD;
+ return 0;
+}
+
+static short set_bezt_quart(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUART;
+ return 0;
+}
+
+static short set_bezt_quint(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUINT;
+ return 0;
+}
+
+static short set_bezt_sine(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_SINE;
+ return 0;
+}
+
/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
// ANIM_editkeyframes_ipocurve_ipotype() !
KeyframeEditFunc ANIM_editkeyframes_ipo(short code)
{
switch (code) {
+ /* interpolation */
case BEZT_IPO_CONST: /* constant */
return set_bezt_constant;
case BEZT_IPO_LIN: /* linear */
return set_bezt_linear;
+
+ /* easing */
+ case BEZT_IPO_BACK:
+ return set_bezt_back;
+ case BEZT_IPO_BOUNCE:
+ return set_bezt_bounce;
+ case BEZT_IPO_CIRC:
+ return set_bezt_circle;
+ case BEZT_IPO_CUBIC:
+ return set_bezt_cubic;
+ case BEZT_IPO_ELASTIC:
+ return set_bezt_elastic;
+ case BEZT_IPO_EXPO:
+ return set_bezt_expo;
+ case BEZT_IPO_QUAD:
+ return set_bezt_quad;
+ case BEZT_IPO_QUART:
+ return set_bezt_quart;
+ case BEZT_IPO_QUINT:
+ return set_bezt_quint;
+ case BEZT_IPO_SINE:
+ return set_bezt_sine;
+
default: /* bezier */
return set_bezt_bezier;
}
@@ -985,6 +1079,45 @@ KeyframeEditFunc ANIM_editkeyframes_keytype(short code)
}
}
+/* ------- */
+
+static short set_easingtype_easein(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_IN;
+ return 0;
+}
+
+static short set_easingtype_easeout(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_OUT;
+ return 0;
+}
+
+static short set_easingtype_easeinout(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_IN_OUT;
+ return 0;
+}
+
+/* Set the easing type of the selected BezTriples in each F-Curve to the specified one */
+KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
+{
+ switch (mode) {
+ case BEZT_IPO_EASE_IN: /* ease in */
+ return set_easingtype_easein;
+
+ case BEZT_IPO_EASE_OUT: /* ease out */
+ return set_easingtype_easeout;
+
+ case BEZT_IPO_EASE_IN_OUT: /* both */
+ default:
+ return set_easingtype_easeinout;
+ }
+}
+
/* ******************************************* */
/* Selection */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 4e68b6a9494..c8365689803 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -217,6 +217,7 @@ KeyframeEditFunc ANIM_editkeyframes_select(short mode);
KeyframeEditFunc ANIM_editkeyframes_handles(short mode);
KeyframeEditFunc ANIM_editkeyframes_ipo(short mode);
KeyframeEditFunc ANIM_editkeyframes_keytype(short mode);
+KeyframeEditFunc ANIM_editkeyframes_easing(short mode);
/* -------- BezTriple Callbacks (Selection Map) ---------- */
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 42aa9935251..671a4c3afd3 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -291,7 +291,26 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa)
/* interpolation */
col = uiLayoutColumn(layout, FALSE);
uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
-
+
+ /* easing type */
+ if (bezt->ipo > BEZT_IPO_BEZ)
+ uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
+
+ /* easing extra */
+ switch (bezt->ipo) {
+ case BEZT_IPO_BACK:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
+ break;
+ case BEZT_IPO_ELASTIC:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
+ uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
+ break;
+ default:
+ break;
+ }
+
/* numerical coordinate editing
* - we use the button-versions of the calls so that we can attach special update handlers
* and unit conversion magic that cannot be achieved using a purely RNA-approach
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index ab69dc9e7b9..eb36abe6eef 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -623,6 +623,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
glPopMatrix();
}
+#if 0
/* helper func - draw one repeat of an F-Curve */
static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d)
{
@@ -778,7 +779,8 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
glEnd();
glPopMatrix();
-}
+}
+#endif
/* Debugging -------------------------------- */
@@ -995,7 +997,8 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
/* just draw curve based on defined data (i.e. no modifiers) */
if (fcu->bezt)
- draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
+ //draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d);
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid); // XXX: better to do an optimised integration here instead, but for now, this works
else if (fcu->fpt)
draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d);
}
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 93d103e11a6..0fa6edd0011 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1502,6 +1502,72 @@ void GRAPH_OT_interpolation_type(wmOperatorType *ot)
ot->prop = RNA_def_enum(ot->srna, "type", beztriple_interpolation_mode_items, 0, "Type", "");
}
+/* ******************** Set Easing Operator *********************** */
+
+static void seteasing_graph_keys(bAnimContext *ac, short mode)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditFunc set_cb = ANIM_editkeyframes_easing(mode);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting BezTriple easing
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next)
+ ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
+
+ /* cleanup */
+ BLI_freelistN(&anim_data);
+}
+
+static int graphkeys_easing_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ short mode;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
+
+ /* set handle type */
+ seteasing_graph_keys(&ac, mode);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_easing_type(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Keyframe Easing Type";
+ ot->idname = "GRAPH_OT_easing_type";
+ ot->description = "Set easing type for the F-Curve segments starting from the selected keyframes";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_easing_exec;
+ ot->poll = graphop_editable_keyframes_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", beztriple_interpolation_easing_items, 0, "Type", "");
+}
+
/* ******************** Set Handle-Type Operator *********************** */
/* this function is responsible for setting handle-type of selected keyframes */
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 567b0a60bb0..fe1378679d8 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -112,6 +112,7 @@ void GRAPH_OT_euler_filter(struct wmOperatorType *ot);
void GRAPH_OT_handle_type(struct wmOperatorType *ot);
void GRAPH_OT_interpolation_type(struct wmOperatorType *ot);
void GRAPH_OT_extrapolation_type(struct wmOperatorType *ot);
+void GRAPH_OT_easing_type(struct wmOperatorType *ot);
void GRAPH_OT_frame_jump(struct wmOperatorType *ot);
void GRAPH_OT_snap(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 0b9936ff14e..1041c885697 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -227,6 +227,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_handle_type);
WM_operatortype_append(GRAPH_OT_interpolation_type);
WM_operatortype_append(GRAPH_OT_extrapolation_type);
+ WM_operatortype_append(GRAPH_OT_easing_type);
WM_operatortype_append(GRAPH_OT_sample);
WM_operatortype_append(GRAPH_OT_bake);
WM_operatortype_append(GRAPH_OT_sound_bake);
@@ -376,6 +377,7 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "GRAPH_OT_handle_type", VKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_interpolation_type", TKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_easing_type", EKEY, KM_PRESS, KM_CTRL, 0);
/* destructive */
WM_keymap_add_item(keymap, "GRAPH_OT_clean", OKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index f0c555792fc..ebba59ec785 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -108,10 +108,19 @@ typedef struct BevPoint {
typedef struct BezTriple {
float vec[3][3];
float alfa, weight, radius; /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */
+
short ipo; /* ipo: interpolation mode for segment from this BezTriple to the next */
+
char h1, h2; /* h1, h2: the handle type of the two handles */
char f1, f2, f3; /* f1, f2, f3: used for selection status */
+
char hide; /* hide: used to indicate whether BezTriple is hidden (3D), type of keyframe (eBezTriple_KeyframeTypes) */
+
+ float back; /* BEZT_IPO_BACK */
+ float amplitude, period; /* BEZT_IPO_ELASTIC */
+ char easing; /* easing: easing type for interpolation mode (eBezTriple_Easing) */
+
+ char pad[3];
} BezTriple;
/* note; alfa location in struct is abused by Key system */
@@ -341,11 +350,31 @@ typedef enum eBezTriple_Handle {
/* interpolation modes (used only for BezTriple->ipo) */
typedef enum eBezTriple_Interpolation {
+ /* traditional interpolation */
BEZT_IPO_CONST = 0, /* constant interpolation */
BEZT_IPO_LIN = 1, /* linear interpolation */
- BEZT_IPO_BEZ = 2 /* bezier interpolation */
+ BEZT_IPO_BEZ = 2, /* bezier interpolation */
+
+ /* easing equations */
+ BEZT_IPO_BACK = 3,
+ BEZT_IPO_BOUNCE = 4,
+ BEZT_IPO_CIRC = 5,
+ BEZT_IPO_CUBIC = 6,
+ BEZT_IPO_ELASTIC = 7,
+ BEZT_IPO_EXPO = 8,
+ BEZT_IPO_QUAD = 9,
+ BEZT_IPO_QUART = 10,
+ BEZT_IPO_QUINT = 11,
+ BEZT_IPO_SINE = 12
} eBezTriple_Interpolation;
+/* easing modes (used only for Keyframes - BezTriple->easing) */
+typedef enum eBezTriple_Easing {
+ BEZT_IPO_EASE_IN = 0,
+ BEZT_IPO_EASE_OUT = 1,
+ BEZT_IPO_EASE_IN_OUT = 2
+} eBezTriple_Easing;
+
/* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */
typedef enum eBezTriple_KeyframeType {
BEZT_KEYTYPE_KEYFRAME = 0, /* default - 'proper' Keyframe */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 49ff04192b8..0b73fc932a9 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -72,6 +72,7 @@ extern EnumPropertyItem color_sets_items[];
extern EnumPropertyItem beztriple_keyframe_type_items[];
extern EnumPropertyItem beztriple_interpolation_mode_items[];
+extern EnumPropertyItem beztriple_interpolation_easing_items[];
extern EnumPropertyItem keyframe_handle_type_items[];
extern EnumPropertyItem keyblock_type_items[];
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 0c17b55d2c6..a4d099c69c7 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -34,6 +34,8 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_font.h"
#include "RNA_access.h"
@@ -67,9 +69,29 @@ EnumPropertyItem keyframe_handle_type_items[] = {
};
EnumPropertyItem beztriple_interpolation_mode_items[] = {
+ /* interpolation */
+ {0, "", 0, N_("Interpolation"), "Standard transitions between keyframes"},
{BEZT_IPO_CONST, "CONSTANT", 0, "Constant", "No interpolation, value of A gets held until B is encountered"},
{BEZT_IPO_LIN, "LINEAR", 0, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"},
{BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", "Smooth interpolation between A and B, with some control over curve shape"},
+
+ /* easing */
+ {0, "", 0, N_("Easing (by strength)"), "Predefined inertial transitions, useful for motion graphics (from least to most ''dramatic'')"},
+ {BEZT_IPO_QUAD, "QUAD", 0, "Quadratic", "Quadratic easing (weakest)"},
+ {BEZT_IPO_CUBIC, "CUBIC", 0, "Cubic", "Cubic easing"},
+ {BEZT_IPO_QUART, "QUART", 0, "Quartic", "Quartic easing"},
+ {BEZT_IPO_QUINT, "QUINT", 0, "Quintic", "Quintic easing"},
+ {BEZT_IPO_EXPO, "EXPO", 0, "Exponential", "Exponential easing (strongest)"},
+
+ {0, "", 0, N_("Dynamic Effects"), "Simple physics-inspired easing effects"},
+ {BEZT_IPO_BACK, "BACK", 0, "Back", "Cubic easing with overshoot and settle"},
+ {BEZT_IPO_BOUNCE, "BOUNCE", 0, "Bounce", "Exponentially decaying parabolic bounce, like when objects collide"},
+ {BEZT_IPO_ELASTIC, "ELASTIC", 0, "Elastic", "Exponentially decaying sine wave, like an elastic band"},
+
+ {0, "", 0, N_("Other"), "Other easing equations"},
+ {BEZT_IPO_SINE, "SINE", 0, "Sinusoidal", "Sinusoidal easing"},
+ {BEZT_IPO_CIRC, "CIRC", 0, "Circular", "Circular easing"},
+
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index aad8d6057ed..81fa2ad62a4 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include "DNA_anim_types.h"
+#include "DNA_curve_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -76,6 +77,13 @@ EnumPropertyItem beztriple_keyframe_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
+EnumPropertyItem beztriple_interpolation_easing_items[] = {
+ {BEZT_IPO_EASE_IN, "EASE_IN", 0, "Ease In", "Only on the end closest to the next keyframe"},
+ {BEZT_IPO_EASE_OUT, "EASE_OUT", 0, "Ease Out", "Only on the end closest to the first keyframe"},
+ {BEZT_IPO_EASE_IN_OUT, "EASE_IN_OUT", 0, "Ease In and Out", "Segment between both keyframes"},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
#include "WM_api.h"
@@ -1652,6 +1660,30 @@ static void rna_def_fkeyframe(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Type", "Type of keyframe (for visual purposes only)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "easing", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "easing");
+ RNA_def_property_enum_items(prop, beztriple_interpolation_easing_items);
+ RNA_def_property_ui_text(prop, "Easing",
+ "Which ends of the segment between this and the next keyframe easing "
+ "interpolation is applied to");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "back");
+ RNA_def_property_ui_text(prop, "Back", "Amount of overshoot for 'back' easing");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "amplitude");
+ RNA_def_property_ui_text(prop, "Amplitude", "Amplitude of bounces for elastic easing");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "period");
+ RNA_def_property_ui_text(prop, "Period", "Time between bounces for elastic easing");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
/* Vector values */
prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_COORDS); /* keyframes are dimensionless */
RNA_def_property_array(prop, 2);