2.5
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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user