Page Menu
Home
Search
Configure Global Search
Log In
Files
F10963
easing.diff
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Dan Eicher (dna)
Nov 13 2013, 2:19 PM
Size
32 KB
Subscribers
None
easing.diff
View Options
Index: release/scripts/ui/space_graph.py
===================================================================
--- release/scripts/ui/space_graph.py (revision 28267)
+++ release/scripts/ui/space_graph.py (working copy)
@@ -180,6 +180,7 @@
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.extrapolation_type", "type", text="Extrapolation Mode")
+ layout.operator_menu_enum("graph.easing_type", "type", text="Easing Mode")
layout.separator()
layout.operator("graph.clean")
Index: source/blender/blenkernel/intern/fcurve_easing.h
===================================================================
--- source/blender/blenkernel/intern/fcurve_easing.h (revision 0)
+++ source/blender/blenkernel/intern/fcurve_easing.h (revision 0)
@@ -0,0 +1,285 @@
+/*
+ * 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 FCURVE_EASING_H
+#define FCURVE_EASING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <math.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;
+}
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // FCURVE_EASING_H
Index: source/blender/blenkernel/intern/fcurve.c
===================================================================
--- source/blender/blenkernel/intern/fcurve.c (revision 28267)
+++ source/blender/blenkernel/intern/fcurve.c (working copy)
@@ -53,6 +53,8 @@
#include "RNA_access.h"
+#include "fcurve_easing.h"
+
#ifndef DISABLE_PYTHON
#include "BPY_extern.h"
#endif
@@ -1610,7 +1612,6 @@
}
#endif
-
/* -------------------------- */
/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
@@ -1749,49 +1750,234 @@
/* evaltime occurs within the interval defined by these two keyframes */
else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime))
{
+ float begin = prevbezt->vec[1][1];
+ float change = bezt->vec[1][1] - prevbezt->vec[1][1];
+ float duration = bezt->vec[1][0] - prevbezt->vec[1][0];
+ float time = evaltime - prevbezt->vec[1][0];
+
/* 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]));
+ return prevbezt->vec[1][1];
+
+ switch (prevbezt->ipo) {
+ case BEZT_IPO_LIN:
+ {
+ cvalue = LinearEase(time, begin, change, duration);
+ break;
}
- 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];
+ 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;
+ }
break;
}
+ 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_CIRCLE:
+ {
+ 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:
+ {
+ float a = prevbezt->amplitude;
+ float p = prevbezt->period;
+ switch (prevbezt->easing) {
+ case BEZT_IPO_EASE_IN: {
+ cvalue = ElasticEaseIn(time, begin, change, duration, a, p);
+ break;
+ }
+ case BEZT_IPO_EASE_OUT: {
+ cvalue = ElasticEaseOut(time, begin, change, duration, a, p);
+ break;
+ }
+ case BEZT_IPO_EASE_IN_OUT: {
+ cvalue = ElasticEaseInOut(time, begin, change, duration, a, p);
+ 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];
+ }
}
}
}
Index: source/blender/makesdna/DNA_curve_types.h
===================================================================
--- source/blender/makesdna/DNA_curve_types.h (revision 28267)
+++ source/blender/makesdna/DNA_curve_types.h (working copy)
@@ -104,10 +104,14 @@
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) */
+ 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 */
@@ -308,8 +312,24 @@
BEZT_IPO_CONST = 0, /* constant interpolation */
BEZT_IPO_LIN, /* linear interpolation */
BEZT_IPO_BEZ, /* bezier interpolation */
+ BEZT_IPO_BACK,
+ BEZT_IPO_BOUNCE,
+ BEZT_IPO_CIRCLE,
+ BEZT_IPO_CUBIC,
+ BEZT_IPO_ELASTIC,
+ BEZT_IPO_EXPO,
+ BEZT_IPO_QUAD,
+ BEZT_IPO_QUART,
+ BEZT_IPO_QUINT,
+ BEZT_IPO_SINE,
} eBezTriple_Interpolation;
+typedef enum eBezTriple_Easing {
+ BEZT_IPO_EASE_IN = 0,
+ BEZT_IPO_EASE_OUT,
+ BEZT_IPO_EASE_IN_OUT,
+} 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 */
Index: source/blender/makesrna/intern/rna_curve.c
===================================================================
--- source/blender/makesrna/intern/rna_curve.c (revision 28267)
+++ source/blender/makesrna/intern/rna_curve.c (working copy)
@@ -47,6 +47,16 @@
{BEZT_IPO_CONST, "CONSTANT", 0, "Constant", ""},
{BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""},
{BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""},
+ {BEZT_IPO_BACK, "BACK", 0, "Back", ""},
+ {BEZT_IPO_BOUNCE, "BOUNCE", 0, "Bounce", ""},
+ {BEZT_IPO_CIRCLE, "CIRCLE", 0, "Circle", ""},
+ {BEZT_IPO_CUBIC, "CUBIC", 0, "Cubic", ""},
+ {BEZT_IPO_ELASTIC, "ELASTIC", 0, "Elastic", ""},
+ {BEZT_IPO_EXPO, "EXPO", 0, "Expo", ""},
+ {BEZT_IPO_QUAD, "QUAD", 0, "Quad", ""},
+ {BEZT_IPO_QUART, "QUART", 0, "Quart", ""},
+ {BEZT_IPO_QUINT, "QUINT", 0, "Quint", ""},
+ {BEZT_IPO_SINE, "SINE", 0, "Sine", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem curve_type_items[] = {
Index: source/blender/makesrna/intern/rna_fcurve.c
===================================================================
--- source/blender/makesrna/intern/rna_fcurve.c (revision 28267)
+++ source/blender/makesrna/intern/rna_fcurve.c (working copy)
@@ -33,6 +33,7 @@
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_curve_types.h"
#include "MEM_guardedalloc.h"
@@ -64,6 +65,12 @@
{BEZT_KEYTYPE_EXTREME, "EXTREME", 0, "Extreme", ""},
{0, NULL, 0, NULL, NULL}};
+EnumPropertyItem beztriple_interpolation_easing_items[] = {
+ {BEZT_IPO_EASE_IN, "EASE_IN", 0, "Ease in", ""},
+ {BEZT_IPO_EASE_OUT, "EASE_OUT", 0, "Ease out", ""},
+ {BEZT_IPO_EASE_IN_OUT, "EASE_IN_OUT", 0, "Ease in and out", ""},
+ {0, NULL, 0, NULL, NULL}};
+
#ifdef RNA_RUNTIME
#include "WM_api.h"
@@ -1210,6 +1217,27 @@
RNA_def_property_ui_text(prop, "Type", "The type of keyframe");
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", "The easing type");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "back", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "back");
+ RNA_def_property_ui_text(prop, "Back", "Back overshoot amount");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "amplitude");
+ RNA_def_property_ui_text(prop, "Amplitude", "Elastic amplitude");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "period", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "period");
+ RNA_def_property_ui_text(prop, "Period", "Elastic period");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
/* Vector values */
prop= RNA_def_property(srna, "handle1", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_array(prop, 2);
Index: source/blender/makesrna/RNA_enum_types.h
===================================================================
--- source/blender/makesrna/RNA_enum_types.h (revision 28267)
+++ source/blender/makesrna/RNA_enum_types.h (working copy)
@@ -53,6 +53,7 @@
extern EnumPropertyItem beztriple_keyframe_type_items[];
extern EnumPropertyItem beztriple_handle_type_items[];
extern EnumPropertyItem beztriple_interpolation_mode_items[];
+extern EnumPropertyItem beztriple_interpolation_easing_items[];
extern EnumPropertyItem keyingset_path_grouping_items[];
Index: source/blender/editors/animation/keyframes_edit.c
===================================================================
--- source/blender/editors/animation/keyframes_edit.c (revision 28267)
+++ source/blender/editors/animation/keyframes_edit.c (working copy)
@@ -947,6 +947,76 @@
return 0;
}
+static short set_bezt_back(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_BACK;
+ return 0;
+}
+
+static short set_bezt_bounce(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_BOUNCE;
+ return 0;
+}
+
+static short set_bezt_circle(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_CIRCLE;
+ return 0;
+}
+
+static short set_bezt_cubic(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_CUBIC;
+ return 0;
+}
+
+static short set_bezt_elastic(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_ELASTIC;
+ return 0;
+}
+
+static short set_bezt_expo(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_EXPO;
+ return 0;
+}
+
+static short set_bezt_quad(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_QUAD;
+ return 0;
+}
+
+static short set_bezt_quart(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_QUART;
+ return 0;
+}
+
+static short set_bezt_quint(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->ipo= BEZT_IPO_QUINT;
+ return 0;
+}
+
+static short set_bezt_sine(KeyframeEditData *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)
@@ -956,6 +1026,26 @@
return set_bezt_constant;
case BEZT_IPO_LIN: /* linear */
return set_bezt_linear;
+ case BEZT_IPO_BACK:
+ return set_bezt_back;
+ case BEZT_IPO_BOUNCE:
+ return set_bezt_bounce;
+ case BEZT_IPO_CIRCLE:
+ 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;
}
@@ -1000,6 +1090,45 @@
}
}
+/* ------- */
+
+static short set_easingtype_easein(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_IN;
+ return 0;
+}
+
+static short set_easingtype_easeout(KeyframeEditData *ked, BezTriple *bezt)
+{
+ if (bezt->f2 & SELECT)
+ bezt->easing= BEZT_IPO_EASE_OUT;
+ return 0;
+}
+
+static short set_easingtype_easeinout(KeyframeEditData *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 code)
+{
+ switch (code) {
+ case BEZT_IPO_EASE_IN: /* breakdown */
+ return set_easingtype_easein;
+
+ case BEZT_IPO_EASE_OUT: /* extreme keyframe */
+ return set_easingtype_easeout;
+
+ case BEZT_IPO_EASE_IN_OUT: /* proper keyframe */
+ default:
+ return set_easingtype_easeinout;
+ }
+}
+
/* ******************************************* */
/* Selection */
Index: source/blender/editors/include/ED_keyframes_edit.h
===================================================================
--- source/blender/editors/include/ED_keyframes_edit.h (revision 28267)
+++ source/blender/editors/include/ED_keyframes_edit.h (working copy)
@@ -181,6 +181,7 @@
KeyframeEditFunc ANIM_editkeyframes_handles(short mode);
KeyframeEditFunc ANIM_editkeyframes_ipo(short mode);
KeyframeEditFunc ANIM_editkeyframes_keytype(short mode);
+KeyframeEditFunc ANIM_editkeyframes_easing(short code);
/* -------- BezTriple Callbacks (Selection Map) ---------- */
Index: source/blender/editors/space_graph/graph_ops.c
===================================================================
--- source/blender/editors/space_graph/graph_ops.c (revision 28267)
+++ source/blender/editors/space_graph/graph_ops.c (working copy)
@@ -242,6 +242,7 @@
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);
Index: source/blender/editors/space_graph/graph_intern.h
===================================================================
--- source/blender/editors/space_graph/graph_intern.h (revision 28267)
+++ source/blender/editors/space_graph/graph_intern.h (working copy)
@@ -109,6 +109,7 @@
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);
Index: source/blender/editors/space_graph/graph_edit.c
===================================================================
--- source/blender/editors/space_graph/graph_edit.c (revision 28267)
+++ source/blender/editors/space_graph/graph_edit.c (working copy)
@@ -1340,6 +1340,72 @@
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_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting BezTriple interpolation
+ * 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 *********************** */
EnumPropertyItem graphkeys_handle_type_items[] = {
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
45/35/ebecf393e730958cc3e7e2a7eb8f
Event Timeline
Log In to Comment