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 c5a2134..5ec3b93 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 8e89f4a..1520381 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)