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-05-03 00:03:00 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2021-11-24 15:58:32 +0300
commit5d59b38605d61b2aeabfa1cb572b5a0d9158424b (patch)
tree82b0a19eb0e5dd7290ae81c10427082576d8dfb5 /source/blender/blenkernel
parent057cb7e5e77bcf932882292a774156b5d8c90ab4 (diff)
Animation: allow manually setting the intended playback range for actions.
Some operations, e.g. adding a new action strip to NLA, require knowing the active frame range of an action. However, currently it can only be deduced by scanning the keyframes of the curves within it. This is not ideal if e.g. curves are staggered for overlap. As suggested by Nathan Vegdahl in comments to T54724, this patch adds Action properties that allow manually specifying its active frame range. The settings are exposed via a panel in the Dopesheet and Action Editor. When enabled, the range is highlighted in the background using a striped fill to distinguish it from the solid filled regular playback range. When set, the frame range is used when adding or updating NLA tracks, and by add-ons using `Action.frame_range`, e.g. FBX exporter. Differential Revision: https://developer.blender.org/D11803
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_action.h4
-rw-r--r--source/blender/blenkernel/intern/action.c18
-rw-r--r--source/blender/blenkernel/intern/nla.c9
3 files changed, 29 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 763e540fdd9..6d457ed32f0 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -91,6 +91,10 @@ short action_get_item_transforms(struct bAction *act,
/* Some kind of bounding box operation on the action */
void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers);
+/* Retrieve the intended playback frame range, using the manually set range if available,
+ * or falling back to scanning F-Curves for their first & last frames otherwise. */
+void BKE_action_get_frame_range(const struct bAction *act, float *r_start, float *r_end);
+
/* Does action have any motion data at all? */
bool action_has_motion(const struct bAction *act);
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 27873f19977..47db5183e76 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -1573,6 +1573,24 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
}
}
+/* Retrieve the intended playback frame range, using the manually set range if available,
+ * or falling back to scanning F-Curves for their first & last frames otherwise. */
+void BKE_action_get_frame_range(const struct bAction *act, float *r_start, float *r_end)
+{
+ if (act && (act->flag & ACT_FRAME_RANGE)) {
+ *r_start = act->frame_start;
+ *r_end = act->frame_end;
+ }
+ else {
+ calc_action_range(act, r_start, r_end, false);
+ }
+
+ /* Ensure that action is at least 1 frame long (for NLA strips to have a valid length). */
+ if (*r_start >= *r_end) {
+ *r_end = *r_start + 1.0f;
+ }
+}
+
/* Return flags indicating which transforms the given object/posechannel has
* - if 'curves' is provided, a list of links to these curves are also returned
*/
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 124db07298d..0666c1dfc53 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -390,6 +390,11 @@ NlaStrip *BKE_nlastrip_new(bAction *act)
*/
strip->flag = NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_SYNC_LENGTH;
+ /* Disable sync for actions with a manual frame range, since it only syncs to range anyway. */
+ if (act->flag & ACT_FRAME_RANGE) {
+ strip->flag &= ~NLASTRIP_FLAG_SYNC_LENGTH;
+ }
+
/* assign the action reference */
strip->act = act;
id_us_plus(&act->id);
@@ -397,7 +402,7 @@ NlaStrip *BKE_nlastrip_new(bAction *act)
/* determine initial range
* - strip length cannot be 0... ever...
*/
- calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
+ BKE_action_get_frame_range(strip->act, &strip->actstart, &strip->actend);
strip->start = strip->actstart;
strip->end = (IS_EQF(strip->actstart, strip->actend)) ? (strip->actstart + 1.0f) :
@@ -1444,7 +1449,7 @@ void BKE_nlastrip_recalculate_bounds_sync_action(NlaStrip *strip)
prev_actstart = strip->actstart;
- calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
+ BKE_action_get_frame_range(strip->act, &strip->actstart, &strip->actend);
/* Set start such that key's do not visually move, to preserve the overall animation result. */
strip->start += (strip->actstart - prev_actstart) * strip->scale;