2.5 - NLA Bugfixes:
* 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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user