== NLA Editor - Auto-Blending for ActionStrips ==

This is just a little time-saver for NLA-workflow. With the 'Auto-Blending' option
turned on in the Transform Properties (NKEY) for an ActionStrip, that strip's blendin/blendout values are determined based on the number of frames that the previous and/or next actionstrip(s) on overlap over the start and end of it.

It is turned on by default for new actionstrips added using the Shift-N hotkey.

Caveats:
* Only the actionstrips immediately on either side of the strip being evaluated, will
 have any effect
* A strip that is longer-than, and extends over the sides of the strip being evaluated,
 will have no effect

Additional Notes:
* Blendin/Blendout have been renamed In/Out in UI for brevity
* Button layout in NLA Transform Properties has changed slightly again, but hopefully that shouldn't be too much of an issue.
This commit is contained in:
Joshua Leung 2007-04-15 09:48:53 +00:00
parent a6113b0059
commit 185a7799a0
3 changed files with 170 additions and 5 deletions

@ -45,10 +45,13 @@ typedef struct bActionModifier {
short type, flag;
char channel[32];
/* path deform modifier */
short pad, no_rot_axis;
struct Object *ob;
/* noise modifier */
float noisesize, turbul;
short channels;
/* path deform modifier */
short no_rot_axis;
struct Object *ob;
} bActionModifier;
#define ACTSTRIP_MOD_DEFORM 0
@ -94,6 +97,7 @@ typedef struct bActionStrip {
#define ACTSTRIP_CYCLIC_USEX 0x100
#define ACTSTRIP_CYCLIC_USEY 0x200
#define ACTSTRIP_CYCLIC_USEZ 0x400
#define ACTSTRIP_AUTO_BLENDS 0x800
#endif

@ -579,8 +579,18 @@ static void nla_panel_properties(short cntrl) // NLA_HANDLER_PROPERTIES
}
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_NLA_PANEL, "Blendin:", 10,100,145,19, &strip->blendin, 0.0, strip->end-strip->start, 100, 0, "Number of frames of ease-in");
uiDefButF(block, NUM, B_NLA_PANEL, "Blendout:", 10,80,145,19, &strip->blendout, 0.0, strip->end-strip->start, 100, 0, "Number of frames of ease-out");
uiDefButBitS(block, TOG, ACTSTRIP_AUTO_BLENDS, B_NLA_LOCK, "Auto-Blending", 10,100,145,19, &(strip->flag), 0, 0, 0, 0, "Toggles automatic calculation of blendin/out values");
if (strip->flag & ACTSTRIP_AUTO_BLENDS) {
char str[32];
sprintf(str, "In: %.2f", strip->blendin);
uiDefBut(block, LABEL, B_NOP, str, 10,80,77,19, NULL, 0.0, 0.0, 0, 0, "Number of frames of ease-in");
sprintf(str, "Out: %.2f", strip->blendout);
uiDefBut(block, LABEL, B_NOP, str, 77,80,78,19, NULL, 0.0, 0.0, 0, 0, "Number of frames of ease-out");
}
else {
uiDefButF(block, NUM, B_NLA_PANEL, "In:", 10,80,77,19, &strip->blendin, 0.0, strip->end-strip->start, 100, 0, "Number of frames of ease-in");
uiDefButF(block, NUM, B_NLA_PANEL, "Out:", 77,80,78,19, &strip->blendout, 0.0, strip->end-strip->start, 100, 0, "Number of frames of ease-out");
}
uiDefButBitS(block, TOG, ACTSTRIP_MUTE, B_NLA_PANEL, "Mute", 10,60,145,19, &strip->flag, 0, 0, 0, 0, "Toggles whether the strip contributes to the NLA solution");
uiBlockBeginAlign(block);

@ -62,6 +62,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_nla.h"
#include "BKE_utildefines.h"
#include "BIF_screen.h"
#include "BIF_interface.h"
@ -188,6 +189,7 @@ void synchronize_action_strips(void)
bActionStrip *strip;
for (base=G.scene->base.first; base; base=base->next) {
/* step 1: adjust strip-lengths */
for (strip = base->object->nlastrips.last; strip; strip=strip->prev) {
if (strip->flag & ACTSTRIP_LOCK_ACTION) {
float actstart, actend;
@ -205,6 +207,153 @@ void synchronize_action_strips(void)
}
}
}
/* step 2: adjust blendin/out values for each strip if option is turned on */
for (strip= base->object->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_AUTO_BLENDS) {
bActionStrip *prev= strip->prev;
bActionStrip *next= strip->next;
float pr[2], nr[2];
strip->blendin = 0.0f;
strip->blendout = 0.0f;
/* setup test ranges */
if (prev && next) {
/* init range for previous strip */
pr[0]= prev->start;
pr[1]= prev->end;
/* init range for next strip */
nr[0]= next->start;
nr[1]= next->end;
}
else if (prev) {
/* next strip's range is same as previous strip's range */
pr[0] = nr[0] = prev->start;
pr[1] = nr[1] = prev->end;
}
else if (next) {
/* previous strip's range is same as next strip's range */
pr[0] = nr[0] = next->start;
pr[1] = nr[1] = next->end;
}
else {
/* there shouldn't be any more strips to loop through for this operation */
break;
}
/* test various cases */
if ( IN_RANGE(pr[1], strip->start, strip->end) &&
(IN_RANGE(pr[0], strip->start, strip->end)==0) )
{
/* previous strip intersects start of current */
if ( IN_RANGE(nr[1], strip->start, strip->end) &&
(IN_RANGE(nr[0], strip->start, strip->end)==0) )
{
/* next strip also intersects start of current */
if (nr[1] < pr[1])
strip->blendin= nr[1] - strip->start;
else
strip->blendin= pr[1] - strip->start;
}
else if (IN_RANGE(nr[0], strip->start, strip->end) &&
(IN_RANGE(nr[1], strip->start, strip->end)==0))
{
/* next strip intersects end of current */
strip->blendout= strip->end - nr[0];
strip->blendin= pr[1] - strip->start;
}
else {
/* only previous strip intersects current */
strip->blendin= pr[1] - strip->start;
}
}
else if (IN_RANGE(pr[0], strip->start, strip->end) &&
(IN_RANGE(pr[1], strip->start, strip->end)==0) )
{
/* previous strip intersects end of current */
if ( IN_RANGE(nr[0], strip->start, strip->end) &&
(IN_RANGE(nr[1], strip->start, strip->end)==0) )
{
/* next strip also intersects end of current */
if (nr[1] > pr[1])
strip->blendout= strip->end - nr[0];
else
strip->blendout= strip->end - pr[0];
}
else if (IN_RANGE(nr[1], strip->start, strip->end) &&
(IN_RANGE(nr[0], strip->start, strip->end)==0))
{
/* next strip intersects start of current */
strip->blendin= nr[1] - strip->start;
strip->blendout= strip->end - pr[0];
}
else {
/* only previous strip intersects current */
strip->blendout= strip->end - pr[0];
}
}
else if (IN_RANGE(nr[1], strip->start, strip->end) &&
(IN_RANGE(nr[0], strip->start, strip->end)==0) )
{
/* next strip intersects start of current */
if ( IN_RANGE(pr[1], strip->start, strip->end) &&
(IN_RANGE(pr[0], strip->start, strip->end)==0) )
{
/* previous strip also intersects start of current */
if (pr[1] < nr[1])
strip->blendin= pr[1] - strip->start;
else
strip->blendin= nr[1] - strip->start;
}
else if (IN_RANGE(pr[0], strip->start, strip->end) &&
(IN_RANGE(pr[1], strip->start, strip->end)==0))
{
/* previous strip intersects end of current */
strip->blendout= strip->end - pr[0];
strip->blendin= nr[1] - strip->start;
}
else {
/* only next strip intersects current */
strip->blendin= nr[1] - strip->start;
}
}
else if (IN_RANGE(nr[0], strip->start, strip->end) &&
(IN_RANGE(nr[1], strip->start, strip->end)==0) )
{
/* next strip intersects end of current */
if ( IN_RANGE(pr[0], strip->start, strip->end) &&
(IN_RANGE(pr[1], strip->start, strip->end)==0) )
{
/* previous strip also intersects end of current */
if (pr[1] > nr[1])
strip->blendout= strip->end - pr[0];
else
strip->blendout= strip->end - nr[0];
}
else if (IN_RANGE(pr[1], strip->start, strip->end) &&
(IN_RANGE(pr[0], strip->start, strip->end)==0))
{
/* previous strip intersects start of current */
strip->blendin= pr[1] - strip->start;
strip->blendout= strip->end - nr[0];
}
else {
/* only next strip intersects current */
strip->blendout= strip->end - nr[0];
}
}
/* make sure blending stays in ranges */
CLAMP(strip->blendin, 0, (strip->end-strip->start));
CLAMP(strip->blendout, 0, (strip->end-strip->start));
}
}
}
}
@ -502,6 +651,7 @@ void add_empty_nlablock(void)
/* change some settings of the strip - try to avoid bad scaling */
if ((EFRA-CFRA) < 100) {
strip->flag |= ACTSTRIP_AUTO_BLENDS;
strip->flag &= ~ACTSTRIP_LOCK_ACTION;
strip->actstart = CFRA;
strip->actend = CFRA + 100;
@ -510,6 +660,7 @@ void add_empty_nlablock(void)
strip->end = CFRA + 100;
}
else {
strip->flag |= ACTSTRIP_AUTO_BLENDS;
strip->flag &= ~ACTSTRIP_LOCK_ACTION;
strip->actstart = CFRA;
strip->actend = EFRA;