diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_view.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 289 |
1 files changed, 163 insertions, 126 deletions
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 5a7edfe4140..b227d32d987 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -111,17 +111,43 @@ float *give_cursor(Scene *scene, View3D *v3d) /* ****************** smooth view operator ****************** */ /* This operator is one of the 'timer refresh' ones like animation playback */ +struct SmoothView3DState { + float dist; + float lens; + float quat[4]; + float ofs[3]; +}; + struct SmoothView3DStore { - float orig_dist, new_dist; - float orig_lens, new_lens; - float orig_quat[4], new_quat[4]; - float orig_ofs[3], new_ofs[3]; - - int to_camera, orig_view; - + /* source*/ + struct SmoothView3DState src; /* source */ + struct SmoothView3DState dst; /* destination */ + struct SmoothView3DState org; /* original */ + + bool to_camera; + char org_view; + double time_allowed; }; +static void view3d_smooth_view_state_backup(struct SmoothView3DState *sms_state, + const View3D *v3d, const RegionView3D *rv3d) +{ + copy_v3_v3(sms_state->ofs, rv3d->ofs); + copy_qt_qt(sms_state->quat, rv3d->viewquat); + sms_state->dist = rv3d->dist; + sms_state->lens = v3d->lens; +} + +static void view3d_smooth_view_state_restore(const struct SmoothView3DState *sms_state, + View3D *v3d, RegionView3D *rv3d) +{ + copy_v3_v3(rv3d->ofs, sms_state->ofs); + copy_qt_qt(rv3d->viewquat, sms_state->quat); + rv3d->dist = sms_state->dist; + v3d->lens = sms_state->lens; +} + /* will start timer if appropriate */ /* the arguments are the desired situation */ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, @@ -132,15 +158,22 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera ScrArea *sa = CTX_wm_area(C); RegionView3D *rv3d = ar->regiondata; - struct SmoothView3DStore sms = {0}; - short ok = FALSE; + struct SmoothView3DStore sms = {{0}}; + bool ok = false; /* initialize sms */ - copy_v3_v3(sms.new_ofs, rv3d->ofs); - copy_qt_qt(sms.new_quat, rv3d->viewquat); - sms.new_dist = rv3d->dist; - sms.new_lens = v3d->lens; - sms.to_camera = FALSE; + view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d); + view3d_smooth_view_state_backup(&sms.src, v3d, rv3d); + /* if smoothview runs multiple times... */ + if (rv3d->sms == NULL) { + view3d_smooth_view_state_backup(&sms.org, v3d, rv3d); + sms.org_view = rv3d->view; + } + else { + sms.org = rv3d->sms->org; + sms.org_view = rv3d->sms->org_view; + } + /* sms.to_camera = false; */ /* initizlized to zero anyway */ /* note on camera locking, this is a little confusing but works ok. * we may be changing the view 'as if' there is no active camera, but in fact @@ -155,50 +188,43 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera } /* store the options we want to end with */ - if (ofs) copy_v3_v3(sms.new_ofs, ofs); - if (quat) copy_qt_qt(sms.new_quat, quat); - if (dist) sms.new_dist = *dist; - if (lens) sms.new_lens = *lens; + if (ofs) copy_v3_v3(sms.dst.ofs, ofs); + if (quat) copy_qt_qt(sms.dst.quat, quat); + if (dist) sms.dst.dist = *dist; + if (lens) sms.dst.lens = *lens; if (camera) { - sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK); - ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); - sms.to_camera = TRUE; /* restore view3d values in end */ + sms.dst.dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK); + ED_view3d_from_object(camera, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens); + sms.to_camera = true; /* restore view3d values in end */ } if (C && U.smooth_viewtx) { - int changed = FALSE; /* zero means no difference */ + bool changed = false; /* zero means no difference */ if (oldcamera != camera) - changed = TRUE; - else if (sms.new_dist != rv3d->dist) - changed = TRUE; - else if (sms.new_lens != v3d->lens) - changed = TRUE; - else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) - changed = TRUE; - else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) - changed = TRUE; + changed = true; + else if (sms.dst.dist != rv3d->dist) + changed = true; + else if (sms.dst.lens != v3d->lens) + changed = true; + else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs)) + changed = true; + else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat)) + changed = true; /* The new view is different from the old one * so animate the view */ if (changed) { - /* original values */ if (oldcamera) { - sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f); - ED_view3d_from_object(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens); - } - else { - copy_v3_v3(sms.orig_ofs, rv3d->ofs); - copy_qt_qt(sms.orig_quat, rv3d->viewquat); - sms.orig_dist = rv3d->dist; - sms.orig_lens = v3d->lens; + sms.src.dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f); + /* this */ + ED_view3d_from_object(oldcamera, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens); } /* grid draw as floor */ if ((rv3d->viewlock & RV3D_LOCKED) == 0) { /* use existing if exists, means multiple calls to smooth view wont loose the original 'view' setting */ - sms.orig_view = rv3d->sms ? rv3d->sms->orig_view : rv3d->view; rv3d->view = RV3D_VIEW_USER; } @@ -212,8 +238,8 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera float vec1[3] = {0, 0, 1}, vec2[3] = {0, 0, 1}; float q1[4], q2[4]; - invert_qt_qt(q1, sms.new_quat); - invert_qt_qt(q2, sms.orig_quat); + invert_qt_qt(q1, sms.dst.quat); + invert_qt_qt(q2, sms.src.quat); mul_qt_v3(q1, vec1); mul_qt_v3(q2, vec2); @@ -223,43 +249,52 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera } /* ensure it shows correct */ - if (sms.to_camera) rv3d->persp = RV3D_PERSP; + if (sms.to_camera) { + rv3d->persp = RV3D_PERSP; + } rv3d->rflag |= RV3D_NAVIGATING; + /* not essential but in some cases the caller will tag the area for redraw, + * and in that case we can get a ficker of the 'org' user view but we want to see 'src' */ + view3d_smooth_view_state_restore(&sms.src, v3d, rv3d); + /* keep track of running timer! */ - if (rv3d->sms == NULL) + if (rv3d->sms == NULL) { rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d"); + } *rv3d->sms = sms; - if (rv3d->smooth_timer) + if (rv3d->smooth_timer) { WM_event_remove_timer(wm, win, rv3d->smooth_timer); + } /* TIMER1 is hardcoded in keymap */ rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); /* max 30 frs/sec */ - - ok = TRUE; + + ok = true; } } /* if we get here nothing happens */ - if (ok == FALSE) { - if (sms.to_camera == FALSE) { - copy_v3_v3(rv3d->ofs, sms.new_ofs); - copy_qt_qt(rv3d->viewquat, sms.new_quat); - rv3d->dist = sms.new_dist; - v3d->lens = sms.new_lens; + if (ok == false) { + if (sms.to_camera == false) { + copy_v3_v3(rv3d->ofs, sms.dst.ofs); + copy_qt_qt(rv3d->viewquat, sms.dst.quat); + rv3d->dist = sms.dst.dist; + v3d->lens = sms.dst.lens; ED_view3d_camera_lock_sync(v3d, rv3d); } - if (rv3d->viewlock & RV3D_BOXVIEW) + if (rv3d->viewlock & RV3D_BOXVIEW) { view3d_boxview_copy(sa, ar); + } ED_region_tag_redraw(ar); } } /* only meant for timer usage */ -static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -281,22 +316,16 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent /* if we went to camera, store the original */ if (sms->to_camera) { rv3d->persp = RV3D_CAMOB; - copy_v3_v3(rv3d->ofs, sms->orig_ofs); - copy_qt_qt(rv3d->viewquat, sms->orig_quat); - rv3d->dist = sms->orig_dist; - v3d->lens = sms->orig_lens; + view3d_smooth_view_state_restore(&sms->org, v3d, rv3d); } else { - copy_v3_v3(rv3d->ofs, sms->new_ofs); - copy_qt_qt(rv3d->viewquat, sms->new_quat); - rv3d->dist = sms->new_dist; - v3d->lens = sms->new_lens; + view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d); ED_view3d_camera_lock_sync(v3d, rv3d); } if ((rv3d->viewlock & RV3D_LOCKED) == 0) { - rv3d->view = sms->orig_view; + rv3d->view = sms->org_view; } MEM_freeN(rv3d->sms); @@ -312,11 +341,11 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent step_inv = 1.0f - step; - interp_v3_v3v3(rv3d->ofs, sms->orig_ofs, sms->new_ofs, step); - interp_qt_qtqt(rv3d->viewquat, sms->orig_quat, sms->new_quat, step); + interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step); + interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step); - rv3d->dist = sms->new_dist * step + sms->orig_dist * step_inv; - v3d->lens = sms->new_lens * step + sms->orig_lens * step_inv; + rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv; + v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv; ED_view3d_camera_lock_sync(v3d, rv3d); } @@ -325,12 +354,16 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent view3d_boxview_copy(CTX_wm_area(C), CTX_wm_region(C)); /* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636, - * when switching camera in quad-view the other ortho views would zoom & reset. */ -#if 0 - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); -#else - ED_region_tag_redraw(CTX_wm_region(C)); -#endif + * when switching camera in quad-view the other ortho views would zoom & reset. + * + * For now only redraw all regions when smoothview finishes. + */ + if (step >= 1.0f) { + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); + } + else { + ED_region_tag_redraw(CTX_wm_region(C)); + } return OPERATOR_FINISHED; } @@ -427,7 +460,7 @@ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(o /* only touch location */ BKE_object_tfm_protected_backup(camera_ob, &obtfm); - BKE_object_apply_mat4(camera_ob, obmat_new, TRUE, TRUE); + BKE_object_apply_mat4(camera_ob, obmat_new, true, true); BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D); /* notifiers */ @@ -446,7 +479,7 @@ static int view3d_camera_to_view_selected_poll(bContext *C) if (v3d && v3d->camera && v3d->camera->id.lib == NULL) { RegionView3D *rv3d = CTX_wm_region_view3d(C); if (rv3d) { - if (rv3d->is_persp == FALSE) { + if (rv3d->is_persp == false) { CTX_wm_operator_poll_msg_set(C, "Only valid for a perspective camera view"); } else if (!rv3d->viewlock) { @@ -579,7 +612,7 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co } -int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], BoundBox *bb) +bool ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], const BoundBox *bb) { /* return 1: draw */ @@ -587,8 +620,8 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], BoundBox *bb) float vec[4], min, max; int a, flag = -1, fl; - if (bb == NULL) return 1; - if (bb->flag & OB_BB_DISABLED) return 1; + if (bb == NULL) return true; + if (bb->flag & OB_BB_DISABLED) return true; mult_m4_m4m4(mat, rv3d->persmat, obmat); @@ -608,10 +641,10 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[4][4], BoundBox *bb) if (vec[2] > max) fl += 32; flag &= fl; - if (flag == 0) return 1; + if (flag == 0) return true; } - return 0; + return false; } float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y) @@ -630,26 +663,33 @@ float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y) void ED_view3d_depth_tag_update(RegionView3D *rv3d) { if (rv3d->depths) - rv3d->depths->damaged = 1; + rv3d->depths->damaged = true; } /* copies logic of get_view3d_viewplane(), keep in sync */ -int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend) +bool ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *r_clipsta, float *r_clipend, + const bool use_ortho_factor) { CameraParams params; BKE_camera_params_init(¶ms); BKE_camera_params_from_view3d(¶ms, v3d, rv3d); - if (clipsta) *clipsta = params.clipsta; - if (clipend) *clipend = params.clipend; + if (use_ortho_factor && params.is_ortho) { + const float fac = 2.0f / (params.clipend - params.clipsta); + params.clipsta *= fac; + params.clipend *= fac; + } + + if (r_clipsta) *r_clipsta = params.clipsta; + if (r_clipend) *r_clipend = params.clipend; return params.is_ortho; } /* also exposed in previewrender.c */ -int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, - rctf *viewplane, float *clipsta, float *clipend) +bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, + rctf *r_viewplane, float *r_clipsta, float *r_clipend) { CameraParams params; @@ -657,9 +697,9 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy, BKE_camera_params_from_view3d(¶ms, v3d, rv3d); BKE_camera_params_compute_viewplane(¶ms, winx, winy, 1.0f, 1.0f); - if (viewplane) *viewplane = params.viewplane; - if (clipsta) *clipsta = params.clipsta; - if (clipend) *clipend = params.clipend; + if (r_viewplane) *r_viewplane = params.viewplane; + if (r_clipsta) *r_clipsta = params.clipsta; + if (r_clipend) *r_clipend = params.clipend; return params.is_ortho; } @@ -758,7 +798,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short #define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0 -int ED_view3d_lock(RegionView3D *rv3d) +bool ED_view3d_lock(RegionView3D *rv3d) { switch (rv3d->view) { case RV3D_VIEW_BOTTOM: @@ -785,10 +825,10 @@ int ED_view3d_lock(RegionView3D *rv3d) QUATSET(rv3d->viewquat, 0.5, -0.5, -0.5, -0.5); break; default: - return FALSE; + return false; } - return TRUE; + return true; } /* don't set windows active in here, is used by renderwin too */ @@ -830,7 +870,9 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) copy_v3_v3(vec, give_cursor(scene, v3d)); translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); } - else translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); + else { + translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); + } } } @@ -846,7 +888,8 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b ARegion *ar = vc->ar; rctf rect; short code, hits; - char dt, dtx; + char dt; + short dtx; G.f |= G_PICKSEL; @@ -908,7 +951,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b Base tbase; tbase.flag = OB_FROMDUPLI; - lb = object_duplilist(scene, base->object, FALSE); + lb = object_duplilist(scene, base->object, false); for (dob = lb->first; dob; dob = dob->next) { tbase.object = dob->ob; @@ -932,7 +975,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b } } } - v3d->xray = FALSE; /* restore */ + v3d->xray = false; /* restore */ } glPopName(); /* see above (pushname) */ @@ -1030,14 +1073,14 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active) return lay; } -static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportList *reports) +static bool view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportList *reports) { View3D *v3d = sa->spacedata.first; Base *base; float min[3], max[3], box[3]; float size = 0.0f, size_persp = 0.0f, size_ortho = 0.0f; unsigned int locallay; - int ok = FALSE; + bool ok = false; if (v3d->localvd) { return ok; @@ -1049,13 +1092,13 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL if (locallay == 0) { BKE_report(reports, RPT_ERROR, "No more than 8 local views"); - ok = FALSE; + ok = false; } else { if (scene->obedit) { - BKE_object_minmax(scene->obedit, min, max, FALSE); + BKE_object_minmax(scene->obedit, min, max, false); - ok = TRUE; + ok = true; BASACT->lay |= locallay; scene->obedit->lay = BASACT->lay; @@ -1063,18 +1106,16 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL else { for (base = FIRSTBASE; base; base = base->next) { if (TESTBASE(v3d, base)) { - BKE_object_minmax(base->object, min, max, FALSE); + BKE_object_minmax(base->object, min, max, false); base->lay |= locallay; base->object->lay = base->lay; - ok = TRUE; + ok = true; } } } - - box[0] = (max[0] - min[0]); - box[1] = (max[1] - min[1]); - box[2] = (max[2] - min[2]); - size = MAX3(box[0], box[1], box[2]); + + sub_v3_v3v3(box, max, min); + size = max_fff(box[0], box[1], box[2]); /* do not zoom closer than the near clipping plane */ size = max_ff(size, v3d->near * 1.5f); @@ -1084,7 +1125,7 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL size_ortho = ED_view3d_radius_to_ortho_dist(v3d->lens, size / 2.0f) * VIEW3D_MARGIN; } - if (ok == TRUE) { + if (ok == true) { ARegion *ar; v3d->localvd = MEM_mallocN(sizeof(View3D), "localview"); @@ -1179,7 +1220,7 @@ static void restore_localviewdata(ScrArea *sa, int free) } } -static int view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa) +static bool view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa) { View3D *v3d = sa->spacedata.first; struct Base *base; @@ -1206,12 +1247,12 @@ static int view3d_localview_exit(Main *bmain, Scene *scene, ScrArea *sa) } } - DAG_on_visible_update(bmain, FALSE); + DAG_on_visible_update(bmain, false); - return TRUE; + return true; } else { - return FALSE; + return false; } } @@ -1221,7 +1262,7 @@ static int localview_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); ScrArea *sa = CTX_wm_area(C); View3D *v3d = CTX_wm_view3d(C); - int change; + bool change; if (v3d->localvd) { change = view3d_localview_exit(bmain, scene, sa); @@ -1362,7 +1403,7 @@ static int game_engine_poll(bContext *C) return 1; } -int ED_view3d_context_activate(bContext *C) +bool ED_view3d_context_activate(bContext *C) { bScreen *sc = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); @@ -1375,20 +1416,20 @@ int ED_view3d_context_activate(bContext *C) break; if (!sa) - return 0; + return false; for (ar = sa->regionbase.first; ar; ar = ar->next) if (ar->regiontype == RGN_TYPE_WINDOW) break; if (!ar) - return 0; + return false; /* bad context switch .. */ CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); - return 1; + return true; } static int game_engine_exec(bContext *C, wmOperator *op) @@ -1425,7 +1466,7 @@ static int game_engine_exec(bContext *C, wmOperator *op) { /* Letterbox */ rctf cam_framef; - ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, FALSE); + ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, false); cam_frame.xmin = cam_framef.xmin + ar->winrct.xmin; cam_frame.xmax = cam_framef.xmax + ar->winrct.xmin; cam_frame.ymin = cam_framef.ymin + ar->winrct.ymin; @@ -1526,11 +1567,7 @@ static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) { - return (rv3d->persmat[3][3] + ( - rv3d->persmat[0][3] * co[0] + - rv3d->persmat[1][3] * co[1] + - rv3d->persmat[2][3] * co[2]) - ) * rv3d->pixsize; + return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize; } float ED_view3d_radius_to_persp_dist(const float angle, const float radius) |