Cleanup: split smooth-view apply into 3 functions

Mixing view interpolation with finishing smooth-view caused arguments
to be passed in that only made sense for one of these cases.
This also makes the intention of the callers clearer.

- view3d_smoothview_apply_with_interp
- view3d_smoothview_apply_and_finish
- view3d_smoothview_apply_from_timer

Also rename 'step' to 'factor` and use `interpf` for blending values.
This commit is contained in:
Campbell Barton 2022-08-09 10:21:42 +10:00
parent 35b0a2f5e7
commit a26b1a299f
1 changed files with 80 additions and 89 deletions

View File

@ -22,13 +22,8 @@
#include "view3d_intern.h"
#include "view3d_navigate.h" /* own include */
static void view3d_smoothview_apply_ex(bContext *C,
View3D *v3d,
ARegion *region,
bool sync_boxview,
bool use_autokey,
const float step,
const bool finished);
static void view3d_smoothview_apply_with_interp(
bContext *C, View3D *v3d, ARegion *region, const bool use_autokey, const float factor);
/* -------------------------------------------------------------------- */
/** \name Smooth View Undo Handling
@ -115,14 +110,9 @@ void ED_view3d_smooth_view_undo_end(bContext *C,
return;
}
/* Arguments to #view3d_smoothview_apply_ex to temporarily apply transformation. */
const bool sync_boxview = false;
const bool use_autokey = false;
const bool finished = false;
/* Fast forward, undo push, then rewind. */
if (is_interactive) {
view3d_smoothview_apply_ex(C, v3d, region_camera, sync_boxview, use_autokey, 1.0f, finished);
view3d_smoothview_apply_with_interp(C, v3d, region_camera, false, 1.0f);
}
RegionView3D *rv3d = region_camera->regiondata;
@ -134,7 +124,7 @@ void ED_view3d_smooth_view_undo_end(bContext *C,
}
if (is_interactive) {
view3d_smoothview_apply_ex(C, v3d, region_camera, sync_boxview, use_autokey, 0.0f, finished);
view3d_smoothview_apply_with_interp(C, v3d, region_camera, false, 0.0f);
}
}
@ -397,110 +387,112 @@ void ED_view3d_smooth_view(bContext *C,
}
}
static void view3d_smoothview_apply_ex(bContext *C,
View3D *v3d,
ARegion *region,
bool sync_boxview,
bool use_autokey,
const float step,
const bool finished)
/**
* Apply with interpolation, on completion run #view3d_smoothview_apply_and_finish.
*/
static void view3d_smoothview_apply_with_interp(
bContext *C, View3D *v3d, ARegion *region, const bool use_autokey, const float factor)
{
RegionView3D *rv3d = region->regiondata;
struct SmoothView3DStore *sms = rv3d->sms;
interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, factor);
if (sms->use_dyn_ofs) {
view3d_orbit_apply_dyn_ofs(
rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
}
else {
interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, factor);
}
rv3d->dist = interpf(sms->dst.dist, sms->src.dist, factor);
v3d->lens = interpf(sms->dst.lens, sms->src.lens, factor);
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
if (use_autokey) {
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
ED_region_tag_redraw(region);
}
/**
* Apply the view-port transformation & free smooth-view related data.
*/
static void view3d_smoothview_apply_and_finish(bContext *C, View3D *v3d, ARegion *region)
{
wmWindowManager *wm = CTX_wm_manager(C);
RegionView3D *rv3d = region->regiondata;
struct SmoothView3DStore *sms = rv3d->sms;
/* end timer */
if (finished) {
wmWindow *win = CTX_wm_window(C);
wmWindow *win = CTX_wm_window(C);
/* if we went to camera, store the original */
if (sms->to_camera) {
rv3d->persp = RV3D_CAMOB;
view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
}
else {
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
rv3d->view = sms->org_view;
}
MEM_freeN(rv3d->sms);
rv3d->sms = NULL;
WM_event_remove_timer(wm, win, rv3d->smooth_timer);
rv3d->smooth_timer = NULL;
rv3d->rflag &= ~RV3D_NAVIGATING;
/* Event handling won't know if a UI item has been moved under the pointer. */
WM_event_add_mousemove(win);
/* if we went to camera, store the original */
if (sms->to_camera) {
rv3d->persp = RV3D_CAMOB;
view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
}
else {
/* ease in/out */
const float step_inv = 1.0f - step;
interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step);
if (sms->use_dyn_ofs) {
view3d_orbit_apply_dyn_ofs(
rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
}
else {
interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step);
}
rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d);
if (use_autokey && ED_screen_animation_playing(wm)) {
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
}
if (sync_boxview && (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW)) {
view3d_boxview_copy(CTX_wm_area(C), region);
if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
rv3d->view = sms->org_view;
}
MEM_freeN(rv3d->sms);
rv3d->sms = NULL;
WM_event_remove_timer(wm, win, rv3d->smooth_timer);
rv3d->smooth_timer = NULL;
rv3d->rflag &= ~RV3D_NAVIGATING;
/* Event handling won't know if a UI item has been moved under the pointer. */
WM_event_add_mousemove(win);
/* 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.
*
* For now only redraw all regions when smooth-view finishes.
*/
if (step >= 1.0f) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
}
else {
ED_region_tag_redraw(region);
}
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
}
/* only meant for timer usage */
static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, bool sync_boxview)
static void view3d_smoothview_apply_from_timer(bContext *C, View3D *v3d, ARegion *region)
{
wmWindowManager *wm = CTX_wm_manager(C);
RegionView3D *rv3d = region->regiondata;
struct SmoothView3DStore *sms = rv3d->sms;
float step;
float factor;
if (sms->time_allowed != 0.0) {
step = (float)((rv3d->smooth_timer->duration) / sms->time_allowed);
factor = (float)((rv3d->smooth_timer->duration) / sms->time_allowed);
}
else {
step = 1.0f;
factor = 1.0f;
}
const bool finished = step >= 1.0f;
if (!finished) {
step = (3.0f * step * step - 2.0f * step * step * step);
if (factor >= 1.0f) {
view3d_smoothview_apply_and_finish(C, v3d, region);
}
else {
/* Ease in/out smoothing. */
factor = (3.0f * factor * factor - 2.0f * factor * factor * factor);
const bool use_autokey = ED_screen_animation_playing(wm);
view3d_smoothview_apply_with_interp(C, v3d, region, use_autokey, factor);
}
if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
view3d_boxview_copy(CTX_wm_area(C), region);
}
view3d_smoothview_apply_ex(C, v3d, region, sync_boxview, true, step, finished);
}
static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
@ -514,7 +506,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w
return OPERATOR_PASS_THROUGH;
}
view3d_smoothview_apply(C, v3d, region, true);
view3d_smoothview_apply_from_timer(C, v3d, region);
return OPERATOR_FINISHED;
}
@ -524,8 +516,7 @@ void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *regio
RegionView3D *rv3d = region->regiondata;
if (rv3d && rv3d->sms) {
rv3d->sms->time_allowed = 0.0; /* force finishing */
view3d_smoothview_apply(C, v3d, region, false);
view3d_smoothview_apply_and_finish(C, v3d, region);
/* force update of view matrix so tools that run immediately after
* can use them without redrawing first */