camera switching via markers
authorCampbell Barton <ideasman42@gmail.com>
Wed, 16 Dec 2009 19:49:33 +0000 (19:49 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 16 Dec 2009 19:49:33 +0000 (19:49 +0000)
Currently access by selecting a marking and binding with the active camera from the view menu.

Note:
after long discussion we decieded there is no nice way to do this.. animate pointers? animate multiple camera visibility?, use sequencer? use NLA?.... have a kind of event system (like framechange scriptlinks)... etc
so this is ifdef'd with DURIAN_CAMERA_SWITCH

release/scripts/ui/space_time.py
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/makesdna/DNA_scene_types.h
source/blender/render/intern/source/pipeline.c

index 86347f8c543105e489968f4e9eb26c6b99b6e3aa..e328fa9e31bb25ebdcc45381810ad4f67d5ffb90 100644 (file)
@@ -98,6 +98,9 @@ class TIME_MT_view(bpy.types.Menu):
         layout.prop(st, "show_cframe_indicator")
         layout.prop(st, "only_selected")
 
+        layout.separator()
+
+        layout.operator("marker.camera_bind")
 
 class TIME_MT_frame(bpy.types.Menu):
     bl_label = "Frame"
index ecff62a795260e67dadc77123f844f15b0d13935..c372004bd199b1b0df5649738eb36ce1287b1226 100644 (file)
@@ -66,6 +66,7 @@ void unlink_scene(struct Main *bmain, struct Scene *sce, struct Scene *newsce);
 
 int next_object(struct Scene *scene, int val, struct Base **base, struct Object **ob);
 struct Object *scene_find_camera(struct Scene *sc);
+struct Object *scene_find_camera_switch(struct Scene *scene); // DURIAN_CAMERA_SWITCH
 
 struct Base *scene_add_base(struct Scene *sce, struct Object *ob);
 void scene_deselect_all(struct Scene *sce);
index 6b86c6c29080c9e780f3c493f3a3836bf9a74400..9a7a35010314d73c188a39c1cc0954627a844f47 100644 (file)
@@ -554,6 +554,17 @@ void unlink_object(Scene *scene, Object *ob)
                if(sce->id.lib==NULL) {
                        if(sce->camera==ob) sce->camera= NULL;
                        if(sce->toolsettings->skgen_template==ob) sce->toolsettings->skgen_template = NULL;
+
+#ifdef DURIAN_CAMERA_SWITCH
+                       {
+                               TimeMarker *m;
+
+                               for (m= sce->markers.first; m; m= m->next) {
+                                       if(m->camera==ob)
+                                               m->camera= NULL;
+                               }
+                       }
+#endif
                }
                sce= sce->id.next;
        }
index 4312f23bd9b6ee9dfaee2d11c24538c8e7a3857a..7bfeac037ce603420d47a74f8685dd8696649cc8 100644 (file)
@@ -698,6 +698,47 @@ Object *scene_find_camera(Scene *sc)
        return NULL;
 }
 
+#ifdef DURIAN_CAMERA_SWITCH
+Object *scene_find_camera_switch(Scene *scene)
+{
+       TimeMarker *m;
+       int cfra = scene->r.cfra;
+       int frame = -(MAXFRAME + 1);
+       Object *camera= NULL;
+
+       for (m= scene->markers.first; m; m= m->next) {
+               if(m->camera && (m->frame <= cfra) && (m->frame > frame)) {
+                       camera= m->camera;
+                       frame= m->frame;
+
+                       if(frame == cfra)
+                               break;
+
+               }
+       }
+       return camera;
+}
+#endif
+
+static char *get_cfra_marker_name(Scene *scene)
+{
+       ListBase *markers= &scene->markers;
+       TimeMarker *m1, *m2;
+
+       /* search through markers for match */
+       for (m1=markers->first, m2=markers->last; m1 && m2; m1=m1->next, m2=m2->prev) {
+               if (m1->frame==CFRA)
+                       return m1->name;
+
+               if (m1 == m2)
+                       break;
+
+               if (m2->frame==CFRA)
+                       return m2->name;
+       }
+
+       return NULL;
+}
 
 Base *scene_add_base(Scene *sce, Object *ob)
 {
index fa878093cc48a82752afead9a61ad82318e8c083..17dfb4f7ce64ea941e6d44602a1b652a49192efb 100644 (file)
@@ -4174,6 +4174,7 @@ static void lib_link_scene(FileData *fd, Main *main)
        Base *base, *next;
        Sequence *seq;
        SceneRenderLayer *srl;
+       TimeMarker *marker;
        
        sce= main->scene.first;
        while(sce) {
@@ -4229,6 +4230,14 @@ static void lib_link_scene(FileData *fd, Main *main)
                        }
                        SEQ_END
 
+#ifdef DURIAN_CAMERA_SWITCH
+                       for(marker= sce->markers.first; marker; marker= marker->next) {
+                               if(marker->camera) {
+                                       marker->camera= newlibadr(fd, sce->id.lib, marker->camera);
+                               }
+                       }
+#endif
+
                        if(sce->ed)
                                seq_update_muting(sce->ed);
                        
@@ -4280,6 +4289,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        Editing *ed;
        Sequence *seq;
        MetaStack *ms;
+       TimeMarker *marker;
 
        sce->theDag = NULL;
        sce->dagisvalid = 0;
@@ -4451,7 +4461,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        link_list(fd, &(sce->markers));
        link_list(fd, &(sce->transform_spaces));
        link_list(fd, &(sce->r.layers));
-       
+
        sce->nodetree= newdataadr(fd, sce->nodetree);
        if(sce->nodetree)
                direct_link_nodetree(fd, sce->nodetree);
@@ -11255,6 +11265,18 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
                
        if(sce->gpd)
                expand_doit(fd, mainvar, sce->gpd);
+
+#ifdef DURIAN_CAMERA_SWITCH
+       {
+               TimeMarker *marker;
+
+               for(marker= sce->markers.first; marker; marker= marker->next) {
+                       if(marker->camera) {
+                               expand_doit(fd, mainvar, marker->camera);
+                       }
+               }
+       }
+#endif
 }
 
 static void expand_camera(FileData *fd, Main *mainvar, Camera *ca)
index 721fa928e4458b9a6cc655b2a6242170ef53be96..0d519c87a9777fd9df61cf391ea430f098c3360c 100644 (file)
@@ -240,15 +240,19 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);                      
        
        /* vertical line - dotted */
-       // NOTE: currently only used for sequencer 
+       // NOTE: currently only used for sequencer
+#ifdef DURIAN_CAMERA_SWITCH
+       if (marker->camera || flag & DRAW_MARKERS_LINES) {
+#else
        if (flag & DRAW_MARKERS_LINES) {
+#endif
                setlinestyle(3);
                
                if (marker->flag & SELECT)
                        glColor4ub(255, 255, 255, 96);
                else
                        glColor4ub(0, 0, 0, 96);
-               
+
                glBegin(GL_LINES);
                        glVertex2f((xpos*xscale)+0.5f, 12.0f);
                        glVertex2f((xpos*xscale)+0.5f, 34.0f*yscale); /* a bit lazy but we know it cant be greater then 34 strips high */
@@ -672,6 +676,10 @@ static void ed_marker_duplicate_apply(bContext *C, wmOperator *op)
                        newmarker->frame= marker->frame;
                        BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
                        
+#ifdef DURIAN_CAMERA_SWITCH
+                       newmarker->camera= marker->camera;
+#endif
+
                        /* new marker is added to the begining of list */
                        BLI_addhead(markers, newmarker);
                }
@@ -978,6 +986,48 @@ static void MARKER_OT_delete(wmOperatorType *ot)
        
 }
 
+#ifdef DURIAN_CAMERA_SWITCH
+/* ******************************* camera bind marker ***************** */
+
+/* remove selected TimeMarkers */
+static int ed_marker_camera_bind_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       ListBase *markers= context_get_markers(C);
+       TimeMarker *marker;
+       short changed= 0;
+
+       if(markers == NULL)
+               return OPERATOR_CANCELLED;
+
+       for(marker= markers->first; marker; marker= marker->next) {
+               if(marker->flag & SELECT) {
+                       marker->camera= scene->camera;
+               }
+       }
+
+       if (changed)
+               WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
+
+       return OPERATOR_FINISHED;
+}
+
+static void MARKER_OT_camera_bind(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bind Camera to Markers";
+       ot->description= "Bind the active camera to selected markers(s).";
+       ot->idname= "MARKER_OT_camera_bind";
+
+       /* api callbacks */
+       ot->exec= ed_marker_camera_bind_exec;
+       ot->poll= ED_operator_areaactive;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+#endif
+
 /* ************************** registration **********************************/
 
 /* called in screen_ops.c:ED_operatortypes_screen() */
@@ -990,6 +1040,9 @@ void ED_operatortypes_marker(void)
        WM_operatortype_append(MARKER_OT_select_border);
        WM_operatortype_append(MARKER_OT_select_all);
        WM_operatortype_append(MARKER_OT_delete);
+#ifdef DURIAN_CAMERA_SWITCH
+       WM_operatortype_append(MARKER_OT_camera_bind);
+#endif
 }
 
 /* called in screen_ops.c:ED_keymap_screen() */
@@ -1008,5 +1061,8 @@ void ED_marker_keymap(wmKeyConfig *keyconf)
        WM_keymap_verify_item(keymap, "MARKER_OT_delete", DELKEY, KM_PRESS, 0, 0);
        
        WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
+#ifdef DURIAN_CAMERA_SWITCH
+       WM_keymap_add_item(keymap, "MARKER_OT_camera_bind", HOMEKEY, KM_PRESS, 0, 0);
+#endif
        
 }
index 640a14a934b6a5e4dd2ab9fa7211965b68b15d85..9c581527e4c97b6665f0bcd43c3b4526b0eff011 100644 (file)
@@ -1670,6 +1670,47 @@ void ED_update_for_newframe(const bContext *C, int mute)
        bScreen *screen= CTX_wm_screen(C);
        Scene *scene= CTX_data_scene(C);
        
+#ifdef DURIAN_CAMERA_SWITCH
+       void *camera= scene_find_camera_switch(scene);
+       if(camera && scene->camera != camera) {
+
+               if(camera && scene->camera && (camera != scene->camera)) {
+                       bScreen *sc;
+                       /* are there cameras in the views that are not in the scene? */
+                       for(sc= CTX_data_main(C)->screen.first; sc; sc= sc->id.next) {
+                               ScrArea *sa= sc->areabase.first;
+                               while(sa) {
+                                       SpaceLink *sl= sa->spacedata.first;
+                                       while(sl) {
+                                               if(sl->spacetype==SPACE_VIEW3D) {
+                                                       View3D *v3d= (View3D*) sl;
+                                                       if (v3d->camera == scene->camera) {
+                                                               v3d->camera= camera;
+                                                               /*
+                                                               ARegion *ar;
+                                                               for(ar=v3d->regionbase.first; ar; ar= ar->next) {
+                                                                       if(ar->regiontype == RGN_TYPE_WINDOW) {
+                                                                               RegionView3D *rv3d= ar->regiondata;
+
+                                                                               if(rv3d->persp==RV3D_CAMOB)
+                                                                                       rv3d->persp= RV3D_PERSP;
+                                                                       }
+                                                               }
+                                                               */
+                                                       }
+                                               }
+                                               sl= sl->next;
+                                       }
+                                       sa= sa->next;
+                               }
+                       }
+               }
+
+               scene->camera= camera;
+
+       }
+#endif
+
        //extern void audiostream_scrub(unsigned int frame);    /* seqaudio.c */
        
        /* this function applies the changes too */
index fe2bc58faf2e148147c9be0afcfff1d51c32cb56..7227c13d37446276a4d5e944dc552b1e0fab0eb8 100644 (file)
@@ -2339,6 +2339,9 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event)
                ScreenAnimData *sad= wt->customdata;
                ScrArea *sa;
                int sync;
+#ifdef DURIAN_CAMERA_SWITCH
+               Object *camera_orig= scene->camera;
+#endif
                
                /* sync, don't sync, or follow scene setting */
                if(sad->flag & ANIMPLAY_FLAG_SYNC) sync= 1;
@@ -2397,10 +2400,11 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event)
                }
                
                /* since we follow drawflags, we can't send notifier but tag regions ourselves */
+
                ED_update_for_newframe(C, 1);
                
                sound_update_playing(C);
-               
+
                for(sa= screen->areabase.first; sa; sa= sa->next) {
                        ARegion *ar;
                        for(ar= sa->regionbase.first; ar; ar= ar->next) {
index 321430158851c98bbfa740704be5663a13de71a8..0ed8aba056a9b4a39d418cfd3800d89483e70d2b 100644 (file)
@@ -29,6 +29,9 @@
 #ifndef DNA_SCENE_TYPES_H
 #define DNA_SCENE_TYPES_H
 
+// XXX, temp feature
+#define DURIAN_CAMERA_SWITCH
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -488,6 +491,7 @@ typedef struct TimeMarker {
        int frame;
        char name[64];
        unsigned int flag;
+       struct Object *camera;
 } TimeMarker;
 
 typedef struct Paint {
index 1eb864e173db59630499bcfe4e486493911c48c6..92a8945af2efd714392c470a02c591830f1e37d6 100644 (file)
@@ -2503,6 +2503,12 @@ static void do_render_seq(Render * re)
 /* main loop: doing sequence + fields + blur + 3d render + compositing */
 static void do_render_all_options(Render *re)
 {
+#ifdef DURIAN_CAMERA_SWITCH
+       Object *camera= scene_find_camera_switch(re->scene);
+       if(camera)
+               re->scene->camera= camera;
+#endif
+
        re->i.starttime= PIL_check_seconds_timer();
 
        /* ensure no images are in memory from previous animated sequences */