NLA: ignore time range when evaluating a raw action.
authorAlexander Gavrilov <angavrilov@gmail.com>
Sat, 12 Jan 2019 11:10:09 +0000 (14:10 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Sat, 12 Jan 2019 11:10:33 +0000 (14:10 +0300)
When editing an action without a strip, or tweaking a strip without
time mapping enabled or supported, the extents of the virtual strip
can't be controlled and are purely derived from keys in the action.

Thus, cutting off evaluation of the action at these arbitrary points
gets in the way of observing the natural extrapolation of the F-Curves
and thus appears to be a mis-feature.

With this change non-mapped actions are evaluated with infinite
range, exactly like they are handled without NLA, unless extend
mode is set to Nothing.

source/blender/blenkernel/intern/anim_sys.c
source/blender/makesdna/DNA_anim_types.h

index c5a21342dc0ae308e34779621c8a3cb249b1c4e6..5ec3b931f09bf353048f3099a789fe5306479e0c 100644 (file)
@@ -1888,11 +1888,18 @@ static void nlastrip_evaluate_controls(Depsgraph *depsgraph, NlaStrip *strip, fl
         * - we do this after the F-Curves have been evaluated to override the effects of those
         *   in case the override has been turned off.
         */
-       if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0)
-               strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
        if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0)
                strip->influence = nlastrip_get_influence(strip, ctime);
 
+       /* Bypass evaluation time computation if time mapping is disabled. */
+       if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) {
+               strip->strip_time = ctime;
+               return;
+       }
+
+       if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0)
+               strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL);
+
        /* if user can control the evaluation time (using F-Curves), consider the option which allows this time to be clamped
         * to lie within extents of the action-clip, so that a steady changing rate of progress through several cycles of the clip
         * can be achieved easily
@@ -1912,7 +1919,7 @@ NlaEvalStrip *nlastrips_ctime_get_strip(Depsgraph *depsgraph, ListBase *list, Li
        /* loop over strips, checking if they fall within the range */
        for (strip = strips->first; strip; strip = strip->next) {
                /* check if current time occurs within this strip  */
-               if (IN_RANGE_INCL(ctime, strip->start, strip->end)) {
+               if (IN_RANGE_INCL(ctime, strip->start, strip->end) || (strip->flag & NLASTRIP_FLAG_NO_TIME_MAP)) {
                        /* this strip is active, so try to use it */
                        estrip = strip;
                        side = NES_TIME_WITHIN;
@@ -2971,13 +2978,18 @@ static bool animsys_evaluate_nla(Depsgraph *depsgraph, NlaEvalData *echannels, P
                                /* Always use the blend mode of the strip in tweak mode, even if not in-place. */
                                if (nlt && adt->actstrip) {
                                        dummy_strip->blendmode = adt->actstrip->blendmode;
-                                       dummy_strip->extendmode = adt->actstrip->extendmode;
+                                       dummy_strip->extendmode = NLASTRIP_EXTEND_HOLD;
                                }
                                else {
                                        dummy_strip->blendmode = adt->act_blendmode;
                                        dummy_strip->extendmode = adt->act_extendmode;
                                }
 
+                               /* Unless extendmode is Nothing (might be useful for flattening NLA evaluation), disable range. */
+                               if (dummy_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+                                       dummy_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+                               }
+
                                dummy_strip->influence = adt->act_influence;
 
                                /* NOTE: must set this, or else the default setting overrides, and this setting doesn't work */
index 8e89f4a42b75d2587ab202696e651b010059e3bd..15203812b2db6adde555e5daf9aca53477edd0f2 100644 (file)
@@ -763,6 +763,8 @@ typedef enum eNlaStrip_Flag {
        NLASTRIP_FLAG_MIRROR        = (1<<13),
 
        /* temporary editing flags */
+               /* NLA strip should ignore frame range and hold settings, and evaluate at global time. */
+       NLASTRIP_FLAG_NO_TIME_MAP   = (1<<29),
                /* NLA-Strip is really just a temporary meta used to facilitate easier transform code */
        NLASTRIP_FLAG_TEMP_META     = (1<<30),
        NLASTRIP_FLAG_EDIT_TOUCHED  = (1u << 31)