2.5
authorTon Roosendaal <ton@blender.org>
Fri, 19 Dec 2008 17:14:02 +0000 (17:14 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 19 Dec 2008 17:14:02 +0000 (17:14 +0000)
View3d: middle mouse rotate, translate, zoom.
(using default mouse map)

source/blender/editors/space_view3d/Makefile
source/blender/editors/space_view3d/SConscript
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_ops.c [new file with mode: 0644]

index 7a5f609a187f90d1988ce0bf89dd4297a22d9686..442ab502e65b053aa403f9f0f360b0360c95b562 100644 (file)
@@ -49,6 +49,7 @@ CPPFLAGS += -I../../makesdna
 CPPFLAGS += -I../../imbuf
 CPPFLAGS += -I../../python
 CPPFLAGS += -I../../gpu
+CPPFLAGS += -I../../makesrna
 CPPFLAGS += -I../../render/extern/include
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
 
index 77cf03820ed7f72da02d5d4d24c26d71982d1c1a..fac4cd65ee2fc250d8df8ef280576c3acdcb8797 100644 (file)
@@ -6,6 +6,6 @@ sources = env.Glob('*.c')
 incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
 incs += ' ../../render/extern/include #/intern/guardedalloc #intern/bmfont'
-incs += ' ../../gpu'
+incs += ' ../../gpu ../../makesrna'
 
 env.BlenderLib ( 'bf_editors_space_view3d', sources, Split(incs), [], libtype=['core','intern'], priority=[35, 40] )
index 4c621c6ec63bd005c25455b71640f1445cb7d44d..01bdc1ba941c86fab5036e4c806e1e9f4c397ddf 100644 (file)
@@ -1202,30 +1202,30 @@ static void drawlattice(View3D *v3d, Object *ob)
 
 static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
-       ARegion *ar= NULL; // XXX
-       View3D *v3d= NULL; // XXX
+       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
        EditVert *eve = EM_get_vert_for_index(index);
        short s[2];
 
        if (eve->h==0) {
                if (data->clipVerts) {
-                       view3d_project_short_clip(ar, v3d, co, s, data->pmat, data->vmat);
+                       view3d_project_short_clip(data->ar, data->v3d, co, s, data->pmat, data->vmat);
                } else {
-                       view3d_project_short_noclip(ar, co, s, data->pmat);
+                       view3d_project_short_noclip(data->ar, co, s, data->pmat);
                }
 
                data->func(data->userData, eve, s[0], s[1], index);
        }
 }
-void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
+
+void mesh_foreachScreenVert(ARegion *ar, View3D *v3d, void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
 {
-       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
-       View3D *v3d= NULL; // XXX
+       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
        DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
 
        data.func = func;
        data.userData = userData;
+       data.ar= ar;
+       data.v3d= v3d;
        data.clipVerts = clipVerts;
 
        view3d_get_object_project_mat(v3d, G.obedit, data.pmat, data.vmat);
@@ -1239,23 +1239,21 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i
 
 static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
 {
-       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
-       ARegion *ar= NULL; // XXX
-       View3D *v3d= NULL; // XXX
+       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
        EditEdge *eed = EM_get_edge_for_index(index);
        short s[2][2];
 
        if (eed->h==0) {
                if (data->clipVerts==1) {
-                       view3d_project_short_clip(ar, v3d, v0co, s[0], data->pmat, data->vmat);
-                       view3d_project_short_clip(ar, v3d, v1co, s[1], data->pmat, data->vmat);
+                       view3d_project_short_clip(data->ar, data->v3d, v0co, s[0], data->pmat, data->vmat);
+                       view3d_project_short_clip(data->ar, data->v3d, v1co, s[1], data->pmat, data->vmat);
                } else {
-                       view3d_project_short_noclip(ar, v0co, s[0], data->pmat);
-                       view3d_project_short_noclip(ar, v1co, s[1], data->pmat);
+                       view3d_project_short_noclip(data->ar, v0co, s[0], data->pmat);
+                       view3d_project_short_noclip(data->ar, v1co, s[1], data->pmat);
 
                        if (data->clipVerts==2) {
-                if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<ar->winx && s[0][1]<ar->winy)) 
-                                       if (!(s[1][0]>=0 && s[1][1]>= 0 && s[1][0]<ar->winx && s[1][1]<ar->winy)) 
+                if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<data->ar->winx && s[0][1]<data->ar->winy)) 
+                                       if (!(s[1][0]>=0 && s[1][1]>= 0 && s[1][0]<data->ar->winx && s[1][1]<data->ar->winy)) 
                                                return;
                        }
                }
@@ -1263,13 +1261,14 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0
                data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index);
        }
 }
-void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
+void mesh_foreachScreenEdge(ARegion *ar, View3D *v3d, void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
 {
-       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
-       View3D *v3d= NULL; // XXX
+       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ARegion *ar; View3D *v3d; int clipVerts; float pmat[4][4], vmat[4][4]; } data;
        DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
 
        data.func = func;
+       data.ar= ar;
+       data.v3d= v3d;
        data.userData = userData;
        data.clipVerts = clipVerts;
 
@@ -1284,25 +1283,24 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0,
 
 static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no)
 {
-       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } *data = userData;
-       ARegion *ar= NULL; // XXX
-       View3D *v3d= NULL; // XXX
+       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; float pmat[4][4], vmat[4][4]; } *data = userData;
        EditFace *efa = EM_get_face_for_index(index);
        short s[2];
 
        if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
-               view3d_project_short_clip(ar, v3d, cent, s, data->pmat, data->vmat);
+               view3d_project_short_clip(data->ar, data->v3d, cent, s, data->pmat, data->vmat);
 
                data->func(data->userData, efa, s[0], s[1], index);
        }
 }
-void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
+void mesh_foreachScreenFace(ARegion *ar, View3D *v3d, void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
 {
-       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float pmat[4][4], vmat[4][4]; } data;
+       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; ARegion *ar; View3D *v3d; float pmat[4][4], vmat[4][4]; } data;
        DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
-       View3D *v3d= NULL; // XXX
 
        data.func = func;
+       data.ar= ar;
+       data.v3d= v3d;
        data.userData = userData;
 
        view3d_get_object_project_mat(v3d, G.obedit, data.pmat, data.vmat);
@@ -1314,10 +1312,8 @@ void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, i
        dm->release(dm);
 }
 
-void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
+void nurbs_foreachScreenVert(ARegion *ar, View3D *v3d, void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
 {
-       ARegion *ar= NULL; // XXX
-       View3D *v3d= NULL; // XXX
        float pmat[4][4], vmat[4][4];
        short s[2];
        Nurb *nu;
@@ -1375,7 +1371,7 @@ void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp,
 
 static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
 {
-       Scene *scene= NULL; // XXX
+       Scene *scene= (Scene *)userData;
        EditFace *efa = EM_get_face_for_index(index);
 
        if (efa->h==0 && efa->fgonf!=EM_FGON) {
@@ -1385,9 +1381,10 @@ static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent
                                        cent[2] + no[2]*scene->editbutsize);
        }
 }
-static void draw_dm_face_normals(DerivedMesh *dm) {
+static void draw_dm_face_normals(Scene *scene, DerivedMesh *dm) 
+{
        glBegin(GL_LINES);
-       dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, 0);
+       dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, scene);
        glEnd();
 }
 
@@ -1409,7 +1406,7 @@ static void draw_dm_face_centers(DerivedMesh *dm, int sel)
 
 static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-       Scene *scene= NULL; // XXX
+       Scene *scene= (Scene *)userData;
        EditVert *eve = EM_get_vert_for_index(index);
 
        if (eve->h==0) {
@@ -1426,9 +1423,10 @@ static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co,
                }
        }
 }
-static void draw_dm_vert_normals(DerivedMesh *dm) {
+static void draw_dm_vert_normals(Scene *scene, DerivedMesh *dm) 
+{
        glBegin(GL_LINES);
-       dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, NULL);
+       dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, scene);
        glEnd();
 }
 
@@ -2106,11 +2104,11 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, Object *ob, EditMesh *em, D
 
                if(G.f & G_DRAWNORMALS) {
                        UI_ThemeColor(TH_NORMAL);
-                       draw_dm_face_normals(cageDM);
+                       draw_dm_face_normals(scene, cageDM);
                }
                if(G.f & G_DRAW_VNORMALS) {
                        UI_ThemeColor(TH_NORMAL);
-                       draw_dm_vert_normals(cageDM);
+                       draw_dm_vert_normals(scene, cageDM);
                }
 
                if(G.f & (G_DRAW_EDGELEN|G_DRAW_FACEAREA|G_DRAW_EDGEANG))
@@ -2978,7 +2976,7 @@ static void draw_new_particle_system(View3D *v3d, Base *base, ParticleSystem *ps
                        break;
                case PART_DRAW_BB:
                        if(v3d->camera==0 && part->bb_ob==0){
-// XXX                         error("Billboards need an active camera or a target object!");
+                               printf("Billboards need an active camera or a target object!\n");
 
                                draw_as=part->draw_as=PART_DRAW_DOT;
 
index b279e888bead389eb7412536a2747ee690c47d7e..e20490c0c075dabc2507d1d0d308ccd88cee5b93 100644 (file)
@@ -178,14 +178,6 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
        return (SpaceLink *)v3dn;
 }
 
-void view3d_operatortypes(void)
-{
-}
-
-void view3d_keymap(struct wmWindowManager *wm)
-{
-}
-
 static void view3d_main_area_draw(const bContext *C, ARegion *ar)
 {
        /* draw entirely, view changes should be handled here */
@@ -195,6 +187,17 @@ static void view3d_main_area_draw(const bContext *C, ARegion *ar)
        drawview3dspace(CTX_data_scene(C), ar, v3d);
 }
 
+/* add handlers, stuff you only do once or on area/region changes */
+static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
+{
+       ListBase *keymap;
+       
+       /* own keymap */
+       keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);      /* XXX weak? */
+       WM_event_add_keymap_handler_bb(&ar->handlers, keymap,NULL, NULL);
+                                                          
+}
+
 
 /* add handlers, stuff you only do once or on area/region changes */
 static void view3d_header_area_init(wmWindowManager *wm, ARegion *ar)
@@ -244,6 +247,7 @@ void ED_spacetype_view3d(void)
        art= MEM_callocN(sizeof(ARegionType), "spacetype time region");
        art->regionid = RGN_TYPE_WINDOW;
        art->draw= view3d_main_area_draw;
+       art->init= view3d_main_area_init;
        
        BLI_addhead(&st->regiontypes, art);
        
index aa2f58ba4a2aa55f3561ff8935d5fb28fa5746e0..2cca530ce860236c2fa3b03028721e204cec89ab 100644 (file)
@@ -49,6 +49,7 @@
 #include "BLI_rand.h"
 
 #include "BKE_action.h"
+#include "BKE_context.h"
 #include "BKE_object.h"
 #include "BKE_global.h"
 #include "BKE_scene.h"
 #include "BIF_retopo.h"
 
 #include "WM_api.h"
+#include "WM_types.h"
 
 #include "ED_screen.h"
+#include "ED_types.h"
 
 #include "UI_interface.h"
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
-#include "ED_types.h"
-
 #include "PIL_time.h" /* smoothview */
 
 #include "view3d_intern.h"     // own include
 
 /* ********************** view3d_edit: view manipulations ********************* */
 
-#define TRACKBALLSIZE  (1.1)
+/* ************************** init for view ops **********************************/
 
-/* the central math in this function was copied from trackball.cpp, sample code from the 
-   Developers Toolbox series by SGI. */
+typedef struct ViewOpsData {
+       ARegion *ar;
+       View3D *v3d;
+       
+       float oldquat[4];
+       float trackvec[3];
+       float ofs[3], obofs[3];
+       float reverse, dist0;
+       
+       int origx, origy, oldx, oldy;
+       
+} ViewOpsData;
 
-/* trackball: better one than a full spherical solution */
+#define TRACKBALLSIZE  (1.1)
 
-void calctrackballvecfirst(rcti *area, short *mval, float *vec)
+static void calctrackballvec(rcti *rect, int mx, int my, float *vec)
 {
        float x, y, radius, d, z, t;
        
        radius= TRACKBALLSIZE;
        
        /* normalize x and y */
-       x= (area->xmax + area->xmin)/2 -mval[0];
-       x/= (float)((area->xmax - area->xmin)/2);
-       y= (area->ymax + area->ymin)/2 -mval[1];
-       y/= (float)((area->ymax - area->ymin)/2);
+       x= (rect->xmax + rect->xmin)/2 - mx;
+       x/= (float)((rect->xmax - rect->xmin)/4);
+       y= (rect->ymax + rect->ymin)/2 - my;
+       y/= (float)((rect->ymax - rect->ymin)/2);
        
        d = sqrt(x*x + y*y);
        if (d < radius*M_SQRT1_2)       /* Inside sphere */
@@ -107,52 +118,592 @@ void calctrackballvecfirst(rcti *area, short *mval, float *vec)
        vec[0]= x;
        vec[1]= y;
        vec[2]= -z;             /* yah yah! */
+}
+
 
-       if( fabs(vec[2])>fabs(vec[1]) && fabs(vec[2])>fabs(vec[0]) ) {
-               vec[0]= 0.0;
-               vec[1]= 0.0;
-               if(vec[2]>0.0) vec[2]= 1.0; else vec[2]= -1.0;
+static void viewops_data(bContext *C, wmOperator *op, wmEvent *event)
+{
+       ScrArea *sa= CTX_wm_area(C);
+       View3D *v3d= sa->spacedata.first;
+       ViewOpsData *vod= MEM_callocN(sizeof(ViewOpsData), "viewops data");
+       
+       /* store data */
+       op->customdata= vod;
+       vod->ar= CTX_wm_region(C);
+       vod->v3d= v3d;
+       vod->dist0= v3d->dist;
+       QUATCOPY(vod->oldquat, v3d->viewquat);
+       vod->origx= vod->oldx= event->x;
+       vod->origy= vod->oldy= event->y;
+       
+       calctrackballvec(&vod->ar->winrct, event->x, event->y, vod->trackvec);
+       
+       initgrabz(v3d, -v3d->ofs[0], -v3d->ofs[1], -v3d->ofs[2]);
+       
+       vod->reverse= 1.0f;
+       if (v3d->persmat[2][1] < 0.0f)
+               vod->reverse= -1.0f;
+       
+}      
+
+/* ************************** viewrotate **********************************/
+
+static const float thres = 0.93f; //cos(20 deg);
+
+#define COS45 0.70710678118654746
+#define SIN45 COS45
+
+static float snapquats[39][6] = {
+       /*{q0, q1, q3, q4, view, oposite_direction}*/
+{COS45, -SIN45, 0.0, 0.0, 1, 0},  //front
+{0.0, 0.0, -SIN45, -SIN45, 1, 1}, //back
+{1.0, 0.0, 0.0, 0.0, 7, 0},       //top
+{0.0, -1.0, 0.0, 0.0, 7, 1},      //bottom
+{0.5, -0.5, -0.5, -0.5, 3, 0},    //left
+{0.5, -0.5, 0.5, 0.5, 3, 1},      //right
+       
+       /* some more 45 deg snaps */
+{0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0, 0},
+{0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0, 0},
+{0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0, 0},
+{0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0, 0},
+{0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0, 0},
+{0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0, 0},
+{0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0, 0},
+{0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0, 0},
+{0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0, 0},
+{0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0, 0},
+{0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0, 0},
+{0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0, 0},
+{0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0, 0},
+{0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0, 0},
+{-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0, 0},
+{-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0, 0},
+{-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0, 0},
+{0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0, 0},
+{-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0, 0},
+{-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0, 0},
+{-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0, 0},
+{-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0, 0},
+{-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0, 0},
+{-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0, 0},
+{-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0, 0},
+{0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0, 0},
+{-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0, 0},
+{-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0, 0},
+{-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0, 0},
+{-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0, 0},
+{-COS45, 0.0, 0.0, SIN45, 0, 0},
+{COS45, 0.0, 0.0, SIN45, 0, 0},
+{0.0, 0.0, 0.0, 1.0, 0, 0}
+};
+
+
+static void viewrotate_apply(ViewOpsData *vod, int x, int y, int ctrl)
+{
+       View3D *v3d= vod->v3d;
+       int use_sel= 0; /* XXX */
+       
+       v3d->view= 0; /* need to reset everytime because of view snapping */
+       
+       if (U.flag & USER_TRACKBALL) {
+               float phi, si, q1[4], dvec[3], newvec[3];
+               
+               calctrackballvec(&vod->ar->winrct, x, y, newvec);
+       
+               VecSubf(dvec, newvec, vod->trackvec);
+       
+               si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]);
+               si/= (2.0*TRACKBALLSIZE);
+       
+               Crossf(q1+1, vod->trackvec, newvec);
+               Normalize(q1+1);
+               
+               /* Allow for rotation beyond the interval
+                       * [-pi, pi] */
+               while (si > 1.0)
+                       si -= 2.0;
+               
+               /* This relation is used instead of
+                       * phi = asin(si) so that the angle
+                       * of rotation is linearly proportional
+                       * to the distance that the mouse is
+                       * dragged. */
+               phi = si * M_PI / 2.0;
+               
+               si= sin(phi);
+               q1[0]= cos(phi);
+               q1[1]*= si;
+               q1[2]*= si;
+               q1[3]*= si;     
+               QuatMul(v3d->viewquat, q1, vod->oldquat);
+               
+               if (use_sel) {
+                       /* compute the post multiplication quat, to rotate the offset correctly */
+                       QUATCOPY(q1, vod->oldquat);
+                       QuatConj(q1);
+                       QuatMul(q1, q1, v3d->viewquat);
+                       
+                       QuatConj(q1); /* conj == inv for unit quat */
+                       VECCOPY(v3d->ofs, vod->ofs);
+                       VecSubf(v3d->ofs, v3d->ofs, vod->obofs);
+                       QuatMulVecf(q1, v3d->ofs);
+                       VecAddf(v3d->ofs, v3d->ofs, vod->obofs);
+               }
+       } 
+       else {
+               /* New turntable view code by John Aughey */
+               float si, phi, q1[4];
+               float m[3][3];
+               float m_inv[3][3];
+               float xvec[3] = {1,0,0};
+               /* Sensitivity will control how fast the viewport rotates.  0.0035 was
+                       obtained experimentally by looking at viewport rotation sensitivities
+                       on other modeling programs. */
+               /* Perhaps this should be a configurable user parameter. */
+               const float sensitivity = 0.0035;
+               
+               /* Get the 3x3 matrix and its inverse from the quaternion */
+               QuatToMat3(v3d->viewquat, m);
+               Mat3Inv(m_inv,m);
+               
+               /* Determine the direction of the x vector (for rotating up and down) */
+               /* This can likely be compuated directly from the quaternion. */
+               Mat3MulVecfl(m_inv,xvec);
+               
+               /* Perform the up/down rotation */
+               phi = sensitivity * -(y - vod->oldy);
+               si = sin(phi);
+               q1[0] = cos(phi);
+               q1[1] = si * xvec[0];
+               q1[2] = si * xvec[1];
+               q1[3] = si * xvec[2];
+               QuatMul(v3d->viewquat, v3d->viewquat, q1);
+               
+               if (use_sel) {
+                       QuatConj(q1); /* conj == inv for unit quat */
+                       VecSubf(v3d->ofs, v3d->ofs, vod->obofs);
+                       QuatMulVecf(q1, v3d->ofs);
+                       VecAddf(v3d->ofs, v3d->ofs, vod->obofs);
+               }
+               
+               /* Perform the orbital rotation */
+               phi = sensitivity * vod->reverse * (x - vod->oldx);
+               q1[0] = cos(phi);
+               q1[1] = q1[2] = 0.0;
+               q1[3] = sin(phi);
+               QuatMul(v3d->viewquat, v3d->viewquat, q1);
+               
+               if (use_sel) {
+                       QuatConj(q1);
+                       VecSubf(v3d->ofs, v3d->ofs, vod->obofs);
+                       QuatMulVecf(q1, v3d->ofs);
+                       VecAddf(v3d->ofs, v3d->ofs, vod->obofs);
+               }
+       }
+       
+       /* check for view snap */
+       if (ctrl){
+               int i;
+               float viewmat[3][3];
+               
+               
+               QuatToMat3(v3d->viewquat, viewmat);
+               
+               for (i = 0 ; i < 39; i++){
+                       float snapmat[3][3];
+                       float view = (int)snapquats[i][4];
+                       float oposite_dir = (int)snapquats[i][5];
+                       
+                       QuatToMat3(snapquats[i], snapmat);
+                       
+                       if ((Inpf(snapmat[0], viewmat[0]) > thres) &&
+                               (Inpf(snapmat[1], viewmat[1]) > thres) &&
+                               (Inpf(snapmat[2], viewmat[2]) > thres)){
+                               
+                               QUATCOPY(v3d->viewquat, snapquats[i]);
+                               
+                               v3d->view = view;
+                               if (view){
+                                       if (oposite_dir){
+                                               v3d->flag2 |= V3D_OPP_DIRECTION_NAME;
+                                       }else{
+                                               v3d->flag2 &= ~V3D_OPP_DIRECTION_NAME;
+                                       }
+                               }
+                               
+                               break;
+                       }
+               }
        }
-       else if( fabs(vec[1])>fabs(vec[0]) && fabs(vec[1])>fabs(vec[2]) ) {
-               vec[0]= 0.0;
-               vec[2]= 0.0;
-               if(vec[1]>0.0) vec[1]= 1.0; else vec[1]= -1.0;
+       vod->oldx= x;
+       vod->oldy= y;
+
+       ED_region_tag_redraw(vod->ar);
+}
+
+static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+
+       /* execute the events */
+       switch(event->type) {
+               case MOUSEMOVE:
+                       viewrotate_apply(op->customdata, event->x, event->y, event->ctrl);
+                       break;
+                       
+               case MIDDLEMOUSE:
+                       if(event->val==0) {
+                               
+                               MEM_freeN(op->customdata);
+                               op->customdata= NULL;
+                               
+                               return OPERATOR_FINISHED;
+                       }
+                       break;
        }
-       else  {
-               vec[1]= 0.0;
-               vec[2]= 0.0;
-               if(vec[0]>0.0) vec[0]= 1.0; else vec[0]= -1.0;
+       
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       ViewOpsData *vod;
+       
+       /* makes op->customdata */
+       viewops_data(C, op, event);
+       vod= op->customdata;
+       
+       /* switch from camera view when: */
+       if(vod->v3d->persp != V3D_PERSP) {
+               
+               if (U.uiflag & USER_AUTOPERSP) 
+                       vod->v3d->persp= V3D_PERSP;
+               else if(vod->v3d->persp==V3D_CAMOB)
+                       vod->v3d->persp= V3D_PERSP;
+               ED_region_tag_redraw(vod->ar);
        }
+       
+       /* add temp handler */
+       WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+       
+       return OPERATOR_RUNNING_MODAL;
 }
 
-void calctrackballvec(rcti *area, short *mval, float *vec)
+
+void ED_VIEW3D_OT_viewrotate(wmOperatorType *ot)
 {
-       float x, y, radius, d, z, t;
        
-       radius= TRACKBALLSIZE;
+       /* identifiers */
+       ot->name= "Rotate view";
+       ot->idname= "ED_VIEW3D_OT_viewrotate";
+       
+       /* api callbacks */
+       ot->invoke= viewrotate_invoke;
+       ot->modal= viewrotate_modal;
+}
+
+/* ************************ viewmove ******************************** */
+
+static void viewmove_apply(ViewOpsData *vod, int x, int y)
+{
+       if(vod->v3d->persp==V3D_CAMOB) {
+               float max= (float)MAX2(vod->ar->winx, vod->ar->winy);
+               
+               vod->v3d->camdx += (vod->oldx - x)/(max);
+               vod->v3d->camdy += (vod->oldy - y)/(max);
+               CLAMP(vod->v3d->camdx, -1.0f, 1.0f);
+               CLAMP(vod->v3d->camdy, -1.0f, 1.0f);
+// XXX         preview3d_event= 0;
+       }
+       else {
+               float dvec[3];
+               
+               window_to_3d(vod->ar, vod->v3d, dvec, x-vod->oldx, y-vod->oldy);
+               VecAddf(vod->v3d->ofs, vod->v3d->ofs, dvec);
+       }
        
-       /* x en y normalizeren */
-       x= (area->xmax + area->xmin)/2 -mval[0];
-       x/= (float)((area->xmax - area->xmin)/4);
-       y= (area->ymax + area->ymin)/2 -mval[1];
-       y/= (float)((area->ymax - area->ymin)/2);
+       vod->oldx= x;
+       vod->oldy= y;
        
-       d = sqrt(x*x + y*y);
-       if (d < radius*M_SQRT1_2)       /* Inside sphere */
-               z = sqrt(radius*radius - d*d);
-       else
-       {                       /* On hyperbola */
-               t = radius / M_SQRT2;
-               z = t*t / d;
+       ED_region_tag_redraw(vod->ar);
+}
+
+
+static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
+{      
+       /* execute the events */
+       switch(event->type) {
+               case MOUSEMOVE:
+                       viewmove_apply(op->customdata, event->x, event->y);
+                       break;
+                       
+               case MIDDLEMOUSE:
+                       if(event->val==0) {
+                               
+                               MEM_freeN(op->customdata);
+                               op->customdata= NULL;
+                               
+                               return OPERATOR_FINISHED;
+                       }
+                       break;
        }
+       
+       return OPERATOR_RUNNING_MODAL;
+}
 
-       vec[0]= x;
-       vec[1]= y;
-       vec[2]= -z;             /* yah yah! */
+static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       /* makes op->customdata */
+       viewops_data(C, op, event);
+       
+       /* add temp handler */
+       WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+       
+       return OPERATOR_RUNNING_MODAL;
+}
+
+
+void ED_VIEW3D_OT_viewmove(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Rotate view";
+       ot->idname= "ED_VIEW3D_OT_viewmove";
+       
+       /* api callbacks */
+       ot->invoke= viewmove_invoke;
+       ot->modal= viewmove_modal;
+}
+
+/* ************************ viewzoom ******************************** */
+
+static void view_zoom_mouseloc(ARegion *ar, View3D *v3d, float dfac, int mx, int my)
+{
+       if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
+               float dvec[3];
+               float tvec[3];
+               float tpos[3];
+               float new_dist;
+               short vb[2], mouseloc[2];
+               
+               mouseloc[0]= mx - ar->winrct.xmin;
+               mouseloc[1]= my - ar->winrct.ymin;
+               
+               /* find the current window width and height */
+               vb[0] = ar->winx;
+               vb[1] = ar->winy;
+               
+               tpos[0] = -v3d->ofs[0];
+               tpos[1] = -v3d->ofs[1];
+               tpos[2] = -v3d->ofs[2];
+               
+               /* Project cursor position into 3D space */
+               initgrabz(v3d, tpos[0], tpos[1], tpos[2]);
+               window_to_3d(ar, v3d, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
+               
+               /* Calculate view target position for dolly */
+               tvec[0] = -(tpos[0] + dvec[0]);
+               tvec[1] = -(tpos[1] + dvec[1]);
+               tvec[2] = -(tpos[2] + dvec[2]);
+               
+               /* Offset to target position and dolly */
+               new_dist = v3d->dist * dfac;
+               
+               VECCOPY(v3d->ofs, tvec);
+               v3d->dist = new_dist;
+               
+               /* Calculate final offset */
+               dvec[0] = tvec[0] + dvec[0] * dfac;
+               dvec[1] = tvec[1] + dvec[1] * dfac;
+               dvec[2] = tvec[2] + dvec[2] * dfac;
+               
+               VECCOPY(v3d->ofs, dvec);
+       } else {
+               v3d->dist *= dfac;
+       }
+}
+
+
+static void viewzoom_apply(ViewOpsData *vod, int x, int y)
+{
+       float zfac=1.0;
+
+       if(U.viewzoom==USER_ZOOM_CONT) {
+               // oldstyle zoom
+               zfac = 1.0+(float)(vod->origx - x + vod->origy - y)/1000.0;
+       }
+       else if(U.viewzoom==USER_ZOOM_SCALE) {
+               int ctr[2], len1, len2;
+               // method which zooms based on how far you move the mouse
+               
+               ctr[0] = (vod->ar->winrct.xmax + vod->ar->winrct.xmin)/2;
+               ctr[1] = (vod->ar->winrct.ymax + vod->ar->winrct.ymin)/2;
+               
+               len1 = (int)sqrt((ctr[0] - x)*(ctr[0] - x) + (ctr[1] - y)*(ctr[1] - y)) + 5;
+               len2 = (int)sqrt((ctr[0] - vod->origx)*(ctr[0] - vod->origx) + (ctr[1] - vod->origy)*(ctr[1] - vod->origy)) + 5;
+               
+               zfac = vod->dist0 * ((float)len2/len1) / vod->v3d->dist;
+       }
+       else {  /* USER_ZOOM_DOLLY */
+               float len1 = (vod->ar->winrct.ymax - y) + 5;
+               float len2 = (vod->ar->winrct.ymax - vod->origy) + 5;
+               zfac = vod->dist0 * (2.0*((len2/len1)-1.0) + 1.0) / vod->v3d->dist;
+       }
+
+       if(zfac != 1.0 && zfac*vod->v3d->dist > 0.001*vod->v3d->grid && 
+                               zfac*vod->v3d->dist < 10.0*vod->v3d->far)
+               view_zoom_mouseloc(vod->ar, vod->v3d, zfac, vod->oldx, vod->oldy);
+
+
+       if ((U.uiflag & USER_ORBIT_ZBUF) && (U.viewzoom==USER_ZOOM_CONT) && (vod->v3d->persp==V3D_PERSP)) {
+               float upvec[3], mat[3][3];
+               
+               /* Secret apricot feature, translate the view when in continues mode */
+               upvec[0] = upvec[1] = 0.0f;
+               upvec[2] = (vod->dist0 - vod->v3d->dist) * vod->v3d->grid;
+               vod->v3d->dist = vod->dist0;
+               Mat3CpyMat4(mat, vod->v3d->viewinv);
+               Mat3MulVecfl(mat, upvec);
+               VecAddf(vod->v3d->ofs, vod->v3d->ofs, upvec);
+       } else {
+               /* these limits are in toets.c too */
+               if(vod->v3d->dist<0.001*vod->v3d->grid) vod->v3d->dist= 0.001*vod->v3d->grid;
+               if(vod->v3d->dist>10.0*vod->v3d->far) vod->v3d->dist=10.0*vod->v3d->far;
+       }
+
+// XXX if(vod->v3d->persp==V3D_ORTHO || vod->v3d->persp==V3D_CAMOB) preview3d_event= 0;
+       
+       ED_region_tag_redraw(vod->ar);
+}
+
+
+static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+{      
+       /* execute the events */
+       switch(event->type) {
+               case MOUSEMOVE:
+                       viewzoom_apply(op->customdata, event->x, event->y);
+                       break;
+                       
+               case MIDDLEMOUSE:
+                       if(event->val==0) {
+                               
+                               MEM_freeN(op->customdata);
+                               op->customdata= NULL;
+                               
+                               return OPERATOR_FINISHED;
+                       }
+                       break;
+       }
+       
+       return OPERATOR_RUNNING_MODAL;
+}
 
+static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       /* makes op->customdata */
+       viewops_data(C, op, event);
+       
+       /* add temp handler */
+       WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+       
+       return OPERATOR_RUNNING_MODAL;
+}
+
+
+void ED_VIEW3D_OT_viewzoom(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Rotate view";
+       ot->idname= "ED_VIEW3D_OT_viewzoom";
+       
+       /* api callbacks */
+       ot->invoke= viewzoom_invoke;
+       ot->modal= viewzoom_modal;
+}
+
+/* ************************* below the line! *********************** */
+
+
+/* XXX todo Zooms in on a border drawn by the user */
+int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mouse_worldloc[3] ) //, float *autodist )
+{
+       rcti rect;
+       /* ZBuffer depth vars */
+       bglMats mats;
+       float depth, depth_close= MAXFLOAT;
+       int had_depth = 0;
+       double cent[2],  p[3];
+       int xs, ys;
+       
+       // XXX          getmouseco_areawin(mval);
+       
+       // XXX  persp(PERSP_VIEW);
+       
+       rect.xmax = mval[0] + 4;
+       rect.ymax = mval[1] + 4;
+       
+       rect.xmin = mval[0] - 4;
+       rect.ymin = mval[1] - 4;
+       
+       /* Get Z Depths, needed for perspective, nice for ortho */
+       bgl_get_mats(&mats);
+       draw_depth(scene, ar, v3d, NULL);
+       
+       /* force updating */
+       if (v3d->depths) {
+               had_depth = 1;
+               v3d->depths->damaged = 1;
+       }
+       
+       view3d_update_depths(ar, v3d);
+       
+       /* Constrain rect to depth bounds */
+       if (rect.xmin < 0) rect.xmin = 0;
+       if (rect.ymin < 0) rect.ymin = 0;
+       if (rect.xmax >= v3d->depths->w) rect.xmax = v3d->depths->w-1;
+       if (rect.ymax >= v3d->depths->h) rect.ymax = v3d->depths->h-1;          
+       
+       /* Find the closest Z pixel */
+       for (xs=rect.xmin; xs < rect.xmax; xs++) {
+               for (ys=rect.ymin; ys < rect.ymax; ys++) {
+                       depth= v3d->depths->depths[ys*v3d->depths->w+xs];
+                       if(depth < v3d->depths->depth_range[1] && depth > v3d->depths->depth_range[0]) {
+                               if (depth_close > depth) {
+                                       depth_close = depth;
+                               }
+                       }
+               }
+       }
+       
+       if (depth_close==MAXFLOAT)
+               return 0;
+       
+       if (had_depth==0) {
+               MEM_freeN(v3d->depths->depths);
+               v3d->depths->depths = NULL;
+       }
+       v3d->depths->damaged = 1;
+       
+       cent[0] = (double)mval[0];
+       cent[1] = (double)mval[1];
+       
+       if (!gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
+               return 0;
+       
+       mouse_worldloc[0] = (float)p[0];
+       mouse_worldloc[1] = (float)p[1];
+       mouse_worldloc[2] = (float)p[2];
+       return 1;
 }
 
 
+
+/* ********************* NDOF ************************ */
+/* note: this code is confusing and unclear... (ton) */
+/* **************************************************** */
+
 // ndof scaling will be moved to user setting.
 // In the mean time this is just a place holder.
 
@@ -333,547 +884,6 @@ void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int mode)
 // XXX BIF_view3d_previewrender_signal(ar, PR_DBASE|PR_DISPRECT);
 }
 
-/* Zooms in on a border drawn by the user */
-static int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mouse_worldloc[3] ) //, float *autodist )
-{
-       rcti rect;
-       /* ZBuffer depth vars */
-       bglMats mats;
-       float depth, depth_close= MAXFLOAT;
-       int had_depth = 0;
-       double cent[2],  p[3];
-       int xs, ys;
-       
-// XXX         getmouseco_areawin(mval);
-       
-// XXX persp(PERSP_VIEW);
-       
-       rect.xmax = mval[0] + 4;
-       rect.ymax = mval[1] + 4;
-       
-       rect.xmin = mval[0] - 4;
-       rect.ymin = mval[1] - 4;
-       
-       /* Get Z Depths, needed for perspective, nice for ortho */
-       bgl_get_mats(&mats);
-       draw_depth(scene, ar, v3d, NULL);
-       
-       /* force updating */
-       if (v3d->depths) {
-               had_depth = 1;
-               v3d->depths->damaged = 1;
-       }
-       
-       view3d_update_depths(ar, v3d);
-       
-       /* Constrain rect to depth bounds */
-       if (rect.xmin < 0) rect.xmin = 0;
-       if (rect.ymin < 0) rect.ymin = 0;
-       if (rect.xmax >= v3d->depths->w) rect.xmax = v3d->depths->w-1;
-       if (rect.ymax >= v3d->depths->h) rect.ymax = v3d->depths->h-1;          
-       
-       /* Find the closest Z pixel */
-       for (xs=rect.xmin; xs < rect.xmax; xs++) {
-               for (ys=rect.ymin; ys < rect.ymax; ys++) {
-                       depth= v3d->depths->depths[ys*v3d->depths->w+xs];
-                       if(depth < v3d->depths->depth_range[1] && depth > v3d->depths->depth_range[0]) {
-                               if (depth_close > depth) {
-                                       depth_close = depth;
-                               }
-                       }
-               }
-       }
-       
-       if (depth_close==MAXFLOAT)
-               return 0;
-               
-       if (had_depth==0) {
-               MEM_freeN(v3d->depths->depths);
-               v3d->depths->depths = NULL;
-       }
-       v3d->depths->damaged = 1;
-       
-       cent[0] = (double)mval[0];
-       cent[1] = (double)mval[1];
-       
-       if (!gluUnProject(cent[0], cent[1], depth_close, mats.modelview, mats.projection, (GLint *)mats.viewport, &p[0], &p[1], &p[2]))
-               return 0;
-
-       mouse_worldloc[0] = (float)p[0];
-       mouse_worldloc[1] = (float)p[1];
-       mouse_worldloc[2] = (float)p[2];
-       return 1;
-}
-
-static void view_zoom_mouseloc(ARegion *ar, View3D *v3d, float dfac, short *mouseloc)
-{
-       if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
-               short vb[2];
-               float dvec[3];
-               float tvec[3];
-               float tpos[3];
-               float new_dist;
-               
-               /* find the current window width and height */
-               vb[0] = ar->winx;
-               vb[1] = ar->winy;
-               
-               tpos[0] = -v3d->ofs[0];
-               tpos[1] = -v3d->ofs[1];
-               tpos[2] = -v3d->ofs[2];
-               
-               /* Project cursor position into 3D space */
-               initgrabz(v3d, tpos[0], tpos[1], tpos[2]);
-               window_to_3d(ar, v3d, dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
-               
-               /* Calculate view target position for dolly */
-               tvec[0] = -(tpos[0] + dvec[0]);
-               tvec[1] = -(tpos[1] + dvec[1]);
-               tvec[2] = -(tpos[2] + dvec[2]);
-               
-               /* Offset to target position and dolly */
-               new_dist = v3d->dist * dfac;
-               
-               VECCOPY(v3d->ofs, tvec);
-               v3d->dist = new_dist;
-               
-               /* Calculate final offset */
-               dvec[0] = tvec[0] + dvec[0] * dfac;
-               dvec[1] = tvec[1] + dvec[1] * dfac;
-               dvec[2] = tvec[2] + dvec[2] * dfac;
-               
-               VECCOPY(v3d->ofs, dvec);
-       } else {
-               v3d->dist *= dfac;
-       }
-}
-
-
-#define COS45 0.70710678118654746
-#define SIN45 COS45
-
-void viewmove(Scene *scene, ARegion *ar, View3D *v3d, int mode)
-{
-       static float lastofs[3] = {0,0,0};
-       Object *ob = OBACT;
-       float firstvec[3], newvec[3], dvec[3];
-       float reverse, oldquat[4], q1[4], si, phi, dist0;
-       float ofs[3], obofs[3]= {0.0f, 0.0f, 0.0f};
-       int firsttime=1;
-       short mvalball[2], mval[2], mvalo[2], mval_area[2], mvali[2];
-       short use_sel = 0;
-       short preview3d_event= 1;
-       
-       // locals for dist correction
-       float mat[3][3];
-       float upvec[3];
-
-               /* 3D window may not be defined */
-       if( !v3d ) {
-               fprintf( stderr, "v3d == NULL in viewmove()\n" );
-               return;
-       }
-       
-       // dist correction from other movement devices  
-       if((dz_flag)||v3d->dist==0) {
-               dz_flag = 0;
-               v3d->dist = m_dist;
-               upvec[0] = upvec[1] = 0;
-               upvec[2] = v3d->dist;
-               Mat3CpyMat4(mat, v3d->viewinv);
-               Mat3MulVecfl(mat, upvec);
-               VecAddf(v3d->ofs, v3d->ofs, upvec);
-       }
-               
-       /* sometimes this routine is called from headerbuttons */
-
-// XXX areawinset(ar->win);
-       
-       QUATCOPY(oldquat, v3d->viewquat);
-       
-// XXX getmouseco_areawin(mval_area);  /* for zoom to mouse loc */
-// XXX getmouseco_sc(mvali);           /* work with screen coordinates because of trackball function */
-       mvalball[0]= mvalo[0] = mvali[0];                       /* needed for turntable to work */
-       mvalball[1]= mvalo[1] = mvali[1];
-       dist0= v3d->dist;
-       
-       calctrackballvec(&ar->winrct, mvalo, firstvec);
-
-       /* cumultime(0); */
-
-       if(!G.obedit && (G.f & G_SCULPTMODE) && ob && v3d->pivot_last) {
-               use_sel= 1;
-               VecCopyf(ofs, v3d->ofs);
-
-// XXX         VecCopyf(obofs, sculpt_data()->pivot);
-               Mat4MulVecfl(ob->obmat, obofs);
-               obofs[0]= -obofs[0];
-               obofs[1]= -obofs[1];
-               obofs[2]= -obofs[2];
-       }
-       else if (U.uiflag & USER_ORBIT_SELECTION) {
-               use_sel = 1;
-               
-               VECCOPY(ofs, v3d->ofs);
-               
-               /* If there's no selection, lastofs is unmodified and last value since static */
-// XXX         calculateTransformCenter(V3D_CENTROID, lastofs);
-               
-               VECCOPY(obofs, lastofs);
-               VecMulf(obofs, -1.0f);
-       }
-       else if (U.uiflag & USER_ORBIT_ZBUF) {
-               if ((use_sel= view_autodist(scene, ar, v3d, mval, obofs))) {
-                       if (v3d->persp==V3D_PERSP) {
-                               float my_origin[3]; /* original v3d->ofs */
-                               float my_pivot[3]; /* view */
-                               
-                               VECCOPY(my_origin, v3d->ofs);
-                               VecMulf(my_origin, -1.0f);                              /* ofs is flipped */
-                               
-                               /* Set the dist value to be the distance from this 3d point */
-                               /* this means youll always be able to zoom into it and panning wont go bad when dist was zero */
-                               
-                               /* remove dist value */                 
-                               upvec[0] = upvec[1] = 0;
-                               upvec[2] = v3d->dist;
-                               Mat3CpyMat4(mat, v3d->viewinv);
-                               Mat3MulVecfl(mat, upvec);
-                               VecSubf(my_pivot, v3d->ofs, upvec);
-                               VecMulf(my_pivot, -1.0f);                               /* ofs is flipped */
-                               
-                               /* find a new ofs value that is allong the view axis (rather then the mouse location) */
-                               lambda_cp_line_ex(obofs, my_pivot, my_origin, dvec);
-                               dist0 = v3d->dist = VecLenf(my_pivot, dvec);
-                               
-                               VecMulf(dvec, -1.0f);
-                               VECCOPY(v3d->ofs, dvec);
-                       }
-                       VecMulf(obofs, -1.0f);
-                       VECCOPY(ofs, v3d->ofs);
-               } else {
-                       ofs[0] = ofs[1] = ofs[2] = 0.0f;
-               }
-       }
-       else
-               ofs[0] = ofs[1] = ofs[2] = 0.0f;
-       
-       initgrabz(v3d, -v3d->ofs[0], -v3d->ofs[1], -v3d->ofs[2]);
-       
-       reverse= 1.0f;
-       if (v3d->persmat[2][1] < 0.0f)
-               reverse= -1.0f;
-
-       while(TRUE) {
-// XXX                 getmouseco_sc(mval);
-               
-               if(     (mode==2 && U.viewzoom==USER_ZOOM_CONT) || /* continues zoom always update */
-                        mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { /* mouse moved, so update */
-                       
-                       if(firsttime) {
-                               
-                               firsttime= 0;
-                               /* are we translating, rotating or zooming? */
-                               if(mode==0) {
-// XXX                                 if(v3d->view!=0) scrarea_queue_headredraw(ar);  /*for button */
-                               }
-                               if(v3d->persp==V3D_CAMOB && mode!=1 && v3d->camera) {
-                                       v3d->persp= V3D_PERSP;
-// XXX                                 scrarea_do_windraw(ar);
-// XXX                                 scrarea_queue_headredraw(ar);
-                               }
-                       }
-
-                       if(mode==0) {   /* view rotate */
-                               v3d->view= 0; /* need to reset everytime because of view snapping */
-               
-                               if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_PERSP;
-
-                               if (U.flag & USER_TRACKBALL) mvalball[0]= mval[0];
-                               mvalball[1]= mval[1];
-                               
-                               calctrackballvec(&ar->winrct, mvalball, newvec);
-                               
-                               VecSubf(dvec, newvec, firstvec);
-                               
-                               si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]);
-                               si/= (2.0*TRACKBALLSIZE);
-                       
-                               if (U.flag & USER_TRACKBALL) {
-                                       Crossf(q1+1, firstvec, newvec);
-       
-                                       Normalize(q1+1);
-       
-                                       /* Allow for rotation beyond the interval
-                                        * [-pi, pi] */
-                                       while (si > 1.0)
-                                               si -= 2.0;
-               
-                                       /* This relation is used instead of
-                                        * phi = asin(si) so that the angle
-                                        * of rotation is linearly proportional
-                                        * to the distance that the mouse is
-                                        * dragged. */
-                                       phi = si * M_PI / 2.0;
-               
-                                       si= sin(phi);
-                                       q1[0]= cos(phi);
-                                       q1[1]*= si;
-                                       q1[2]*= si;
-                                       q1[3]*= si;     
-                                       QuatMul(v3d->viewquat, q1, oldquat);
-
-                                       if (use_sel) {
-                                               /* compute the post multiplication quat, to rotate the offset correctly */
-                                               QUATCOPY(q1, oldquat);
-                                               QuatConj(q1);
-                                               QuatMul(q1, q1, v3d->viewquat);
-
-                                               QuatConj(q1); /* conj == inv for unit quat */
-                                               VECCOPY(v3d->ofs, ofs);
-                                               VecSubf(v3d->ofs, v3d->ofs, obofs);
-                                               QuatMulVecf(q1, v3d->ofs);
-                                               VecAddf(v3d->ofs, v3d->ofs, obofs);
-                                       }
-                               } else {
-                                       /* New turntable view code by John Aughey */
-
-                                       float m[3][3];
-                                       float m_inv[3][3];
-                                       float xvec[3] = {1,0,0};
-                                       /* Sensitivity will control how fast the viewport rotates.  0.0035 was
-                                          obtained experimentally by looking at viewport rotation sensitivities
-                                          on other modeling programs. */
-                                       /* Perhaps this should be a configurable user parameter. */
-                                       const float sensitivity = 0.0035;
-
-                                       /* Get the 3x3 matrix and its inverse from the quaternion */
-                                       QuatToMat3(v3d->viewquat, m);
-                                       Mat3Inv(m_inv,m);
-
-                                       /* Determine the direction of the x vector (for rotating up and down) */
-                                       /* This can likely be compuated directly from the quaternion. */
-                                       Mat3MulVecfl(m_inv,xvec);
-
-                                       /* Perform the up/down rotation */
-                                       phi = sensitivity * -(mval[1] - mvalo[1]);
-                                       si = sin(phi);
-                                       q1[0] = cos(phi);
-                                       q1[1] = si * xvec[0];
-                                       q1[2] = si * xvec[1];
-                                       q1[3] = si * xvec[2];
-                                       QuatMul(v3d->viewquat, v3d->viewquat, q1);
-
-                                       if (use_sel) {
-                                               QuatConj(q1); /* conj == inv for unit quat */
-                                               VecSubf(v3d->ofs, v3d->ofs, obofs);
-                                               QuatMulVecf(q1, v3d->ofs);
-                                               VecAddf(v3d->ofs, v3d->ofs, obofs);
-                                       }
-
-                                       /* Perform the orbital rotation */
-                                       phi = sensitivity * reverse * (mval[0] - mvalo[0]);
-                                       q1[0] = cos(phi);
-                                       q1[1] = q1[2] = 0.0;
-                                       q1[3] = sin(phi);
-                                       QuatMul(v3d->viewquat, v3d->viewquat, q1);
-
-                                       if (use_sel) {
-                                               QuatConj(q1);
-                                               VecSubf(v3d->ofs, v3d->ofs, obofs);
-                                               QuatMulVecf(q1, v3d->ofs);
-                                               VecAddf(v3d->ofs, v3d->ofs, obofs);
-                                       }
-                               }
-                               
-                               /* check for view snap */
-                               if (G.qual==LR_CTRLKEY){
-                                       int i;
-                                       float viewmat[3][3];
-
-                                       static const float thres = 0.93f; //cos(20 deg);
-                                       
-                                       static float snapquats[39][6] = {
-                                               /*{q0, q1, q3, q4, view, oposite_direction}*/
-                                               {COS45, -SIN45, 0.0, 0.0, 1, 0},  //front
-                                               {0.0, 0.0, -SIN45, -SIN45, 1, 1}, //back
-                                               {1.0, 0.0, 0.0, 0.0, 7, 0},       //top
-                                               {0.0, -1.0, 0.0, 0.0, 7, 1},      //bottom
-                                               {0.5, -0.5, -0.5, -0.5, 3, 0},    //left
-                                               {0.5, -0.5, 0.5, 0.5, 3, 1},      //right
-                                               
-                                               /* some more 45 deg snaps */
-                                               {0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0, 0},
-                                               {0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0, 0},
-                                               {0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0, 0},
-                                               {0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0, 0},
-                                               {0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0, 0},
-                                               {0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0, 0},
-                                               {0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0, 0},
-                                               {0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0, 0},
-                                               {0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0, 0},
-                                               {0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0, 0},
-                                               {0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0, 0},
-                                               {0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0, 0},
-                                               {0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0, 0},
-                                               {0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0, 0},
-                                               {-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0, 0},
-                                               {-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0, 0},
-                                               {-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0, 0},
-                                               {0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0, 0},
-                                               {-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0, 0},
-                                               {-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0, 0},
-                                               {-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0, 0},
-                                               {-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0, 0},
-                                               {-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0, 0},
-                                               {-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0, 0},
-                                               {-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0, 0},
-                                               {0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0, 0},
-                                               {-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0, 0},
-                                               {-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0, 0},
-                                               {-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0, 0},
-                                               {-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0, 0},
-                                               {-COS45, 0.0, 0.0, SIN45, 0, 0},
-                                               {COS45, 0.0, 0.0, SIN45, 0, 0},
-                                               {0.0, 0.0, 0.0, 1.0, 0, 0}
-                                       };
-
-                                       QuatToMat3(v3d->viewquat, viewmat);
-
-                                       for (i = 0 ; i < 39; i++){
-                                               float snapmat[3][3];
-                                               float view = (int)snapquats[i][4];
-                                               float oposite_dir = (int)snapquats[i][5];
-                                               
-                                               QuatToMat3(snapquats[i], snapmat);
-                                               
-                                               if ((Inpf(snapmat[0], viewmat[0]) > thres) &&
-                                                       (Inpf(snapmat[1], viewmat[1]) > thres) &&
-                                                       (Inpf(snapmat[2], viewmat[2]) > thres)){
-                                                       
-                                                       QUATCOPY(v3d->viewquat, snapquats[i]);
-                                                       
-                                                       v3d->view = view;
-                                                       if (view){
-                                                               if (oposite_dir){
-                                                                       v3d->flag2 |= V3D_OPP_DIRECTION_NAME;
-                                                               }else{
-                                                                       v3d->flag2 &= ~V3D_OPP_DIRECTION_NAME;
-                                                               }
-                                                       }
-                                                       
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-                       else if(mode==1) {      /* translate */
-                               if(v3d->persp==V3D_CAMOB) {
-                                       float max= (float)MAX2(ar->winx, ar->winy);
-
-                                       v3d->camdx += (mvalo[0]-mval[0])/(max);
-                                       v3d->camdy += (mvalo[1]-mval[1])/(max);
-                                       CLAMP(v3d->camdx, -1.0f, 1.0f);
-                                       CLAMP(v3d->camdy, -1.0f, 1.0f);
-                                       preview3d_event= 0;
-                               }
-                               else {
-                                       window_to_3d(ar, v3d, dvec, mval[0]-mvalo[0], mval[1]-mvalo[1]);
-                                       VecAddf(v3d->ofs, v3d->ofs, dvec);
-                               }
-                       }
-                       else if(mode==2) {
-                               float zfac=1.0;
-
-                               /* use initial value (do not use mvalo (that is used to detect mouse moviments)) */
-                               mvalo[0] = mvali[0];
-                               mvalo[1] = mvali[1];
-                               
-                               if(U.viewzoom==USER_ZOOM_CONT) {
-                                       // oldstyle zoom
-                                       zfac = 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
-                               }
-                               else if(U.viewzoom==USER_ZOOM_SCALE) {
-                                       int ctr[2], len1, len2;
-                                       // method which zooms based on how far you move the mouse
-                                       
-                                       ctr[0] = (ar->winrct.xmax + ar->winrct.xmin)/2;
-                                       ctr[1] = (ar->winrct.ymax + ar->winrct.ymin)/2;
-                                       
-                                       len1 = (int)sqrt((ctr[0] - mval[0])*(ctr[0] - mval[0]) + (ctr[1] - mval[1])*(ctr[1] - mval[1])) + 5;
-                                       len2 = (int)sqrt((ctr[0] - mvalo[0])*(ctr[0] - mvalo[0]) + (ctr[1] - mvalo[1])*(ctr[1] - mvalo[1])) + 5;
-                                       
-                                       zfac = dist0 * ((float)len2/len1) / v3d->dist;
-                               }
-                               else {  /* USER_ZOOM_DOLLY */
-                                       float len1 = (ar->winrct.ymax - mval[1]) + 5;
-                                       float len2 = (ar->winrct.ymax - mvalo[1]) + 5;
-                                       zfac = dist0 * (2.0*((len2/len1)-1.0) + 1.0) / v3d->dist;
-                               }
-
-                               if(zfac != 1.0 && zfac*v3d->dist > 0.001*v3d->grid && 
-                                       zfac*v3d->dist < 10.0*v3d->far)
-                                       view_zoom_mouseloc(ar, v3d, zfac, mval_area);
-                               
-                               
-                               if ((U.uiflag & USER_ORBIT_ZBUF) && (U.viewzoom==USER_ZOOM_CONT) && (v3d->persp==V3D_PERSP)) {
-                                       /* Secret apricot feature, translate the view when in continues mode */
-                                       upvec[0] = upvec[1] = 0;
-                                       upvec[2] = (dist0 - v3d->dist) * v3d->grid;
-                                       v3d->dist = dist0;
-                                       Mat3CpyMat4(mat, v3d->viewinv);
-                                       Mat3MulVecfl(mat, upvec);
-                                       VecAddf(v3d->ofs, v3d->ofs, upvec);
-                               } else {
-                                       /* these limits are in toets.c too */
-                                       if(v3d->dist<0.001*v3d->grid) v3d->dist= 0.001*v3d->grid;
-                                       if(v3d->dist>10.0*v3d->far) v3d->dist=10.0*v3d->far;
-                               }
-                               
-                               if(v3d->persp==V3D_ORTHO || v3d->persp==V3D_CAMOB) preview3d_event= 0;
-                       }
-                       
-                       
-                       
-                       mvalo[0]= mval[0];
-                       mvalo[1]= mval[1];
-
-// XXX                 if(G.f & G_PLAYANIM) inner_play_anim_loop(0, 0);
-
-                       /* If in retopo paint mode, update lines */
-                       if(retopo_mesh_paint_check() && v3d->retopo_view_data) {
-                               v3d->retopo_view_data->queue_matrix_update= 1;
-                               retopo_paint_view_update(v3d);
-                       }
-
-//     XXX             scrarea_do_windraw(ar);
-// XXX                 screen_swapbuffers();
-               }
-               else {
-//                     short val;
-//                     unsigned short event;
-                       /* we need to empty the queue... when you do this very long it overflows */
-// XX                  while(qtest()) event= extern_qread(&val);
-                       
-// XXX                 BIF_wait_for_statechange();
-               }
-               
-               /* this in the end, otherwise get_mbut does not work on a PC... */
-// XXX         if( !(get_mbut() & (L_MOUSE|M_MOUSE))) break;
-       }
-
-       if(v3d->depths) v3d->depths->damaged= 1;
-// XXX retopo_queue_updates(v3d);
-// XXX allqueue(REDRAWVIEW3D, 0);
-
-// XXX if(preview3d_event) 
-//             BIF_view3d_previewrender_signal(ar, PR_DBASE|PR_DISPRECT);
-//     else
-//             BIF_view3d_previewrender_signal(ar, PR_PROJECTED);
-
-}
-
 void viewmoveNDOF(Scene *scene, View3D *v3d, int mode)
 {
     float fval[7];
index 6c0a978f088ee2f8f430f88c6142d79607a0fc10..4067fb2bc4c525879fc95367fd7aadddba261d64 100644 (file)
@@ -33,6 +33,7 @@
 struct BoundBox;
 struct Object;
 struct DerivedMesh;
+struct wmOperatorType;
 
 typedef struct ViewDepths {
        unsigned short w, h;
@@ -56,6 +57,15 @@ typedef struct ViewDepths {
 /* view3d_header.c */
 void view3d_header_buttons(const struct bContext *C, ARegion *ar);
 
+/* view3d_ops.c */
+void view3d_operatortypes(void);
+void view3d_keymap(struct wmWindowManager *wm);
+
+/* view3d_edit.c */
+void ED_VIEW3D_OT_viewzoom(struct wmOperatorType *ot);
+void ED_VIEW3D_OT_viewmove(struct wmOperatorType *ot);
+void ED_VIEW3D_OT_viewrotate(struct wmOperatorType *ot);
+
 /* drawobject.c */
 void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag);
 int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
new file mode 100644 (file)
index 0000000..31b7fe3
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+
+#include "view3d_intern.h"
+
+
+/* ************************** registration **********************************/
+
+void view3d_operatortypes(void)
+{
+       WM_operatortype_append(ED_VIEW3D_OT_viewrotate);
+       WM_operatortype_append(ED_VIEW3D_OT_viewmove);
+       WM_operatortype_append(ED_VIEW3D_OT_viewzoom);
+}
+
+void view3d_keymap(wmWindowManager *wm)
+{
+       ListBase *keymap= WM_keymap_listbase(wm, "View3D", SPACE_VIEW3D, 0);
+       
+       WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
+       WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_viewmove", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
+       WM_keymap_verify_item(keymap, "ED_VIEW3D_OT_viewzoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
+}
+