Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-03-20 08:19:02 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-03-20 08:19:02 +0400
commite5f1c0bd636e744c59a4fa18d2496ebf773466d3 (patch)
treedeb1b7ccb0fb7eb49303bc417c57373550b45286 /source
parentc6252d6e608a0dff72a8d5fde404fa6bd2c7ca7b (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.h1
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c219
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c53
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)