2.5
authorTon Roosendaal <ton@blender.org>
Fri, 26 Dec 2008 18:15:46 +0000 (18:15 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 26 Dec 2008 18:15:46 +0000 (18:15 +0000)
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.

source/blender/blenloader/intern/readfile.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/makesdna/DNA_view3d_types.h
source/blender/windowmanager/intern/wm_event_system.c

index cc4a2d800b9ac03c76575e6827e850baf8eddd09..2ef315d6841df57241b410c8b0f221cc9b1bb252 100644 (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;
index 75abc27ce73a1415e5664cea4253d3e50bd83732..8b7da3e24dc2128cdadc1613c057cf86408cfddc 100644 (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;
 
-
+       v3d->view= view;
+       
        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 {
+               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(v3d, NULL, new_quat, NULL, NULL);
+               smooth_view(C, NULL, NULL, NULL, new_quat, NULL, NULL);
        }
-       v3d->view= view;
+
 }
 
+
 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;
-
-                                       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;
-                       }
+                       if(v3d->persp!=V3D_ORTHO) 
+                               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;
-                       }
-                       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;
+                               if(G.qual==LR_ALTKEY) {
+                                       if(oldcamera && is_an_active_object(oldcamera)) {
+                                               v3d->camera= oldcamera;
+                                       }
+                                       handle_view3d_lock();
                                }
-                               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(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();*/
                                }
-                       }
-
-                       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;
+                               smooth_view(C, NULL, v3d->camera, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens);
+                               
+                       }
+                       else{
+                               /* return to settings of last view */
+                               /* 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
 }
 
 
index dac80f09646a76d04d6777533eef607141ccff75..deb8c29d3e6ab5ccca4e394f4f47bedc7473c6c7 100644 (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;
                                }
                        }
index e0b674678a6051754f3520f278addd48c2af9483..a36a04cf6be30b057f71a83fe141b29bca5c66ad 100644 (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);
index 75b4cea0bb9ca601da551e9464114461dc78eac8..0e3e2c73fe91430362f4b039f915432a9f07b160 100644 (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);
index 7c2f5a7d5ab9efb745a9ac1bf5d0719b7ad08468..9b5b2cf621182d854fc1182a227153c0dec23cef 100644 (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;
-       }
-}
-
-
index 3d05362530884ab78909c1923d04c5b70b4c41a4..e819ce8a7cdcd6b38d9ab8dff1da853b48f75e3f 100644 (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;
index ff9e135b83c14656374fbf9f3e3e6672332b94a9..eeda0226dd95d6c2fea0ec295ca627ec81f251cc 100644 (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 */