merged 30707:31141 from trunk
[blender-staging.git] / source / blender / editors / space_view3d / view3d_edit.c
index 981b45c7396f35f639608a75265b795ab7c37c0f..8dd901d9e54a21e964aa02f3e90e476ab6abdd46 100644 (file)
@@ -206,7 +206,7 @@ void view3d_boxview_copy(ScrArea *sa, ARegion *ar)
 
                        if(rv3dtest->viewlock) {
                                rv3dtest->dist= rv3d->dist;
-                               VECCOPY(rv3dtest->ofs, rv3d->ofs);
+                               copy_v3_v3(rv3dtest->ofs, rv3d->ofs);
                                ED_region_tag_redraw(artest);
                        }
                }
@@ -310,14 +310,14 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
        vod->ar= CTX_wm_region(C);
        vod->rv3d= rv3d= vod->ar->regiondata;
        vod->dist0= rv3d->dist;
-       QUATCOPY(vod->oldquat, rv3d->viewquat);
+       copy_qt_qt(vod->oldquat, rv3d->viewquat);
        vod->origx= vod->oldx= event->x;
        vod->origy= vod->oldy= event->y;
        vod->origkey= event->type; /* the key that triggered the operator. */
        vod->use_dyn_ofs= (U.uiflag & USER_ORBIT_SELECTION) ? 1:0;
 
        if (vod->use_dyn_ofs) {
-               VECCOPY(vod->ofs, rv3d->ofs);
+               copy_v3_v3(vod->ofs, rv3d->ofs);
                /* If there's no selection, lastofs is unmodified and last value since static */
                calculateTransformCenter(C, V3D_CENTROID, lastofs);
                negate_v3_v3(vod->dyn_ofs, lastofs);
@@ -336,8 +336,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
                                float mat[3][3];
                                float upvec[3];
 
-                               VECCOPY(my_origin, rv3d->ofs);
-                               negate_v3(my_origin);                           /* ofs is flipped */
+                               negate_v3_v3(my_origin, rv3d->ofs);                             /* 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 */
@@ -358,7 +357,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
                                negate_v3_v3(rv3d->ofs, dvec);
                        }
                        negate_v3(vod->dyn_ofs);
-                       VECCOPY(vod->ofs, rv3d->ofs);
+                       copy_v3_v3(vod->ofs, rv3d->ofs);
                } else {
                        vod->ofs[0] = vod->ofs[1] = vod->ofs[2] = 0.0f;
                }
@@ -403,49 +402,49 @@ 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, RV3D_VIEW_FRONT, 0},  //front
-{0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK, 0}, //back
-{1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP, 0},       //top
-{0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM, 0},      //bottom
-{0.5, -0.5, -0.5, -0.5, RV3D_VIEW_LEFT, 0},    //left
-{0.5, -0.5, 0.5, 0.5, RV3D_VIEW_RIGHT, 0},      //right
+static float snapquats[39][5] = {
+       /*{q0, q1, q3, q4, view}*/
+       {COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT},  //front
+       {0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK}, //back
+       {1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP},       //top
+       {0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM},      //bottom
+       {0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT},    //left
+       {0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT},      //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}
+       {0.65328145027160645, -0.65328145027160645, 0.27059805393218994, 0.27059805393218994, 0},
+       {0.92387950420379639, 0.0, 0.0, 0.38268342614173889, 0},
+       {0.0, -0.92387950420379639, 0.38268342614173889, 0.0, 0},
+       {0.35355335474014282, -0.85355335474014282, 0.35355338454246521, 0.14644660055637360, 0},
+       {0.85355335474014282, -0.35355335474014282, 0.14644660055637360, 0.35355338454246521, 0},
+       {0.49999994039535522, -0.49999994039535522, 0.49999997019767761, 0.49999997019767761, 0},
+       {0.27059802412986755, -0.65328145027160645, 0.65328145027160645, 0.27059802412986755, 0},
+       {0.65328145027160645, -0.27059802412986755, 0.27059802412986755, 0.65328145027160645, 0},
+       {0.27059799432754517, -0.27059799432754517, 0.65328139066696167, 0.65328139066696167, 0},
+       {0.38268336653709412, 0.0, 0.0, 0.92387944459915161, 0},
+       {0.0, -0.38268336653709412, 0.92387944459915161, 0.0, 0},
+       {0.14644658565521240, -0.35355335474014282, 0.85355335474014282, 0.35355335474014282, 0},
+       {0.35355335474014282, -0.14644658565521240, 0.35355335474014282, 0.85355335474014282, 0},
+       {0.0, 0.0, 0.92387944459915161, 0.38268336653709412, 0},
+       {-0.0, 0.0, 0.38268336653709412, 0.92387944459915161, 0},
+       {-0.27059802412986755, 0.27059802412986755, 0.65328133106231689, 0.65328133106231689, 0},
+       {-0.38268339633941650, 0.0, 0.0, 0.92387938499450684, 0},
+       {0.0, 0.38268339633941650, 0.92387938499450684, 0.0, 0},
+       {-0.14644658565521240, 0.35355338454246521, 0.85355329513549805, 0.35355332493782043, 0},
+       {-0.35355338454246521, 0.14644658565521240, 0.35355332493782043, 0.85355329513549805, 0},
+       {-0.49999991059303284, 0.49999991059303284, 0.49999985098838806, 0.49999985098838806, 0},
+       {-0.27059799432754517, 0.65328145027160645, 0.65328139066696167, 0.27059799432754517, 0},
+       {-0.65328145027160645, 0.27059799432754517, 0.27059799432754517, 0.65328139066696167, 0},
+       {-0.65328133106231689, 0.65328133106231689, 0.27059793472290039, 0.27059793472290039, 0},
+       {-0.92387932538986206, 0.0, 0.0, 0.38268333673477173, 0},
+       {0.0, 0.92387932538986206, 0.38268333673477173, 0.0, 0},
+       {-0.35355329513549805, 0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0},
+       {-0.85355329513549805, 0.35355329513549805, 0.14644657075405121, 0.35355329513549805, 0},
+       {-0.38268330693244934, 0.92387938499450684, 0.0, 0.0, 0},
+       {-0.92387938499450684, 0.38268330693244934, 0.0, 0.0, 0},
+       {-COS45, 0.0, 0.0, SIN45, 0},
+       {COS45, 0.0, 0.0, SIN45, 0},
+       {0.0, 0.0, 0.0, 1.0, 0}
 };
 
 enum {
@@ -537,12 +536,12 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
 
                if (vod->use_dyn_ofs) {
                        /* compute the post multiplication quat, to rotate the offset correctly */
-                       QUATCOPY(q1, vod->oldquat);
+                       copy_qt_qt(q1, vod->oldquat);
                        conjugate_qt(q1);
                        mul_qt_qtqt(q1, q1, rv3d->viewquat);
 
                        conjugate_qt(q1); /* conj == inv for unit quat */
-                       VECCOPY(rv3d->ofs, vod->ofs);
+                       copy_v3_v3(rv3d->ofs, vod->ofs);
                        sub_v3_v3(rv3d->ofs, vod->dyn_ofs);
                        mul_qt_v3(q1, rv3d->ofs);
                        add_v3_v3(rv3d->ofs, vod->dyn_ofs);
@@ -599,22 +598,66 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
        /* check for view snap */
        if (vod->axis_snap){
                int i;
-               float viewmat[3][3];
+               float viewquat_inv[4];
+               float zaxis[3]={0,0,1};
+               invert_qt_qt(viewquat_inv, rv3d->viewquat);
 
-               quat_to_mat3( viewmat,rv3d->viewquat);
+               mul_qt_v3(viewquat_inv, zaxis);
 
                for (i = 0 ; i < 39; i++){
-                       float snapmat[3][3];
+
                        float view = (int)snapquats[i][4];
+                       float viewquat_inv_test[4];
+                       float zaxis_test[3]={0,0,1};
 
-                       quat_to_mat3( snapmat,snapquats[i]);
+                       invert_qt_qt(viewquat_inv_test, snapquats[i]);
+                       mul_qt_v3(viewquat_inv_test, zaxis_test);
+                       
+                       if(angle_v3v3(zaxis_test, zaxis) < DEG2RAD(45/3)) {
+                               /* find the best roll */
+                               float quat_roll[4], quat_final[4], quat_best[4];
+                               float viewquat_align[4]; /* viewquat aligned to zaxis_test */
+                               float viewquat_align_inv[4]; /* viewquat aligned to zaxis_test */
+                               float best_angle = FLT_MAX;
+                               int j;
+
+                               /* viewquat_align is the original viewquat aligned to the snapped axis
+                                * for testing roll */
+                               rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis);
+                               normalize_qt(viewquat_align);
+                               mul_qt_qtqt(viewquat_align, rv3d->viewquat, viewquat_align);
+                               normalize_qt(viewquat_align);
+                               invert_qt_qt(viewquat_align_inv, viewquat_align);
+
+                               /* find best roll */
+                               for(j= 0; j<8; j++) {
+                                       float angle;
+                                       float xaxis1[3]={1,0,0};
+                                       float xaxis2[3]={1,0,0};
+                                       float quat_final_inv[4];
+
+                                       axis_angle_to_quat(quat_roll, zaxis_test, j * DEG2RAD(45.0));
+                                       normalize_qt(quat_roll);
+
+                                       mul_qt_qtqt(quat_final, snapquats[i], quat_roll);
+                                       normalize_qt(quat_final);
+                                       
+                                       /* compare 2 vector angles to find the least roll */
+                                       invert_qt_qt(quat_final_inv, quat_final);
+                                       mul_qt_v3(viewquat_align_inv, xaxis1);
+                                       mul_qt_v3(quat_final_inv, xaxis2);
+                                       angle= angle_v3v3(xaxis1, xaxis2);
+
+                                       if(angle <= best_angle) {
+                                               best_angle= angle;
+                                               copy_qt_qt(quat_best, quat_final);
+                                               if(j) view= 0; /* view grid assumes certain up axis */
+                                       }
+                               }
+
+                               copy_qt_qt(rv3d->viewquat, quat_best);
+                               rv3d->view= view; /* if we snap to a rolled camera the grid is invalid */
 
-                       if ((dot_v3v3(snapmat[0], viewmat[0]) > thres) &&
-                               (dot_v3v3(snapmat[1], viewmat[1]) > thres) &&
-                               (dot_v3v3(snapmat[2], viewmat[2]) > thres)
-                       ) {
-                               copy_qt_qt(rv3d->viewquat, snapquats[i]);
-                               rv3d->view= view;
                                break;
                        }
                }
@@ -944,6 +987,9 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf)
 {
        static EnumPropertyItem modal_items[] = {
        {VIEW_MODAL_CONFIRM,    "CONFIRM", 0, "Confirm", ""},
+               
+       {VIEWROT_MODAL_SWITCH_ZOOM, "SWITCH_TO_ZOOM", 0, "Switch to Zoom"},
+       {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
 
        {0, NULL, 0, NULL, NULL}};
 
@@ -1085,6 +1131,9 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf)
 {
        static EnumPropertyItem modal_items[] = {
        {VIEW_MODAL_CONFIRM,    "CONFIRM", 0, "Confirm", ""},
+               
+       {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"},
+       {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"},
 
        {0, NULL, 0, NULL, NULL}};
 
@@ -1140,7 +1189,7 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
                /* Offset to target position and dolly */
                new_dist = rv3d->dist * dfac;
 
-               VECCOPY(rv3d->ofs, tvec);
+               copy_v3_v3(rv3d->ofs, tvec);
                rv3d->dist = new_dist;
 
                /* Calculate final offset */
@@ -1548,11 +1597,9 @@ static int viewselected_exec(bContext *C, wmOperator *op) /* like a localview wi
                                        if(pchan->bone->layer & arm->layer) {
                                                bPoseChannel *pchan_tx= pchan->custom_tx ? pchan->custom_tx : pchan;
                                                ok= 1;
-                                               VECCOPY(vec, pchan_tx->pose_head);
-                                               mul_m4_v3(ob->obmat, vec);
+                                               mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_head);
                                                DO_MINMAX(vec, min, max);
-                                               VECCOPY(vec, pchan_tx->pose_tail);
-                                               mul_m4_v3(ob->obmat, vec);
+                                               mul_v3_m4v3(vec, ob->obmat, pchan_tx->pose_tail);
                                                DO_MINMAX(vec, min, max);
                                        }
                                }
@@ -2200,7 +2247,7 @@ static int vieworbit_exec(bContext *C, wmOperator *op)
                        }
                        else if(orbitdir == V3D_VIEW_STEPDOWN || orbitdir == V3D_VIEW_STEPUP) {
                                /* horizontal axis */
-                               VECCOPY(q1+1, rv3d->viewinv[0]);
+                               copy_v3_v3(q1+1, rv3d->viewinv[0]);
 
                                normalize_v3(q1+1);
                                phi= (float)(M_PI/360.0)*U.pad_rot_angle;
@@ -2509,17 +2556,26 @@ static int set_3dcursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
        float dx, dy, fz, *fp = NULL, dvec[3], oldcurs[3];
        short mx, my, mval[2];
 //     short ctrl= 0; // XXX
-
+       int flip;
        fp= give_cursor(scene, v3d);
 
 //     if(obedit && ctrl) lr_click= 1;
-       VECCOPY(oldcurs, fp);
+       copy_v3_v3(oldcurs, fp);
 
        mx= event->x - ar->winrct.xmin;
        my= event->y - ar->winrct.ymin;
+
        project_short_noclip(ar, fp, mval);
+       flip= initgrabz(rv3d, fp[0], fp[1], fp[2]);
+       
+       /* reset the depth based on the view offset */
+       if(flip) {
+               negate_v3_v3(fp, rv3d->ofs);
 
-       initgrabz(rv3d, fp[0], fp[1], fp[2]);
+               /* re initialize */
+               project_short_noclip(ar, fp, mval);
+               flip= initgrabz(rv3d, fp[0], fp[1], fp[2]);
+       }
 
        if(mval[0]!=IS_CLIPPED) {
                short depth_used = 0;