2.5 - NLA Bugfixes:
authorJoshua Leung <aligorith@gmail.com>
Tue, 25 Aug 2009 01:46:05 +0000 (01:46 +0000)
committerJoshua Leung <aligorith@gmail.com>
Tue, 25 Aug 2009 01:46:05 +0000 (01:46 +0000)
* F-Modifiers on F-Curves can now taken into account when calculating the extents of actions. This is used when there are some NLA strips and some action with some F-Modifiers is being played back on top of those.

* The toggles in the NLA channels list now respect the width of the list instead of using a hardcoded position. This means that clicking on these toggles when the list is resized works again.

source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/nla.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_nla/nla_edit.c

index d35acb5447aae7e82c35fca7a1a2513a70336216..4724ee19aaa0e38926115df87fbf4be4e31a7551 100644 (file)
@@ -66,7 +66,7 @@ void free_action(struct bAction *act);
 void make_local_action(struct bAction *act);
 
 /* Some kind of bounding box operation on the action */
-void calc_action_range(const struct bAction *act, float *start, float *end, int incl_hidden);
+void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers);
 
 /* Does action have any motion data at all? */
 short action_has_motion(const struct bAction *act);
index 6a39139d2505253ed6bc7054f8f809b9e5c7f851..47de044ea25e9cc7bffddca8dfd9537064639e11 100644 (file)
@@ -838,14 +838,15 @@ short action_has_motion(const bAction *act)
 }
 
 /* Calculate the extents of given action */
-void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
+void calc_action_range(const bAction *act, float *start, float *end, short incl_modifiers)
 {
        FCurve *fcu;
        float min=999999999.0f, max=-999999999.0f;
-       short foundvert=0;
+       short foundvert=0, foundmod=0;
 
        if (act) {
                for (fcu= act->curves.first; fcu; fcu= fcu->next) {
+                       /* if curve has keyframes, consider them first */
                        if (fcu->totvert) {
                                float nmin, nmax;
                                
@@ -858,10 +859,53 @@ void calc_action_range(const bAction *act, float *start, float *end, int incl_hi
                                
                                foundvert= 1;
                        }
+                       
+                       /* if incl_modifiers is enabled, need to consider modifiers too
+                        *      - only really care about the last modifier
+                        */
+                       if ((incl_modifiers) && (fcu->modifiers.last)) {
+                               FModifier *fcm= fcu->modifiers.last;
+                               
+                               /* only use the maximum sensible limits of the modifiers if they are more extreme */
+                               switch (fcm->type) {
+                                       case FMODIFIER_TYPE_LIMITS: /* Limits F-Modifier */
+                                       {
+                                               FMod_Limits *fmd= (FMod_Limits *)fcm->data;
+                                               
+                                               if (fmd->flag & FCM_LIMIT_XMIN) {
+                                                       min= MIN2(min, fmd->rect.xmin);
+                                               }
+                                               if (fmd->flag & FCM_LIMIT_XMAX) {
+                                                       max= MAX2(max, fmd->rect.xmax);
+                                               }
+                                       }
+                                               break;
+                                               
+                                       case FMODIFIER_TYPE_CYCLES: /* Cycles F-Modifier */
+                                       {
+                                               FMod_Cycles *fmd= (FMod_Cycles *)fcm->data;
+                                               
+                                               if (fmd->before_mode != FCM_EXTRAPOLATE_NONE)
+                                                       min= MINAFRAMEF;
+                                               if (fmd->after_mode != FCM_EXTRAPOLATE_NONE)
+                                                       max= MAXFRAMEF;
+                                       }
+                                               break;
+                                               
+                                       // TODO: function modifier may need some special limits
+                                               
+                                       default: /* all other standard modifiers are on the infinite range... */
+                                               min= MINAFRAMEF;
+                                               max= MAXFRAMEF;
+                                               break;
+                               }
+                               
+                               foundmod= 1;
+                       }
                }
        }       
        
-       if (foundvert) {
+       if (foundvert || foundmod) {
                if(min==max) max+= 1.0f;
                *start= min;
                *end= max;
index 5eaf21335157f4702348de78d16a43e120c1ee56..8daaaab62d499eab290125489fcb129a76308d26 100644 (file)
@@ -1263,7 +1263,6 @@ static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime)
                        dummy_strip.act= adt->action;
                        dummy_strip.remap= adt->remap;
                        
-                               // FIXME: what happens when we want to included F-Modifier access?
                        calc_action_range(dummy_strip.act, &dummy_strip.actstart, &dummy_strip.actend, 1);
                        dummy_strip.start = dummy_strip.actstart;
                        dummy_strip.end = (IS_EQ(dummy_strip.actstart, dummy_strip.actend)) ?  (dummy_strip.actstart + 1.0f): (dummy_strip.actend);
index c41c4ae78e43c57708b4c991980d6c099820e658..480c79fbc1aa8236cf4d66afdd1614643417fb37 100644 (file)
@@ -291,7 +291,7 @@ NlaStrip *add_nlastrip (bAction *act)
        /* determine initial range 
         *      - strip length cannot be 0... ever...
         */
-       calc_action_range(strip->act, &strip->actstart, &strip->actend, 1);
+       calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
        
        strip->start = strip->actstart;
        strip->end = (IS_EQ(strip->actstart, strip->actend)) ?  (strip->actstart + 1.0f): (strip->actend);
index 063b329b7a19db660fdce27fdacc91933be323f1..ccf2326642793f1e352b64bb03220d1e54237587 100644 (file)
@@ -97,6 +97,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
        ListBase anim_data = {NULL, NULL};
        bAnimListElem *ale;
        int filter;
+       View2D *v2d= &ac->ar->v2d;
        int notifierFlags = 0;
        
        /* get the channel that was clicked on */
@@ -186,14 +187,14 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
                        else
                                offset= 0;
                        
-                       if (x >= (NLACHANNEL_NAMEWIDTH-NLACHANNEL_BUTTON_WIDTH)) {
+                       if (x >= (v2d->cur.xmax-NLACHANNEL_BUTTON_WIDTH)) {
                                /* toggle protection (only if there's a toggle there) */
                                nlt->flag ^= NLATRACK_PROTECTED;
                                
                                /* notifier flags - channel was edited */
                                notifierFlags |= ND_ANIMCHAN_EDIT;
                        }
-                       else if (x >= (NLACHANNEL_NAMEWIDTH-2*NLACHANNEL_BUTTON_WIDTH)) {
+                       else if (x >= (v2d->cur.xmax-2*NLACHANNEL_BUTTON_WIDTH)) {
                                /* toggle mute */
                                nlt->flag ^= NLATRACK_MUTED;
                                
@@ -232,7 +233,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
                {
                        AnimData *adt= BKE_animdata_from_id(ale->owner); /* this won't crash, right? */
                        
-                       if (x >= (NLACHANNEL_NAMEWIDTH-NLACHANNEL_BUTTON_WIDTH)) {
+                       if (x >= (v2d->cur.xmax-NLACHANNEL_BUTTON_WIDTH)) {
                                if (nlaedit_is_tweakmode_on(ac) == 0) {
                                        /* 'push-down' action - only usable when not in TweakMode */
                                        // TODO: make this use the operator instead of calling the function directly
index 763f41164160e5bd0fe4bd4ddcfa1c94b7c3d4e9..e53ccd004db9d74bf5f69e027c16ac51b3fdd488 100644 (file)
@@ -1249,7 +1249,7 @@ static int nlaedit_apply_scale_exec (bContext *C, wmOperator *op)
                                 * but leave everything else alone 
                                 */
                                strip->scale= 1.0f;
-                               calc_action_range(strip->act, &strip->actstart, &strip->actend, 1);
+                               calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
                        }
                }
        }