Brought back 'smooth view'. Took some hours to untangle it all,
code was spread all over, instead of localized in 1 call. Tsk!
Still not perfect, but at least more in control. For the hackers;
check void smooth_view() in view3d_view.c, here all 3d view
stuff should be handled, so it can optionally use animating.

For the users: 'smooth view' now plays at a maximum of 30 hz,
and doesn't block anymore. So even slow animated views remain
responsive if you press many numpad keys.
This commit is contained in:
Ton Roosendaal
2008-12-26 18:15:46 +00:00
parent ce733db5cb
commit 6086c31fd3
8 changed files with 295 additions and 307 deletions

View File

@@ -4248,6 +4248,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
v3d->clipbb= newdataadr(fd, v3d->clipbb);
v3d->retopo_view_data= NULL;
v3d->properties_storage= NULL;
v3d->sms= NULL;
v3d->smooth_timer= NULL;
}
else if (sl->spacetype==SPACE_OOPS) {
SpaceOops *soops= (SpaceOops*) sl;

View File

@@ -724,24 +724,13 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.
new_dist*= size;
}
if (v3d->persp==V3D_CAMOB && v3d->camera) {
/* switch out of camera view */
float orig_lens= v3d->lens;
if (v3d->persp==V3D_CAMOB) {
v3d->persp= V3D_PERSP;
v3d->dist= 0.0;
view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, new_ofs, NULL, &new_dist, &orig_lens); /* TODO - this dosnt work yet */
} else {
if(v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP;
smooth_view(v3d, new_ofs, NULL, &new_dist, NULL); /* TODO - this dosnt work yet */
smooth_view(C, NULL, v3d->camera, new_ofs, NULL, &new_dist, NULL);
}
}
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
@@ -861,24 +850,16 @@ static int viewcenter_exec(bContext *C, wmOperator *op) /* like a localview with
v3d->cursor[1]= -new_ofs[1];
v3d->cursor[2]= -new_ofs[2];
if (v3d->persp==V3D_CAMOB && v3d->camera) {
float orig_lens= v3d->lens;
v3d->persp=V3D_PERSP;
v3d->dist= 0.0f;
view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, new_ofs, NULL, &new_dist, &orig_lens);
} else {
if(v3d->persp==V3D_CAMOB)
v3d->persp= V3D_PERSP;
smooth_view(v3d, new_ofs, NULL, &new_dist, NULL);
if (v3d->persp==V3D_CAMOB) {
v3d->persp= V3D_PERSP;
smooth_view(C, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL);
}
else {
smooth_view(C, NULL, NULL, new_ofs, NULL, &new_dist, NULL);
}
// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
ED_region_tag_redraw(ar);
return OPERATOR_FINISHED;
}
void VIEW3D_OT_viewcenter(wmOperatorType *ot)
@@ -914,56 +895,47 @@ static EnumPropertyItem prop_view_items[] = {
{V3D_VIEW_PANDOWN, "PANDOWN", "Pan Down", "Pan the view Down"},
{0, NULL, NULL, NULL}};
static void axis_set_view(View3D *v3d, float q1, float q2, float q3, float q4, short view, int perspo)
static void axis_set_view(bContext *C, View3D *v3d, float q1, float q2, float q3, float q4, short view, int perspo)
{
float new_quat[4];
new_quat[0]= q1; new_quat[1]= q2;
new_quat[2]= q3; new_quat[3]= q4;
v3d->view=0;
if (v3d->persp==V3D_CAMOB && v3d->camera) {
/* Is this switching from a camera view ? */
float orig_ofs[3];
float orig_lens= v3d->lens;
VECCOPY(orig_ofs, v3d->ofs);
view_settings_from_ob(v3d->camera, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens);
if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_ORTHO;
else if(v3d->persp==V3D_CAMOB) v3d->persp= perspo;
smooth_view(v3d, orig_ofs, new_quat, NULL, &orig_lens);
} else {
if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_ORTHO;
else if(v3d->persp==V3D_CAMOB) v3d->persp= perspo;
smooth_view(v3d, NULL, new_quat, NULL, NULL);
}
v3d->view= view;
if (v3d->persp==V3D_CAMOB && v3d->camera) {
if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_ORTHO;
else if(v3d->persp==V3D_CAMOB) v3d->persp= perspo;
smooth_view(C, v3d->camera, NULL, v3d->ofs, new_quat, NULL, NULL);
}
else {
if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_ORTHO;
else if(v3d->persp==V3D_CAMOB) v3d->persp= perspo;
smooth_view(C, NULL, NULL, NULL, new_quat, NULL, NULL);
}
}
static int viewnumpad_exec(bContext *C, wmOperator *op)
{
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= CTX_wm_region(C);
View3D *v3d= sa->spacedata.first;
Scene *scene= CTX_data_scene(C);
Object *act_cam_orig=NULL;
float phi, si, q1[4], vec[3];
static int perspo=V3D_PERSP;
float orig_ofs[3];
int viewnum;
viewnum = RNA_enum_get(op->ptr, "viewnum");
/* Use this to test if we started out with a camera */
if (v3d->persp == V3D_CAMOB)
act_cam_orig = v3d->camera;
/* Indicate that this view is inverted,
* but only if it actually _was_ inverted (jobbe) */
if (viewnum == V3D_VIEW_BOTTOM || viewnum == V3D_VIEW_BACK || viewnum == V3D_VIEW_LEFT)
@@ -973,50 +945,36 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
switch (viewnum) {
case V3D_VIEW_BOTTOM :
axis_set_view(v3d,0.0, -1.0, 0.0, 0.0, 7, perspo);
axis_set_view(C, v3d, 0.0, -1.0, 0.0, 0.0, 7, perspo);
break;
case V3D_VIEW_BACK:
axis_set_view(v3d,0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0), 1, perspo);
axis_set_view(C, v3d, 0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0), 1, perspo);
break;
case V3D_VIEW_LEFT:
axis_set_view(v3d,0.5, -0.5, 0.5, 0.5, 3, perspo);
axis_set_view(C, v3d, 0.5, -0.5, 0.5, 0.5, 3, perspo);
break;
case V3D_VIEW_TOP:
axis_set_view(v3d,1.0, 0.0, 0.0, 0.0, 7, perspo);
axis_set_view(C, v3d, 1.0, 0.0, 0.0, 0.0, 7, perspo);
break;
case V3D_VIEW_FRONT:
axis_set_view(v3d,(float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0, 1, perspo);
axis_set_view(C, v3d, (float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0, 1, perspo);
break;
case V3D_VIEW_RIGHT:
axis_set_view(v3d,0.5, -0.5, -0.5, -0.5, 3, perspo);
axis_set_view(C, v3d, 0.5, -0.5, -0.5, -0.5, 3, perspo);
break;
case V3D_VIEW_PERSPORTHO:
if (U.smooth_viewtx) {
if(v3d->persp==V3D_PERSP) { v3d->persp=V3D_ORTHO;
} else if (act_cam_orig) {
/* were from a camera view */
float orig_dist= v3d->dist;
float orig_lens= v3d->lens;
VECCOPY(orig_ofs, v3d->ofs);
v3d->persp=V3D_PERSP;
v3d->dist= 0.0;
if(v3d->persp!=V3D_ORTHO)
v3d->persp=V3D_ORTHO;
else v3d->persp=V3D_PERSP;
view_settings_from_ob(act_cam_orig, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, orig_ofs, NULL, &orig_dist, &orig_lens);
} else {
v3d->persp=V3D_PERSP;
}
} else {
if(v3d->persp==V3D_PERSP) v3d->persp=V3D_ORTHO;
else v3d->persp=V3D_PERSP;
}
ED_region_tag_redraw(ar);
break;
case V3D_VIEW_CAMERA:
@@ -1027,48 +985,36 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
QUATCOPY(v3d->lviewquat, v3d->viewquat);
v3d->lview= v3d->view;
v3d->lpersp= v3d->persp;
#if 0
if(G.qual==LR_ALTKEY) {
if(oldcamera && is_an_active_object(oldcamera)) {
v3d->camera= oldcamera;
}
handle_view3d_lock();
}
#endif
if(BASACT) {
/* check both G.vd as G.scene cameras */
if((v3d->camera==NULL || scene->camera==NULL) && OBACT->type==OB_CAMERA) {
v3d->camera= OBACT;
/*handle_view3d_lock();*/
}
}
if(v3d->camera==NULL) {
v3d->camera= scene_find_camera(scene);
/*handle_view3d_lock();*/
}
v3d->persp= V3D_CAMOB;
smooth_view(C, NULL, v3d->camera, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens);
}
else{
/* return to settings of last view */
axis_set_view(v3d,v3d->lviewquat[0], v3d->lviewquat[1], v3d->lviewquat[2], v3d->lviewquat[3], v3d->lview, v3d->lpersp);
}
#if 0
if(G.qual==LR_ALTKEY) {
if(oldcamera && is_an_active_object(oldcamera)) {
v3d->camera= oldcamera;
}
handle_view3d_lock();
}
#endif
if(BASACT) {
/* check both G.vd as G.scene cameras */
if((v3d->camera==NULL || scene->camera==NULL) && OBACT->type==OB_CAMERA) {
v3d->camera= OBACT;
/*handle_view3d_lock();*/
}
}
if(v3d->camera==0) {
v3d->camera= scene_find_camera(scene);
/*handle_view3d_lock();*/
}
if(v3d->camera && (v3d->camera != act_cam_orig)) {
v3d->persp= V3D_CAMOB;
v3d->view= 0;
} else if (U.smooth_viewtx) {
/* move 3d view to camera view */
float orig_lens = v3d->lens;
VECCOPY(orig_ofs, v3d->ofs);
if (act_cam_orig)
view_settings_from_ob(act_cam_orig, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens);
smooth_view_to_camera(v3d);
VECCOPY(v3d->ofs, orig_ofs);
v3d->lens = orig_lens;
/* does smooth_view too */
axis_set_view(C, v3d, v3d->lviewquat[0], v3d->lviewquat[1], v3d->lviewquat[2], v3d->lviewquat[3], v3d->lview, v3d->lpersp);
}
break;
@@ -1104,6 +1050,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
QuatMul(v3d->viewquat, v3d->viewquat, q1);
v3d->view= 0;
}
ED_region_tag_redraw(ar);
}
break;
@@ -1122,6 +1069,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
v3d->ofs[1]+= vec[1];
v3d->ofs[2]+= vec[2];
ED_region_tag_redraw(ar);
break;
default :
@@ -1130,9 +1078,6 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
if(v3d->persp != V3D_CAMOB) perspo= v3d->persp;
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
return OPERATOR_FINISHED;
}
@@ -1416,7 +1361,7 @@ void view3d_border_zoom(Scene *scene, ARegion *ar, View3D *v3d)
new_dist = ((new_dist*scale) >= 0.001*v3d->grid)? new_dist*scale:0.001*v3d->grid;
}
smooth_view(v3d, new_ofs, NULL, &new_dist, NULL);
smooth_view(NULL, NULL, NULL, new_ofs, NULL, &new_dist, NULL); // XXX
}

View File

@@ -259,30 +259,12 @@ static void do_view3d_view_camerasmenu(bContext *C, void *arg, int event)
if (v3d->camera == base->object && v3d->persp==V3D_CAMOB)
return;
if (U.smooth_viewtx) {
/* move 3d view to camera view */
float orig_ofs[3], orig_lens = v3d->lens;
VECCOPY(orig_ofs, v3d->ofs);
if (v3d->camera && v3d->persp==V3D_CAMOB)
view_settings_from_ob(v3d->camera, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens);
v3d->camera = base->object;
handle_view3d_lock();
v3d->persp= V3D_CAMOB;
v3d->view= 0;
smooth_view_to_camera(v3d);
/* restore values */
VECCOPY(v3d->ofs, orig_ofs);
v3d->lens = orig_lens;
} else {
v3d->camera= base->object;
handle_view3d_lock();
v3d->persp= V3D_CAMOB;
v3d->view= 0;
}
/* XXX handle smooth view */
v3d->camera= base->object;
handle_view3d_lock();
v3d->persp= V3D_CAMOB;
v3d->view= 0;
break;
}
}

View File

@@ -118,6 +118,8 @@ void VIEW3D_OT_borderselect(struct wmOperatorType *ot);
void VIEW3D_OT_circle_select(struct wmOperatorType *ot);
/* view3d_view.c */
void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
void view3d_operator_needs_opengl(const struct bContext *C);
void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]);
void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]);
@@ -152,8 +154,7 @@ void centerview(ARegion *ar, View3D *v3d);
void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3]);
void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens);
void smooth_view_to_camera(View3D *v3d);
void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat, float *dist, float *lens);
void setwinmatrixview3d(View3D *v3d, int winx, int winy, rctf *rect); /* rect: for picking */
void setviewmatrixview3d(View3D *v3d);

View File

@@ -71,6 +71,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_borderselect);
WM_operatortype_append(VIEW3D_OT_clipping);
WM_operatortype_append(VIEW3D_OT_circle_select);
WM_operatortype_append(VIEW3D_OT_smoothview);
}
void view3d_keymap(wmWindowManager *wm)
@@ -82,6 +83,8 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "VIEW3D_OT_viewzoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_viewcenter", PADPERIOD, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1);
RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", WHEELUPMOUSE, KM_ANY, 0, 0)->ptr, "delta", 1);

View File

@@ -64,6 +64,7 @@
#include "BIF_gl.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_screen.h"
@@ -77,6 +78,8 @@
#define BL_NEAR_CLIP 0.001
/* use this call when executing an operator,
event system doesn't set for each event the
opengl drawing context */
@@ -105,6 +108,201 @@ float *give_cursor(Scene *scene, View3D *v3d)
else return scene->cursor;
}
/* ****************** smooth view operator ****************** */
struct SmoothViewStore {
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;
double time_allowed;
};
/* will start timer if appropriate */
/* the arguments are the desired situation */
void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, float *quat, float *dist, float *lens)
{
View3D *v3d= (View3D *)CTX_wm_space_data(C);
struct SmoothViewStore sms;
/* initialize sms */
VECCOPY(sms.new_ofs, v3d->ofs);
QUATCOPY(sms.new_quat, v3d->viewquat);
sms.new_dist= v3d->dist;
sms.new_lens= v3d->lens;
sms.to_camera= 0;
/* store the options we want to end with */
if(ofs) VECCOPY(sms.new_ofs, ofs);
if(quat) QUATCOPY(sms.new_quat, quat);
if(dist) sms.new_dist= *dist;
if(lens) sms.new_lens= *lens;
if (camera) {
view_settings_from_ob(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens);
sms.to_camera= 1; /* restore view3d values in end */
}
if (C && U.smooth_viewtx) {
int changed = 0; /* zero means no difference */
if (sms.new_dist != v3d->dist)
changed = 1;
if (sms.new_lens != v3d->lens)
changed = 1;
if ((sms.new_ofs[0]!=v3d->ofs[0]) ||
(sms.new_ofs[1]!=v3d->ofs[1]) ||
(sms.new_ofs[2]!=v3d->ofs[2]) )
changed = 1;
if ((sms.new_quat[0]!=v3d->viewquat[0]) ||
(sms.new_quat[1]!=v3d->viewquat[1]) ||
(sms.new_quat[2]!=v3d->viewquat[2]) ||
(sms.new_quat[3]!=v3d->viewquat[3]) )
changed = 1;
/* The new view is different from the old one
* so animate the view */
if (changed) {
sms.time_allowed= (double)U.smooth_viewtx / 1000.0;
/* if this is view rotation only
* we can decrease the time allowed by
* the angle between quats
* this means small rotations wont lag */
if (quat && !ofs && !dist) {
float vec1[3], vec2[3];
VECCOPY(vec1, sms.new_quat);
VECCOPY(vec2, sms.orig_quat);
Normalize(vec1);
Normalize(vec2);
/* scale the time allowed by the rotation */
sms.time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2);
}
/* original values */
if (oldcamera) {
sms.orig_dist= v3d->dist; // below function does weird stuff with it...
view_settings_from_ob(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens);
}
else {
VECCOPY(sms.orig_ofs, v3d->ofs);
QUATCOPY(sms.orig_quat, v3d->viewquat);
sms.orig_dist= v3d->dist;
sms.orig_lens= v3d->lens;
}
/* grid draw as floor */
sms.orig_view= v3d->view;
v3d->view= 0;
/* ensure it shows correct */
if(sms.to_camera) v3d->persp= V3D_PERSP;
/* keep track of running timer! */
if(v3d->sms==NULL)
v3d->sms= MEM_mallocN(sizeof(struct SmoothViewStore), "smoothview v3d");
*v3d->sms= sms;
if(v3d->smooth_timer)
WM_event_remove_window_timer(CTX_wm_window(C), v3d->smooth_timer);
/* TIMER1 is hardcoded in keymap */
v3d->smooth_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frs/sec */
return;
}
}
/* if we get here nothing happens */
if(sms.to_camera==0) {
VECCOPY(v3d->ofs, sms.new_ofs);
QUATCOPY(v3d->viewquat, sms.new_quat);
v3d->dist = sms.new_dist;
v3d->lens = sms.new_lens;
}
ED_region_tag_redraw(CTX_wm_region(C));
}
/* only meant for timer usage */
static int view3d_smoothview_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
View3D *v3d= (View3D *)CTX_wm_space_data(C);
struct SmoothViewStore *sms= v3d->sms;
double step, step_inv;
/* escape if not our timer */
if(v3d->smooth_timer==NULL || v3d->smooth_timer!=event->customdata)
return OPERATOR_PASS_THROUGH;
step = (v3d->smooth_timer->duration)/sms->time_allowed;
/* end timer */
if(step >= 1.0f) {
/* if we went to camera, store the original */
if(sms->to_camera) {
v3d->persp= V3D_CAMOB;
VECCOPY(v3d->ofs, sms->orig_ofs);
QUATCOPY(v3d->viewquat, sms->orig_quat);
v3d->dist = sms->orig_dist;
v3d->lens = sms->orig_lens;
}
else {
VECCOPY(v3d->ofs, sms->new_ofs);
QUATCOPY(v3d->viewquat, sms->new_quat);
v3d->dist = sms->new_dist;
v3d->lens = sms->new_lens;
}
v3d->view= sms->orig_view;
MEM_freeN(v3d->sms);
v3d->sms= NULL;
WM_event_remove_window_timer(CTX_wm_window(C), v3d->smooth_timer);
v3d->smooth_timer= NULL;
}
else {
int i;
/* ease in/out */
if (step < 0.5) step = (float)pow(step*2, 2)/2;
else step = (float)1-(pow(2*(1-step),2)/2);
step_inv = 1.0-step;
for (i=0; i<3; i++)
v3d->ofs[i] = sms->new_ofs[i]*step + sms->orig_ofs[i]*step_inv;
QuatInterpol(v3d->viewquat, sms->orig_quat, sms->new_quat, step);
v3d->dist = sms->new_dist*step + sms->orig_dist*step_inv;
v3d->lens = sms->new_lens*step + sms->orig_lens*step_inv;
}
ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
void VIEW3D_OT_smoothview(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Smooth View";
ot->idname= "VIEW3D_OT_smoothview";
/* api callbacks */
ot->invoke= view3d_smoothview_invoke;
ot->poll= ED_operator_areaactive;
}
/* ********************************** */
/* create intersection coordinates in view Z direction at mouse coordinates */
void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3])
{
@@ -599,7 +797,7 @@ void setwinmatrixview3d(View3D *v3d, int winx, int winy, rctf *rect) /* rect: f
/* Gets the lens and clipping values from a camera of lamp type object */
static void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend)
static void object_lens_clip_settings(Object *ob, float *lens, float *clipsta, float *clipend)
{
if (!ob) return;
@@ -620,6 +818,9 @@ static void object_view_settings(Object *ob, float *lens, float *clipsta, float
if (clipsta) *clipsta= cam->clipsta;
if (clipend) *clipend= cam->clipend;
}
else {
if (lens) *lens= 35.0f;
}
}
@@ -664,7 +865,7 @@ void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, flo
/* Lens */
if (lens)
object_view_settings(ob, lens, NULL, NULL);
object_lens_clip_settings(ob, lens, NULL, NULL);
}
@@ -698,13 +899,13 @@ void obmat_to_viewmat(View3D *v3d, Object *ob, short smooth)
v3d->dist= 0.0;
view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, orig_ofs, new_quat, &orig_dist, &orig_lens);
smooth_view(NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); // XXX
v3d->persp=V3D_CAMOB; /* just to be polite, not needed */
} else {
Mat3ToQuat(tmat, new_quat);
smooth_view(v3d, NULL, new_quat, NULL, NULL);
smooth_view(NULL, NULL, NULL, NULL, new_quat, NULL, NULL); // XXX
}
} else {
Mat3ToQuat(tmat, v3d->viewquat);
@@ -1096,163 +1297,10 @@ void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3])
v3d->persp= V3D_PERSP;
v3d->dist= 0.0;
view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
smooth_view(v3d, orig_ofs, new_quat, &orig_dist, &orig_lens);
smooth_view(NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); // XXX
} else {
if (v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP; /* switch out of camera mode */
smooth_view(v3d, NULL, new_quat, NULL, NULL);
smooth_view(NULL, NULL, NULL, NULL, new_quat, NULL, NULL); // XXX
}
}
/* SMOOTHVIEW */
void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens)
{
/* View Animation enabled */
if (U.smooth_viewtx) {
int i;
char changed = 0;
float step = 0.0, step_inv;
float orig_dist;
float orig_lens;
float orig_quat[4];
float orig_ofs[3];
double time_allowed, time_current, time_start;
/* if there is no difference, return */
changed = 0; /* zero means no difference */
if (dist) {
if ((*dist) != v3d->dist)
changed = 1;
}
if (lens) {
if ((*lens) != v3d->lens)
changed = 1;
}
if (!changed && ofs) {
if ((ofs[0]!=v3d->ofs[0]) ||
(ofs[1]!=v3d->ofs[1]) ||
(ofs[2]!=v3d->ofs[2]) )
changed = 1;
}
if (!changed && quat ) {
if ((quat[0]!=v3d->viewquat[0]) ||
(quat[1]!=v3d->viewquat[1]) ||
(quat[2]!=v3d->viewquat[2]) ||
(quat[3]!=v3d->viewquat[3]) )
changed = 1;
}
/* The new view is different from the old one
* so animate the view */
if (changed) {
/* store original values */
VECCOPY(orig_ofs, v3d->ofs);
QUATCOPY(orig_quat, v3d->viewquat);
orig_dist = v3d->dist;
orig_lens = v3d->lens;
time_allowed= (float)U.smooth_viewtx / 1000.0;
time_current = time_start = PIL_check_seconds_timer();
/* if this is view rotation only
* we can decrease the time allowed by
* the angle between quats
* this means small rotations wont lag */
if (quat && !ofs && !dist) {
float vec1[3], vec2[3];
VECCOPY(vec1, quat);
VECCOPY(vec2, v3d->viewquat);
Normalize(vec1);
Normalize(vec2);
/* scale the time allowed by the rotation */
time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2);
}
while (time_start + time_allowed > time_current) {
step = (float)((time_current-time_start) / time_allowed);
/* ease in/out */
if (step < 0.5) step = (float)pow(step*2, 2)/2;
else step = (float)1-(pow(2*(1-step),2)/2);
step_inv = 1-step;
if (ofs)
for (i=0; i<3; i++)
v3d->ofs[i] = ofs[i]*step + orig_ofs[i]*step_inv;
if (quat)
QuatInterpol(v3d->viewquat, orig_quat, quat, step);
if (dist)
v3d->dist = ((*dist)*step) + (orig_dist*step_inv);
if (lens)
v3d->lens = ((*lens)*step) + (orig_lens*step_inv);
/*redraw the view*/
// scrarea_do_windraw(ar);
// screen_swapbuffers();
time_current= PIL_check_seconds_timer();
}
}
}
/* set these values even if animation is enabled because flaot
* error will make then not quite accurate */
if (ofs)
VECCOPY(v3d->ofs, ofs);
if (quat)
QUATCOPY(v3d->viewquat, quat);
if (dist)
v3d->dist = *dist;
if (lens)
v3d->lens = *lens;
}
/* For use with smooth view
*
* the current view is unchanged, blend between the current view and the
* camera view
* */
void smooth_view_to_camera(View3D *v3d)
{
if (!U.smooth_viewtx || !v3d->camera || v3d->persp != V3D_CAMOB) {
return;
} else {
Object *ob = v3d->camera;
float orig_ofs[3];
float orig_dist=v3d->dist;
float orig_lens=v3d->lens;
float new_dist=0.0;
float new_lens=35.0;
float new_quat[4];
float new_ofs[3];
VECCOPY(orig_ofs, v3d->ofs);
view_settings_from_ob(ob, new_ofs, new_quat, NULL, &new_lens);
v3d->persp= V3D_PERSP;
smooth_view(v3d, new_ofs, new_quat, &new_dist, &new_lens);
VECCOPY(v3d->ofs, orig_ofs);
v3d->lens= orig_lens;
v3d->dist = orig_dist; /* restore the dist */
v3d->camera = ob;
v3d->persp= V3D_CAMOB;
}
}

View File

@@ -41,6 +41,8 @@ struct BoundBox;
struct RenderInfo;
struct RetopoViewData;
struct bGPdata;
struct SmoothViewStore;
struct wmTimer;
/* This is needed to not let VC choke on near and far... old
* proprietary MS extensions... */
@@ -143,6 +145,10 @@ typedef struct View3D {
void *properties_storage; /* Nkey panel stores stuff here, not in file */
struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */
/* animated smooth view */
struct SmoothViewStore *sms;
struct wmTimer *smooth_timer;
/* last view */
float lviewquat[4];
short lpersp, lview;

View File

@@ -44,6 +44,7 @@
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "ED_screen.h"
#include "ED_space_api.h"
@@ -504,7 +505,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
static int wm_event_always_pass(wmEvent *event)
{
/* some events we always pass on, to ensure proper communication */
return (event->type == TIMER);
return ELEM4(event->type, TIMER, TIMER0, TIMER1, TIMER2);
}
/* Warning: this function removes a modal handler, when finished */