From c3401eb5cb0833dc76eff1e90e573b487181ec81 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 16 Dec 2009 19:49:33 +0000 Subject: camera switching via markers 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 | 3 ++ source/blender/blenkernel/BKE_scene.h | 1 + source/blender/blenkernel/intern/object.c | 11 +++++ source/blender/blenkernel/intern/scene.c | 41 +++++++++++++++++ source/blender/blenloader/intern/readfile.c | 24 +++++++++- source/blender/editors/animation/anim_markers.c | 60 ++++++++++++++++++++++++- source/blender/editors/screen/screen_edit.c | 41 +++++++++++++++++ source/blender/editors/screen/screen_ops.c | 6 ++- source/blender/makesdna/DNA_scene_types.h | 4 ++ source/blender/render/intern/source/pipeline.c | 6 +++ 10 files changed, 193 insertions(+), 4 deletions(-) diff --git a/release/scripts/ui/space_time.py b/release/scripts/ui/space_time.py index 86347f8c543..e328fa9e31b 100644 --- a/release/scripts/ui/space_time.py +++ b/release/scripts/ui/space_time.py @@ -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" diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index ecff62a7952..c372004bd19 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -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); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 6b86c6c2908..9a7a3501031 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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; } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 4312f23bd9b..7bfeac037ce 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -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) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fa878093cc4..17dfb4f7ce6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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) diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 721fa928e44..0d519c87a97 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -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 } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 640a14a934b..9c581527e4c 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -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 */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index fe2bc58faf2..7227c13d374 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -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) { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 32143015885..0ed8aba056a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -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 { diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 1eb864e173d..92a8945af2e 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -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 */ -- cgit v1.2.3