Page Menu
Home
Search
Configure Global Search
Log In
Files
F10972
easing-4.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
39 KB
Subscribers
None
easing-4.diff
View Options
Index: release/scripts/ui/space_graph.py
===================================================================
--- release/scripts/ui/space_graph.py (revision 28330)
+++ 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.c
===================================================================
--- source/blender/blenkernel/intern/fcurve_easing.c (revision 0)
+++ source/blender/blenkernel/intern/fcurve_easing.c (revision 0)
@@ -0,0 +1,276 @@
+/*
+ * 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.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "fcurve_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;
+}
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,74 @@
+/*
+ * 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
+
+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 // FCURVE_EASING_H
Index: source/blender/blenkernel/intern/fcurve.c
===================================================================
--- source/blender/blenkernel/intern/fcurve.c (revision 28330)
+++ 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_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:
+ {
+ 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 28330)
+++ 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_CIRC,
+ 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 28330)
+++ source/blender/makesrna/intern/rna_curve.c (working copy)
@@ -45,8 +45,18 @@
EnumPropertyItem beztriple_interpolation_mode_items[] = {
{BEZT_IPO_CONST, "CONSTANT", 0, "Constant", ""},
- {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""},
+ {BEZT_IPO_LIN, "LINEAR", 0, "Linear", "Simple linear: no easing"},
{BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""},
+ {BEZT_IPO_BACK, "BACK", 0, "Back", "Back easing: overshooting cubic easing"},
+ {BEZT_IPO_BOUNCE, "BOUNCE", 0, "Bounce", "Bounce easing: exponentially decaying parabolic bounce"},
+ {BEZT_IPO_CIRC, "CIRC", 0, "Circular", "Circular easing"},
+ {BEZT_IPO_CUBIC, "CUBIC", 0, "Cubic", "Cubic easing"},
+ {BEZT_IPO_ELASTIC, "ELASTIC", 0, "Elastic", "Elastic easing: exponentially decaying sine wave"},
+ {BEZT_IPO_EXPO, "EXPO", 0, "Exponential", "Exponential easing"},
+ {BEZT_IPO_QUAD, "QUAD", 0, "Quadratic", "Quadratic easing"},
+ {BEZT_IPO_QUART, "QUART", 0, "Quartic", "Quartic easing"},
+ {BEZT_IPO_QUINT, "QUINT", 0, "Quintic", "Quintic easing"},
+ {BEZT_IPO_SINE, "SINE", 0, "Sinusoidal", "Sinusoidal easing"},
{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 28330)
+++ 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 28330)
+++ 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 28330)
+++ 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_CIRC;
+ 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_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;
}
@@ -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 28330)
+++ 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_draw.c
===================================================================
--- source/blender/editors/space_graph/graph_draw.c (revision 28330)
+++ source/blender/editors/space_graph/graph_draw.c (working copy)
@@ -883,8 +883,13 @@
}
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, grid);
+ if (fcu->bezt) {
+ BezTriple *bezt = fcu->bezt;
+ if (bezt->ipo > BEZT_IPO_BEZ)
+ draw_fcurve_curve(ac, ale->id, fcu, sipo, &ar->v2d, grid);
+ else
+ draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d, grid);
+ }
else if (fcu->fpt)
draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d);
}
Index: source/blender/editors/space_graph/graph_buttons.c
===================================================================
--- source/blender/editors/space_graph/graph_buttons.c (revision 28330)
+++ source/blender/editors/space_graph/graph_buttons.c (working copy)
@@ -216,6 +216,58 @@
MEM_freeN(ale);
}
+/* ******************* active Key ************** */
+
+static void graph_panel_key_properties(const bContext *C, Panel *pa)
+{
+ bAnimListElem *ale;
+ FCurve *fcu;
+ PointerRNA bezt_ptr;
+ BezTriple *bezt;
+ uiLayout *layout = pa->layout;
+ uiLayout *col;
+ uiBlock *block;
+ int i, selected = 0;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ bezt = fcu->bezt;
+
+ for (i=0; i < fcu->totvert; i++) {
+ if(bezt->f1 || bezt->f2 || bezt->f3){
+ selected = 1;
+ break;
+ }
+ bezt++;
+ }
+
+ if (!selected)
+ return;
+
+ block= uiLayoutGetBlock(layout);
+ uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
+
+ /* Keyframe pointer */
+ RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
+
+ col= uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, 0);
+ uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
+
+ col= uiLayoutColumn(layout, 1);
+ uiLayoutSetEnabled(col, (bezt->ipo == BEZT_IPO_BACK));
+ uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
+
+ col= uiLayoutColumn(layout, 1);
+ uiLayoutSetEnabled(col, (bezt->ipo == BEZT_IPO_ELASTIC));
+ uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
+ uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
+
+
+ MEM_freeN(ale);
+}
+
/* ******************* drivers ******************************** */
#define B_IPO_DEPCHANGE 10
@@ -640,6 +692,13 @@
pt->poll= graph_panel_poll;
BLI_addtail(&art->paneltypes, pt);
+ pt= MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
+ strcpy(pt->idname, "GRAPH_PT_key_properties");
+ strcpy(pt->label, "Active Key");
+ pt->draw= graph_panel_key_properties;
+ pt->poll= graph_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
pt= MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers");
strcpy(pt->idname, "GRAPH_PT_drivers");
strcpy(pt->label, "Drivers");
Index: source/blender/editors/space_graph/graph_ops.c
===================================================================
--- source/blender/editors/space_graph/graph_ops.c (revision 28330)
+++ 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 28330)
+++ 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 28330)
+++ 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
59/37/b3e5f1d5618543096ee39ddbee30
Event Timeline
Log In to Comment