diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-03-20 08:19:02 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-03-20 08:19:02 +0400 |
commit | e5f1c0bd636e744c59a4fa18d2496ebf773466d3 (patch) | |
tree | deb1b7ccb0fb7eb49303bc417c57373550b45286 /source | |
parent | c6252d6e608a0dff72a8d5fde404fa6bd2c7ca7b (diff) |
View3D: remove orbit snapping LUT, allow to snap axis but not roll
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 219 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 53 |
3 files changed, 131 insertions, 142 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index adeb271f7a2..65d31da2347 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -311,6 +311,7 @@ struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip); void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]); bool ED_view3d_quat_from_axis_view(const char view, float quat[4]); +char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon); char ED_view3d_lock_view_from_index(int index); bool ED_view3d_lock(struct RegionView3D *rv3d); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index ea81bb2b857..4e21a318d85 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -695,56 +695,6 @@ static void viewops_data_free(bContext *C, wmOperator *op) /* ************************** viewrotate **********************************/ -#define COS45 0.7071068 -#define SIN45 COS45 - -#define NUM_SNAP_QUATS 39 - -static const float snapquats[NUM_SNAP_QUATS][5] = { - /*{q0, q1, q3, q4, view}*/ - {COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT}, - {0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK}, - {1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP}, - {0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM}, - {0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT}, - {0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT}, - - /* some more 45 deg snaps */ - { 0.6532815, -0.6532815, 0.2705981, 0.2705981, 0}, - { 0.9238795, 0.0, 0.0, 0.3826834, 0}, - { 0.0, -0.9238795, 0.3826834, 0.0, 0}, - { 0.3535534, -0.8535534, 0.3535534, 0.1464466, 0}, - { 0.8535534, -0.3535534, 0.1464466, 0.3535534, 0}, - { 0.4999999, -0.4999999, 0.5, 0.5, 0}, - { 0.2705980, -0.6532815, 0.6532815, 0.2705980, 0}, - { 0.6532815, -0.2705980, 0.2705980, 0.6532815, 0}, - { 0.2705978, -0.2705980, 0.6532814, 0.6532814, 0}, - { 0.3826834, 0.0, 0.0, 0.9238794, 0}, - { 0.0, -0.3826834, 0.9238794, 0.0, 0}, - { 0.1464466, -0.3535534, 0.8535534, 0.3535534, 0}, - { 0.3535534, -0.1464466, 0.3535534, 0.8535534, 0}, - { 0.0, 0.0, 0.9238794, 0.3826834, 0}, - {-0.0, 0.0, 0.3826834, 0.9238794, 0}, - {-0.2705980, 0.2705980, 0.6532813, 0.6532813, 0}, - {-0.3826834, 0.0, 0.0, 0.9238794, 0}, - { 0.0, 0.3826834, 0.9238794, 0.0, 0}, - {-0.1464466, 0.3535534, 0.8535533, 0.3535533, 0}, - {-0.3535534, 0.1464466, 0.3535533, 0.8535533, 0}, - {-0.4999999, 0.4999999, 0.4999999, 0.4999999, 0}, - {-0.2705980, 0.6532815, 0.6532814, 0.2705980, 0}, - {-0.6532815, 0.2705980, 0.2705980, 0.6532814, 0}, - {-0.6532813, 0.6532813, 0.2705979, 0.2705979, 0}, - {-0.9238793, 0.0, 0.0, 0.3826833, 0}, - { 0.0, 0.9238793, 0.3826833, 0.0, 0}, - {-0.3535533, 0.8535533, 0.3535533, 0.1464466, 0}, - {-0.8535533, 0.3535533, 0.1464466, 0.3535533, 0}, - {-0.3826833, 0.9238794, 0.0, 0.0, 0}, - {-0.9238794, 0.3826833, 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 { VIEW_PASS = 0, VIEW_APPLY, @@ -818,6 +768,108 @@ static void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat[4]) } } +static void viewrotate_apply_snap(ViewOpsData *vod) +{ + const float axis_limit = DEG2RADF(45 / 3); + + RegionView3D *rv3d = vod->rv3d; + + float viewquat_inv[4]; + float zaxis[3] = {0, 0, 1}; + float zaxis_best[3]; + int x, y, z; + bool found = false; + + invert_qt_qt(viewquat_inv, vod->viewquat); + + mul_qt_v3(viewquat_inv, zaxis); + normalize_v3(zaxis); + + + for (x = -1; x < 2; x++) { + for (y = -1; y < 2; y++) { + for (z = -1; z < 2; z++) { + if (x || y || z) { + float zaxis_test[3] = {x, y, z}; + + normalize_v3(zaxis_test); + + if (angle_normalized_v3v3(zaxis_test, zaxis) < axis_limit) { + copy_v3_v3(zaxis_best, zaxis_test); + found = true; + } + } + } + } + } + + if (found) { + + /* find the best roll */ + float quat_roll[4], quat_final[4], quat_best[4], quat_snap[4]; + float viewquat_align[4]; /* viewquat aligned to zaxis_best */ + float viewquat_align_inv[4]; /* viewquat aligned to zaxis_best */ + float best_angle = axis_limit; + int j; + + /* viewquat_align is the original viewquat aligned to the snapped axis + * for testing roll */ + rotation_between_vecs_to_quat(viewquat_align, zaxis_best, zaxis); + normalize_qt(viewquat_align); + mul_qt_qtqt(viewquat_align, vod->viewquat, viewquat_align); + normalize_qt(viewquat_align); + invert_qt_qt(viewquat_align_inv, viewquat_align); + + vec_to_quat(quat_snap, zaxis_best, OB_NEGZ, OB_POSY); + invert_qt(quat_snap); + normalize_qt(quat_snap); + + /* check if we can find the roll */ + found = false; + + /* 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_best, (float)j * DEG2RADF(45.0f)); + normalize_qt(quat_roll); + + mul_qt_qtqt(quat_final, quat_snap, 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) { + found = true; + best_angle = angle; + copy_qt_qt(quat_best, quat_final); + } + } + + if (found) { + /* lock 'quat_best' to an axis view if we can */ + rv3d->view = ED_view3d_quat_to_axis_view(quat_best, 0.01f); + if (rv3d->view != RV3D_VIEW_USER) { + ED_view3d_quat_from_axis_view(rv3d->view, quat_best); + } + } + else { + copy_qt_qt(quat_best, viewquat_align); + } + + copy_qt_qt(rv3d->viewquat, quat_best); + + viewrotate_apply_dyn_ofs(vod, rv3d->viewquat); + } +} + static void viewrotate_apply(ViewOpsData *vod, int x, int y) { RegionView3D *rv3d = vod->rv3d; @@ -916,72 +968,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y) /* check for view snap, * note: don't apply snap to vod->viewquat so the view wont jam up */ if (vod->axis_snap) { - int i; - float viewquat_inv[4]; - float zaxis[3] = {0, 0, 1}; - invert_qt_qt(viewquat_inv, vod->viewquat); - - mul_qt_v3(viewquat_inv, zaxis); - - for (i = 0; i < NUM_SNAP_QUATS; i++) { - - float view = (int)snapquats[i][4]; - float viewquat_inv_test[4]; - float zaxis_test[3] = {0, 0, 1}; - - invert_qt_qt(viewquat_inv_test, snapquats[i]); - mul_qt_v3(viewquat_inv_test, zaxis_test); - - if (angle_v3v3(zaxis_test, zaxis) < DEG2RADF(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, vod->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, (float)j * DEG2RADF(45.0f)); - 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 */ - - viewrotate_apply_dyn_ofs(vod, rv3d->viewquat); - - break; - } - } + viewrotate_apply_snap(vod); } vod->oldx = x; vod->oldy = y; diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index e2467ec83f1..22f16091066 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -831,39 +831,40 @@ static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob) mat3_to_quat(rv3d->viewquat, tmat); } -bool ED_view3d_quat_from_axis_view(const char view, float quat[4]) -{ - /* quat values are all unit length */ +static float view3d_quat_axis[6][4] = { + {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f}, /* RV3D_VIEW_FRONT */ + {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2}, /* RV3D_VIEW_BACK */ + {0.5f, -0.5f, 0.5f, 0.5f}, /* RV3D_VIEW_LEFT */ + {0.5f, -0.5f, -0.5f, -0.5f}, /* RV3D_VIEW_RIGHT */ + {1.0f, 0.0f, 0.0f, 0.0f}, /* RV3D_VIEW_TOP */ + {0.0f, -1.0f, 0.0f, 0.0f}, /* RV3D_VIEW_BOTTOM */ + }; - switch (view) { - case RV3D_VIEW_BOTTOM: - copy_v4_fl4(quat, 0.0, -1.0, 0.0, 0.0); - break; - - case RV3D_VIEW_BACK: - copy_v4_fl4(quat, 0.0, 0.0, -M_SQRT1_2, -M_SQRT1_2); - break; - case RV3D_VIEW_LEFT: - copy_v4_fl4(quat, 0.5, -0.5, 0.5, 0.5); - break; +bool ED_view3d_quat_from_axis_view(const char view, float quat[4]) +{ + if (RV3D_VIEW_IS_AXIS(view)) { + copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]); + return true; + } + else { + return false; + } +} - case RV3D_VIEW_TOP: - copy_v4_fl4(quat, 1.0, 0.0, 0.0, 0.0); - break; +char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon) +{ + /* quat values are all unit length */ - case RV3D_VIEW_FRONT: - copy_v4_fl4(quat, M_SQRT1_2, -M_SQRT1_2, 0.0, 0.0); - break; + char view; - case RV3D_VIEW_RIGHT: - copy_v4_fl4(quat, 0.5, -0.5, -0.5, -0.5); - break; - default: - return false; + for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) { + if (angle_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]) < epsilon) { + return view; + } } - return true; + return RV3D_VIEW_USER; } char ED_view3d_lock_view_from_index(int index) |