fix [#33894] Viewport heavily distorted

The SmoothView operator was mixing up source-view and original-view parameters cleanup this operator and add 'original' view settings store.
This commit is contained in:
Campbell Barton
2013-01-17 08:05:48 +00:00
parent c1f6261aee
commit 5f35d91ab5
3 changed files with 93 additions and 70 deletions

View File

@@ -4274,6 +4274,8 @@ void ED_view3d_from_object(Object *ob, float ofs[3], float quat[4], float *dist,
CameraParams params; CameraParams params;
BKE_camera_params_init(&params); BKE_camera_params_init(&params);
/* incase we can't get the lens */
params.lens = *lens;
BKE_camera_params_from_object(&params, ob); BKE_camera_params_from_object(&params, ob);
*lens = params.lens; *lens = params.lens;
} }

View File

@@ -111,17 +111,43 @@ float *give_cursor(Scene *scene, View3D *v3d)
/* ****************** smooth view operator ****************** */ /* ****************** smooth view operator ****************** */
/* This operator is one of the 'timer refresh' ones like animation playback */ /* This operator is one of the 'timer refresh' ones like animation playback */
struct SmoothView3DStore { struct SmoothView3DState {
float orig_dist, new_dist; float dist;
float orig_lens, new_lens; float lens;
float orig_quat[4], new_quat[4]; float quat[4];
float orig_ofs[3], new_ofs[3]; float ofs[3];
};
int to_camera, orig_view; struct SmoothView3DStore {
/* source*/
struct SmoothView3DState src; /* source */
struct SmoothView3DState dst; /* destination */
struct SmoothView3DState org; /* original */
bool to_camera;
char org_view;
double time_allowed; 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 */ /* will start timer if appropriate */
/* the arguments are the desired situation */ /* the arguments are the desired situation */
void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera,
@@ -132,15 +158,14 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
ScrArea *sa = CTX_wm_area(C); ScrArea *sa = CTX_wm_area(C);
RegionView3D *rv3d = ar->regiondata; RegionView3D *rv3d = ar->regiondata;
struct SmoothView3DStore sms = {0}; struct SmoothView3DStore sms = {{0}};
short ok = FALSE; bool ok = false;
/* initialize sms */ /* initialize sms */
copy_v3_v3(sms.new_ofs, rv3d->ofs); view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
copy_qt_qt(sms.new_quat, rv3d->viewquat); view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
sms.new_dist = rv3d->dist; view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
sms.new_lens = v3d->lens; sms.to_camera = false;
sms.to_camera = FALSE;
/* note on camera locking, this is a little confusing but works ok. /* 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 * we may be changing the view 'as if' there is no active camera, but in fact
@@ -155,50 +180,44 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
} }
/* store the options we want to end with */ /* store the options we want to end with */
if (ofs) copy_v3_v3(sms.new_ofs, ofs); if (ofs) copy_v3_v3(sms.dst.ofs, ofs);
if (quat) copy_qt_qt(sms.new_quat, quat); if (quat) copy_qt_qt(sms.dst.quat, quat);
if (dist) sms.new_dist = *dist; if (dist) sms.dst.dist = *dist;
if (lens) sms.new_lens = *lens; if (lens) sms.dst.lens = *lens;
if (camera) { if (camera) {
sms.new_dist = ED_view3d_offset_distance(camera->obmat, ofs, VIEW3D_DIST_FALLBACK); sms.dst.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); 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 */ sms.to_camera = true; /* restore view3d values in end */
} }
if (C && U.smooth_viewtx) { if (C && U.smooth_viewtx) {
int changed = FALSE; /* zero means no difference */ bool changed = false; /* zero means no difference */
if (oldcamera != camera) if (oldcamera != camera)
changed = TRUE; changed = true;
else if (sms.new_dist != rv3d->dist) else if (sms.dst.dist != rv3d->dist)
changed = TRUE; changed = true;
else if (sms.new_lens != v3d->lens) else if (sms.dst.lens != v3d->lens)
changed = TRUE; changed = true;
else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) else if (!equals_v3v3(sms.dst.ofs, rv3d->ofs))
changed = TRUE; changed = true;
else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) else if (!equals_v4v4(sms.dst.quat, rv3d->viewquat))
changed = TRUE; changed = true;
/* The new view is different from the old one /* The new view is different from the old one
* so animate the view */ * so animate the view */
if (changed) { if (changed) {
/* original values */ /* original values */
if (oldcamera) { if (oldcamera) {
sms.orig_dist = ED_view3d_offset_distance(oldcamera->obmat, rv3d->ofs, 0.0f); sms.src.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); /* this */
} ED_view3d_from_object(oldcamera, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.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;
} }
/* grid draw as floor */ /* grid draw as floor */
if ((rv3d->viewlock & RV3D_LOCKED) == 0) { if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
/* use existing if exists, means multiple calls to smooth view wont loose the original 'view' setting */ /* 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; sms.org_view = rv3d->sms ? rv3d->sms->org_view : rv3d->view;
rv3d->view = RV3D_VIEW_USER; rv3d->view = RV3D_VIEW_USER;
} }
@@ -212,8 +231,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 vec1[3] = {0, 0, 1}, vec2[3] = {0, 0, 1};
float q1[4], q2[4]; float q1[4], q2[4];
invert_qt_qt(q1, sms.new_quat); invert_qt_qt(q1, sms.dst.quat);
invert_qt_qt(q2, sms.orig_quat); invert_qt_qt(q2, sms.src.quat);
mul_qt_v3(q1, vec1); mul_qt_v3(q1, vec1);
mul_qt_v3(q2, vec2); mul_qt_v3(q2, vec2);
@@ -223,36 +242,45 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
} }
/* ensure it shows correct */ /* ensure it shows correct */
if (sms.to_camera) rv3d->persp = RV3D_PERSP; if (sms.to_camera) {
rv3d->persp = RV3D_PERSP;
}
rv3d->rflag |= RV3D_NAVIGATING; 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! */ /* keep track of running timer! */
if (rv3d->sms == NULL) if (rv3d->sms == NULL) {
rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d"); rv3d->sms = MEM_mallocN(sizeof(struct SmoothView3DStore), "smoothview v3d");
}
*rv3d->sms = sms; *rv3d->sms = sms;
if (rv3d->smooth_timer) if (rv3d->smooth_timer) {
WM_event_remove_timer(wm, win, rv3d->smooth_timer); WM_event_remove_timer(wm, win, rv3d->smooth_timer);
}
/* TIMER1 is hardcoded in keymap */ /* TIMER1 is hardcoded in keymap */
rv3d->smooth_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 100.0); /* max 30 frs/sec */ 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 we get here nothing happens */
if (ok == FALSE) { if (ok == false) {
if (sms.to_camera == FALSE) { if (sms.to_camera == false) {
copy_v3_v3(rv3d->ofs, sms.new_ofs); copy_v3_v3(rv3d->ofs, sms.dst.ofs);
copy_qt_qt(rv3d->viewquat, sms.new_quat); copy_qt_qt(rv3d->viewquat, sms.dst.quat);
rv3d->dist = sms.new_dist; rv3d->dist = sms.dst.dist;
v3d->lens = sms.new_lens; v3d->lens = sms.dst.lens;
ED_view3d_camera_lock_sync(v3d, rv3d); ED_view3d_camera_lock_sync(v3d, rv3d);
} }
if (rv3d->viewlock & RV3D_BOXVIEW) if (rv3d->viewlock & RV3D_BOXVIEW) {
view3d_boxview_copy(sa, ar); view3d_boxview_copy(sa, ar);
}
ED_region_tag_redraw(ar); ED_region_tag_redraw(ar);
} }
@@ -281,22 +309,16 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
/* if we went to camera, store the original */ /* if we went to camera, store the original */
if (sms->to_camera) { if (sms->to_camera) {
rv3d->persp = RV3D_CAMOB; rv3d->persp = RV3D_CAMOB;
copy_v3_v3(rv3d->ofs, sms->orig_ofs); view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
copy_qt_qt(rv3d->viewquat, sms->orig_quat);
rv3d->dist = sms->orig_dist;
v3d->lens = sms->orig_lens;
} }
else { else {
copy_v3_v3(rv3d->ofs, sms->new_ofs); view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
copy_qt_qt(rv3d->viewquat, sms->new_quat);
rv3d->dist = sms->new_dist;
v3d->lens = sms->new_lens;
ED_view3d_camera_lock_sync(v3d, rv3d); ED_view3d_camera_lock_sync(v3d, rv3d);
} }
if ((rv3d->viewlock & RV3D_LOCKED) == 0) { if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
rv3d->view = sms->orig_view; rv3d->view = sms->org_view;
} }
MEM_freeN(rv3d->sms); MEM_freeN(rv3d->sms);
@@ -312,11 +334,11 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
step_inv = 1.0f - step; step_inv = 1.0f - step;
interp_v3_v3v3(rv3d->ofs, sms->orig_ofs, sms->new_ofs, step); interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step);
interp_qt_qtqt(rv3d->viewquat, sms->orig_quat, sms->new_quat, step); interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step);
rv3d->dist = sms->new_dist * step + sms->orig_dist * step_inv; rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv;
v3d->lens = sms->new_lens * step + sms->orig_lens * step_inv; v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv;
ED_view3d_camera_lock_sync(v3d, rv3d); ED_view3d_camera_lock_sync(v3d, rv3d);
} }
@@ -326,7 +348,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent
/* note: this doesn't work right because the v3d->lens is now used in ortho mode r51636, /* 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. */ * when switching camera in quad-view the other ortho views would zoom & reset. */
#if 0 #if 1
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
#else #else
ED_region_tag_redraw(CTX_wm_region(C)); ED_region_tag_redraw(CTX_wm_region(C));

View File

@@ -5873,7 +5873,6 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2])
int i; int i;
for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) { for (i = 0, sv = sld->sv; i < sld->totsv; i++, sv++) {
/* allow points behind the view [#33643] */
dist = len_squared_v2v2(mval_fl, sv->co_orig_2d); dist = len_squared_v2v2(mval_fl, sv->co_orig_2d);
if (dist < min_dist) { if (dist < min_dist) {
min_dist = dist; min_dist = dist;