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:
authorAlexander Gavrilov <angavrilov@gmail.com>2021-07-27 10:39:52 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2021-11-24 15:58:32 +0300
commit72acce43bc34e5e9569606e08ee536b02cab088b (patch)
tree3a51c79a085a2357c652b55e833787c8ca221f09 /source/blender/editors/animation
parent5d59b38605d61b2aeabfa1cb572b5a0d9158424b (diff)
Animation: allow marking actions as cyclic for Cycle-Aware Keying.
When a manual frame range is set, allow marking an action as having Cyclic Animation. This does not affect how the action is evaluated, but the Cycle-Aware Keying option will automatically make any newly added F-Curves cyclic. This allows using the option from the start to build the cycle, rather than only for tweaking an existing loop. The curves are made cyclic when they have only one key, either after inserting the first key, or before adding the second one. The latter case avoids the need to manually make the first added curve cyclic after marking a newly added action cyclic. Differential Revision: https://developer.blender.org/D11803
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r--source/blender/editors/animation/keyframing.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 0a9f1a36a28..95d1ca1e7a6 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -35,6 +35,7 @@
#include "BLT_translation.h"
+#include "DNA_action_types.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
@@ -375,6 +376,43 @@ static eFCU_Cycle_Type remap_cyclic_keyframe_location(FCurve *fcu, float *px, fl
return type;
}
+/* Used to make curves newly added to a cyclic Action cycle with the correct period. */
+static void make_new_fcurve_cyclic(const bAction *act, FCurve *fcu)
+{
+ /* The curve must contain one (newly-added) keyframe. */
+ if (fcu->totvert != 1 || !fcu->bezt) {
+ return;
+ }
+
+ const float period = act->frame_end - act->frame_start;
+
+ if (period < 0.1f) {
+ return;
+ }
+
+ /* Move the keyframe into the range. */
+ const float frame_offset = fcu->bezt[0].vec[1][0] - act->frame_start;
+ const float fix = floorf(frame_offset / period) * period;
+
+ fcu->bezt[0].vec[0][0] -= fix;
+ fcu->bezt[0].vec[1][0] -= fix;
+ fcu->bezt[0].vec[2][0] -= fix;
+
+ /* Duplicate and offset the keyframe. */
+ fcu->bezt = MEM_reallocN(fcu->bezt, sizeof(BezTriple) * 2);
+ fcu->totvert = 2;
+
+ fcu->bezt[1] = fcu->bezt[0];
+ fcu->bezt[1].vec[0][0] += period;
+ fcu->bezt[1].vec[1][0] += period;
+ fcu->bezt[1].vec[2][0] += period;
+
+ /* Add the cycles modifier. */
+ if (!fcu->modifiers.first) {
+ add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu);
+ }
+}
+
/* -------------- BezTriple Insertion -------------------- */
/* Change the Y position of a keyframe to match the input, adjusting handles. */
@@ -1352,8 +1390,10 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
/* we may not have a F-Curve when we're replacing only... */
if (fcu) {
+ const bool is_new_curve = (fcu->totvert == 0);
+
/* set color mode if the F-Curve is new (i.e. without any keyframes) */
- if ((fcu->totvert == 0) && (flag & INSERTKEY_XYZ2RGB)) {
+ if (is_new_curve && (flag & INSERTKEY_XYZ2RGB)) {
/* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
* is determined by the array index for the F-Curve
*/
@@ -1366,12 +1406,26 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
}
}
+ /* If the curve has only one key, make it cyclic if appropriate. */
+ const bool is_cyclic_action = (flag & INSERTKEY_CYCLE_AWARE) && BKE_action_is_cyclic(act);
+
+ if (is_cyclic_action && fcu->totvert == 1) {
+ make_new_fcurve_cyclic(act, fcu);
+ }
+
/* update F-Curve flags to ensure proper behavior for property type */
update_autoflags_fcurve_direct(fcu, prop);
/* insert keyframe */
- return insert_keyframe_value(
+ const bool success = insert_keyframe_value(
reports, ptr, prop, fcu, anim_eval_context, curval, keytype, flag);
+
+ /* If the curve is new, make it cyclic if appropriate. */
+ if (is_cyclic_action && is_new_curve) {
+ make_new_fcurve_cyclic(act, fcu);
+ }
+
+ return success;
}
return false;