NLA SoC: Quick hack - Reversed playback

Animations can now be played back in reverse, by clicking on the reversed-playback button in the TimeLine header beside the play button (NEW ICON NEEDED HERE).

I'm not sure how well this works with sound, but from what I gather, this can be quite useful for animators to use.
This commit is contained in:
Joshua Leung
2009-07-07 07:29:21 +00:00
parent 761241fcbb
commit a86d20e5a2
4 changed files with 67 additions and 15 deletions

View File

@@ -33,6 +33,7 @@
typedef struct ScreenAnimData {
ARegion *ar; /* do not read from this, only for comparing if region exists */
int redraws;
int reverse;
} ScreenAnimData;

View File

@@ -1460,7 +1460,9 @@ void ED_screen_full_prevspace(bContext *C)
ed_screen_fullarea(C, sa);
}
/* redraws: uses defines from stime->redraws */
/* redraws: uses defines from stime->redraws
* enable: 1 - forward on, -1 - backwards on, 0 - off
*/
void ED_screen_animation_timer(bContext *C, int redraws, int enable)
{
bScreen *screen= CTX_wm_screen(C);
@@ -1477,6 +1479,7 @@ void ED_screen_animation_timer(bContext *C, int redraws, int enable)
screen->animtimer= WM_event_add_window_timer(win, TIMER0, (1.0/FPS));
sad->ar= CTX_wm_region(C);
sad->redraws= redraws;
sad->reverse= (enable < 0);
screen->animtimer->customdata= sad;
}

View File

@@ -2067,19 +2067,40 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event)
if(scene->audio.flag & AUDIO_SYNC) {
int step = floor(wt->duration * FPS);
scene->r.cfra += step;
if (sad->reverse) // XXX does this option work with audio?
scene->r.cfra -= step;
else
scene->r.cfra += step;
wt->duration -= ((float)step)/FPS;
}
else
scene->r.cfra++;
else {
if (sad->reverse)
scene->r.cfra--;
else
scene->r.cfra++;
}
if (scene->r.psfra) {
if(scene->r.cfra > scene->r.pefra)
scene->r.cfra= scene->r.psfra;
if (sad->reverse) {
/* jump back to end */
if (scene->r.psfra) {
if(scene->r.cfra < scene->r.psfra)
scene->r.cfra= scene->r.pefra;
}
else {
if(scene->r.cfra < scene->r.sfra)
scene->r.cfra= scene->r.efra;
}
}
else {
if(scene->r.cfra > scene->r.efra)
scene->r.cfra= scene->r.sfra;
/* jump back to start */
if (scene->r.psfra) {
if(scene->r.cfra > scene->r.pefra)
scene->r.cfra= scene->r.psfra;
}
else {
if(scene->r.cfra > scene->r.efra)
scene->r.cfra= scene->r.sfra;
}
}
/* since we follow drawflags, we can't send notifier but tag regions ourselves */
@@ -2127,8 +2148,9 @@ static int screen_animation_play(bContext *C, wmOperator *op, wmEvent *event)
ED_screen_animation_timer(C, 0, 0);
}
else {
/* todo: RNA properties to define play types */
ED_screen_animation_timer(C, TIME_REGION|TIME_ALL_3D_WIN, 1);
int mode= (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
ED_screen_animation_timer(C, TIME_REGION|TIME_ALL_3D_WIN, mode);
if(screen->animtimer) {
wmTimer *wt= screen->animtimer;
@@ -2152,7 +2174,7 @@ void SCREEN_OT_animation_play(wmOperatorType *ot)
ot->poll= ED_operator_screenactive;
RNA_def_boolean(ot->srna, "reverse", 0, "Play in Reverse", "Animation is played backwards");
}
/* ************** border select operator (template) ***************************** */

View File

@@ -373,6 +373,7 @@ static uiBlock *time_framemenu(bContext *C, ARegion *ar, void *arg_unused)
#define B_REDRAWALL 750
#define B_TL_REW 751
#define B_TL_PLAY 752
#define B_TL_RPLAY 760
#define B_TL_FF 753
#define B_TL_PREVKEY 754
#define B_TL_NEXTKEY 755
@@ -415,6 +416,18 @@ void do_time_buttons(bContext *C, void *arg, int event)
sad->ar= time_top_left_3dwindow(screen);
}
break;
case B_TL_RPLAY:
ED_screen_animation_timer(C, stime->redraws, -1);
/* update region if TIME_REGION was set, to leftmost 3d window */
if(screen->animtimer && (stime->redraws & TIME_REGION)) {
wmTimer *wt= screen->animtimer;
ScreenAnimData *sad= wt->customdata;
sad->ar= time_top_left_3dwindow(screen);
}
break;
case B_TL_STOP:
ED_screen_animation_timer(C, 0, 0);
@@ -553,14 +566,27 @@ void time_header_buttons(const bContext *C, ARegion *ar)
xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Skip to previous keyframe (Ctrl PageDown)");
xco+= XIC+4;
if(CTX_wm_screen(C)->animtimer)
if(CTX_wm_screen(C)->animtimer) {
/* pause button is drawn centered between the two other buttons for now (saves drawing 2 buttons, or having position changes) */
xco+= XIC/2 + 2;
uiDefIconBut(block, BUT, B_TL_STOP, ICON_PAUSE,
xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Stop Playing Timeline");
else
xco+= XIC/2 + 2;
}
else {
// FIXME: the icon for this is crap
uiDefIconBut(block, BUT, B_TL_RPLAY, ICON_REW/*ICON_PLAY*/,
xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Play Timeline in Reverse");
xco+= XIC+4;
uiDefIconBut(block, BUT, B_TL_PLAY, ICON_PLAY,
xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Play Timeline ");
}
xco+= XIC+4;
uiDefIconBut(block, BUT, B_TL_NEXTKEY, ICON_NEXT_KEYFRAME,
xco, yco, XIC, YIC, 0, 0, 0, 0, 0, "Skip to next keyframe (Ctrl PageUp)");
xco+= XIC+4;