[Bf-codereview] Blender Animation: Jog keys (issue4298043)

elubie at gmx.net elubie at gmx.net
Wed Mar 16 22:35:19 CET 2011


Reviewers: bf-codereview_blender.org,

Description:
This patch implements a simple version of 'jog keys'.

Functionality:
Alternative keys for animation playback:
ALT + Right Arrow: Start animation playback forward or increase speed if
already playing
ALT + Left Arrow: Start animation playback backward or increase speed if
already playing backwards

The speed is currently clamped at 6x normal speed.

Implementation Notes:
This is a cleaned up version of a previous commit that had issues - if I
remember correctly the playback buttons weren't working as expected
anymore. I have tested the current patch and it seems ok.
The jog keys are disabled if the animation is synched to the sound
(AV-sync) and playing forward - in my view it also doesn't make sense to
speed up if you synch to the sound.

Waiting for feedback :)


Please review this at http://codereview.appspot.com/4298043/

Affected files:
   source/blender/editors/include/ED_screen.h
   source/blender/editors/include/ED_screen_types.h
   source/blender/editors/render/render_internal.c
   source/blender/editors/screen/screen_edit.c
   source/blender/editors/screen/screen_ops.c
   source/blender/windowmanager/intern/wm_event_system.c


Index: source/blender/editors/include/ED_screen.h
===================================================================
--- source/blender/editors/include/ED_screen.h	(revision 35577)
+++ source/blender/editors/include/ED_screen.h	(working copy)
@@ -104,7 +104,7 @@
  void	ED_screen_delete_scene(struct bContext *C, struct Scene *scene);
  void	ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event);
  void	ED_screen_exit(struct bContext *C, struct wmWindow *window, struct  
bScreen *screen);
-void	ED_screen_animation_timer(struct bContext *C, int redraws, int  
refresh, int sync, int enable);
+void	ED_screen_animation_timer(struct bContext *C, int redraws, int  
refresh, int sync, int enable, int speed_mul);
  void	ED_screen_animation_timer_update(struct bScreen *screen, int redraws,  
int refresh);
  int		ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
  void	ED_screen_full_prevspace(struct bContext *C, ScrArea *sa);
@@ -117,7 +117,7 @@
  void	ED_update_for_newframe(struct Main *bmain, struct Scene *scene,  
struct bScreen *screen, int mute);

  void 	ED_refresh_viewport_fps(struct bContext *C);
-int ED_screen_animation_play(struct bContext *C, int sync, int mode);
+int		ED_screen_animation_play(struct bContext *C, int sync, int mode, int  
toggle);

  /* screen keymaps */
  void	ED_operatortypes_screen(void);
Index: source/blender/editors/include/ED_screen_types.h
===================================================================
--- source/blender/editors/include/ED_screen_types.h	(revision 35577)
+++ source/blender/editors/include/ED_screen_types.h	(working copy)
@@ -43,6 +43,7 @@
  	short flag;			/* flags for playback */
  	int sfra;			/* frame that playback was started from */
  	int nextfra;		/* next frame to go to (when ANIMPLAY_FLAG_USE_NEXT_FRAME  
is set) */
+	int speed_mul;		/* multiplier for anim speed - twice as fast, three times  
as fast etc. */
  } ScreenAnimData;

  /* for animplayer */
Index: source/blender/editors/render/render_internal.c
===================================================================
--- source/blender/editors/render/render_internal.c	(revision 35577)
+++ source/blender/editors/render/render_internal.c	(working copy)
@@ -696,7 +696,7 @@

  	/* cancel animation playback */
  	if (screen->animtimer)
-		ED_screen_animation_play(C, 0, 0);
+		ED_screen_animation_play(C, 0, 0, 1);
  	
  	/* handle UI stuff */
  	WM_cursor_wait(1);
Index: source/blender/editors/screen/screen_edit.c
===================================================================
--- source/blender/editors/screen/screen_edit.c	(revision 35577)
+++ source/blender/editors/screen/screen_edit.c	(working copy)
@@ -1702,26 +1702,28 @@
  /* 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 refresh, int  
sync, int enable)
+void ED_screen_animation_timer(bContext *C, int redraws, int refresh, int  
sync, int enable, int speed_mul)
  {
  	bScreen *screen= CTX_wm_screen(C);
  	wmWindowManager *wm= CTX_wm_manager(C);
  	wmWindow *win= CTX_wm_window(C);
  	Scene *scene= CTX_data_scene(C);
  	
-	if(screen->animtimer)
+	if(screen->animtimer) {
  		WM_event_remove_timer(wm, win, screen->animtimer);
+	}
  	screen->animtimer= NULL;
  	
  	if(enable) {
  		ScreenAnimData *sad=  
MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData");
  		
-		screen->animtimer= WM_event_add_timer(wm, win, TIMER0, (1.0/FPS));
+		screen->animtimer= WM_event_add_timer(wm, win, TIMER0,  
(1.0/(FPS*speed_mul)));
  		
  		sad->ar= CTX_wm_region(C);
  		sad->sfra = scene->r.cfra;
  		sad->redraws= redraws;
  		sad->refresh= refresh;
+		sad->speed_mul = speed_mul;
  		sad->flag |= (enable < 0)? ANIMPLAY_FLAG_REVERSE: 0;
  		sad->flag |= (sync == 0)? ANIMPLAY_FLAG_NO_SYNC: (sync == 1)?  
ANIMPLAY_FLAG_SYNC: 0;
  		
Index: source/blender/editors/screen/screen_ops.c
===================================================================
--- source/blender/editors/screen/screen_ops.c	(revision 35577)
+++ source/blender/editors/screen/screen_ops.c	(working copy)
@@ -2760,20 +2760,20 @@
  		else
  		{
  			if (sync) {
-				int step = floor(wt->duration * FPS);
+				int step = floor(wt->duration * (FPS*sad->speed_mul));
  				/* skip frames */
  				if (sad->flag & ANIMPLAY_FLAG_REVERSE)
  					scene->r.cfra -= step;
  				else
  					scene->r.cfra += step;
-				wt->duration -= ((float)step)/FPS;
+				wt->duration -= ((float)step)/(FPS*sad->speed_mul);
  			}
  			else {
  				/* one frame +/- */
  				if (sad->flag & ANIMPLAY_FLAG_REVERSE)
-					scene->r.cfra--;
+					scene->r.cfra -= sad->speed_mul;
  				else
-					scene->r.cfra++;
+					scene->r.cfra += sad->speed_mul;
  			}
  		}
  		
@@ -2848,7 +2848,7 @@
  		 * since the frames-per-second value may have been changed
  		 */
  		// TODO: this may make evaluation a bit slower if the value doesn't  
change... any way to avoid this?
-		wt->timestep= (1.0/FPS);
+		wt->timestep= (1.0/(FPS*sad->speed_mul));
  		
  		return OPERATOR_FINISHED;
  	}
@@ -2871,25 +2871,36 @@

  /* ****************** anim player, starts or ends timer *****************  
*/

+#define ANIMPLAYER_MAX_SPEEDMUL 6
+
  /* toggle operator */
-int ED_screen_animation_play(bContext *C, int sync, int mode)
+int ED_screen_animation_play(bContext *C, int sync, int mode, int toggle)
  {
  	bScreen *screen= CTX_wm_screen(C);
  	Scene *scene = CTX_data_scene(C);
+	int speed_mul = 1;

-	if (screen->animtimer) {
+	if (screen->animtimer && toggle) {
  		/* stop playback now */
-		ED_screen_animation_timer(C, 0, 0, 0, 0);
+		ED_screen_animation_timer(C, 0, 0, 0, 0, 1);
  		sound_stop_scene(scene);
-	}
-	else {
+	} else {
  		int refresh= SPACE_TIME; /* these settings are currently only available  
from a menu in the TimeLine */
-		
-		if (mode == 1) // XXX only play audio forwards!?
+
+		if (screen->animtimer) {
+			ScreenAnimData *sad = (ScreenAnimData*)screen->animtimer->customdata;
+			int oldmode = (sad->flag & ANIMPLAY_FLAG_REVERSE) ? -1 : 1;
+			if (!toggle && (mode == oldmode)) {
+				/* we are not toggling on/off and are already playing, so we increase  
playback speed */
+				speed_mul = (sad->speed_mul < ANIMPLAYER_MAX_SPEEDMUL) ?  
sad->speed_mul+1 : ANIMPLAYER_MAX_SPEEDMUL;
+			}
+		}
+
+		if ( (mode == 1) && (speed_mul==1) ) // XXX only play audio forwards at  
normal speed!?
  			sound_play_scene(scene);
+
+		ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode,  
speed_mul);
  		
-		ED_screen_animation_timer(C, screen->redraws_flag, refresh, sync, mode);
-		
  		if (screen->animtimer) {
  			wmTimer *wt= screen->animtimer;
  			ScreenAnimData *sad= wt->customdata;
@@ -2905,11 +2916,15 @@
  {
  	int mode= (RNA_boolean_get(op->ptr, "reverse")) ? -1 : 1;
  	int sync= -1;
-	
+	int toggle = 1;
+
  	if (RNA_property_is_set(op->ptr, "sync"))
  		sync= (RNA_boolean_get(op->ptr, "sync"));
-	
-	return ED_screen_animation_play(C, sync, mode);
+
+	if (RNA_property_is_set(op->ptr, "toggle"))
+		toggle= (RNA_boolean_get(op->ptr, "toggle"));
+
+	return ED_screen_animation_play(C, sync, mode, toggle);
  }

  static void SCREEN_OT_animation_play(wmOperatorType *ot)
@@ -2926,6 +2941,7 @@
  	
  	RNA_def_boolean(ot->srna, "reverse", 0, "Play in Reverse", "Animation is  
played backwards");
  	RNA_def_boolean(ot->srna, "sync", 0, "Sync", "Drop frames to maintain  
framerate");
+	RNA_def_boolean(ot->srna, "toggle", 1, "Toggle", "Toggle forward/backward  
rather than stopping the animation");
  }

  static int screen_animation_cancel_exec(bContext *C, wmOperator  
*UNUSED(op))
@@ -2943,7 +2959,7 @@
  		WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
  		
  		/* call the other "toggling" operator to clean up now */
-		ED_screen_animation_play(C, 0, 0);
+		ED_screen_animation_play(C, 0, 0, 1);
  	}

  	return OPERATOR_PASS_THROUGH;
@@ -3313,7 +3329,7 @@
  {
  	ListBase *lb;
  	wmKeyMap *keymap;
-	//wmKeyMapItem *kmi;
+	wmKeyMapItem *kmi;
  	
  	/* Screen Editing ------------------------------------------------ */
  	keymap= WM_keymap_find(keyconf, "Screen Editing", 0, 0);
@@ -3422,17 +3438,15 @@
  	WM_keymap_add_item(keymap, "SCREEN_OT_animation_cancel", MEDIASTOP,  
KM_PRESS, 0, 0);
  	
  	/* Alternative keys for animation and sequencer playing */
-#if 0 // XXX: disabled for restoring later... bad implementation
-	keymap= WM_keymap_find(keyconf, "Frames", 0, 0);
+	// keymap= WM_keymap_find(keyconf, "Frames", 0, 0);
  	kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play",  
RIGHTARROWKEY, KM_PRESS, KM_ALT, 0);
-		RNA_boolean_set(kmi->ptr, "cycle_speed", 1);
+		RNA_boolean_set(kmi->ptr, "toggle", 0);
  	
  	kmi = WM_keymap_add_item(keymap, "SCREEN_OT_animation_play",  
LEFTARROWKEY, KM_PRESS, KM_ALT, 0);
  		RNA_boolean_set(kmi->ptr, "reverse", 1);
-		RNA_boolean_set(kmi->ptr, "cycle_speed", 1);
+		RNA_boolean_set(kmi->ptr, "toggle", 0);
  	
  	WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", DOWNARROWKEY,  
KM_PRESS, KM_ALT, 0);
-#endif

  	/* dropbox for entire window */
  	lb= WM_dropboxmap_find("Window", 0, 0);
Index: source/blender/windowmanager/intern/wm_event_system.c
===================================================================
--- source/blender/windowmanager/intern/wm_event_system.c	(revision 35577)
+++ source/blender/windowmanager/intern/wm_event_system.c	(working copy)
@@ -1714,7 +1714,7 @@
  					CTX_data_scene_set(C, scene);
  					
  					if(((playing == 1) && (!win->screen->animtimer)) || ((playing == 0)  
&& (win->screen->animtimer))){
-						ED_screen_animation_play(C, -1, 1);
+						ED_screen_animation_play(C, -1, 1, 1);
  					}
  					
  					if(playing == 0) {




More information about the Bf-codereview mailing list