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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-02-09 03:50:25 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-02-09 17:50:23 +0300
commit8e981efe38ae6d0760f08c49564010104eee78c6 (patch)
treede33177cee685849351e40724487f2c14ba13a94 /source/blender/editors/space_view3d/view3d_utils.c
parent89ce270f6137aa359f0fa31cf19485f986bde131 (diff)
3D View: support axis views with axis-aligned roll
Previously any of the named views could not have any roll, this commit supports roll as long as it's axis-aligned (90,180,270 deg). This is useful for snapping to views, an improvement on cebd025e02f11.
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_utils.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c116
1 files changed, 78 insertions, 38 deletions
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index e7d514baa41..08a4947dc18 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -408,6 +408,7 @@ void ED_view3d_lastview_store(RegionView3D *rv3d)
{
copy_qt_qt(rv3d->lviewquat, rv3d->viewquat);
rv3d->lview = rv3d->view;
+ rv3d->lview_axis_roll = rv3d->view_axis_roll;
if (rv3d->persp != RV3D_CAMOB) {
rv3d->lpersp = rv3d->persp;
}
@@ -470,7 +471,7 @@ bool ED_view3d_persp_ensure(const Depsgraph *depsgraph, View3D *v3d, ARegion *ar
char persp = (autopersp && RV3D_VIEW_IS_AXIS(rv3d->lview)) ? RV3D_PERSP : rv3d->lpersp;
ED_view3d_persp_switch_from_camera(depsgraph, v3d, rv3d, persp);
}
- else if (autopersp && ED_view3d_quat_is_axis_aligned(rv3d->viewquat)) {
+ else if (autopersp && RV3D_VIEW_IS_AXIS(rv3d->view)) {
rv3d->persp = RV3D_PERSP;
}
return true;
@@ -781,14 +782,16 @@ static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_
int i;
/* we could use rv3d->viewinv, but better not depend on view matrix being updated */
- if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, viewinv) == false)) {
+ if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_src->view, rv3d_src->view_axis_roll, viewinv) ==
+ false)) {
return;
}
invert_qt_normalized(viewinv);
mul_qt_v3(viewinv, view_src_x);
mul_qt_v3(viewinv, view_src_y);
- if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, viewinv) == false)) {
+ if (UNLIKELY(ED_view3d_quat_from_axis_view(rv3d_dst->view, rv3d_dst->view_axis_roll, viewinv) ==
+ false)) {
return;
}
invert_qt_normalized(viewinv);
@@ -903,8 +906,9 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip)
if (ar->alignment == RGN_ALIGN_QSPLIT) {
rv3d = ar->regiondata;
if (rv3d->viewlock) {
- if (!RV3D_VIEW_IS_AXIS(rv3d->view)) {
+ if (!RV3D_VIEW_IS_AXIS(rv3d->view) || (rv3d->view_axis_roll != RV3D_VIEW_AXIS_ROLL_0)) {
rv3d->view = ED_view3d_lock_view_from_index(index_qsplit);
+ rv3d->view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
rv3d->persp = RV3D_ORTHO;
ED_view3d_lock(rv3d);
}
@@ -1304,19 +1308,62 @@ bool ED_view3d_distance_set_from_location(RegionView3D *rv3d,
/* -------------------------------------------------------------------- */
/** \name View Axis Utilities
* \{ */
-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 */
+
+/**
+ * Lookup by axis-view, axis-roll.
+ */
+static float view3d_quat_axis[6][4][4] = {
+ /* RV3D_VIEW_FRONT */
+ {
+ {M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f},
+ {0.5f, -0.5f, -0.5f, 0.5f},
+ {0, 0, -M_SQRT1_2, M_SQRT1_2},
+ {-0.5f, 0.5f, -0.5f, 0.5f},
+ },
+ /* RV3D_VIEW_BACK */
+ {
+ {0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2},
+ {0.5f, 0.5f, -0.5f, -0.5f},
+ {M_SQRT1_2, M_SQRT1_2, 0, 0},
+ {0.5f, 0.5f, 0.5f, 0.5f},
+ },
+ /* RV3D_VIEW_LEFT */
+ {
+ {0.5f, -0.5f, 0.5f, 0.5f},
+ {0, -M_SQRT1_2, 0.0f, M_SQRT1_2},
+ {-0.5f, -0.5f, -0.5f, 0.5f},
+ {-M_SQRT1_2, 0, -M_SQRT1_2, 0},
+ },
+
+ /* RV3D_VIEW_RIGHT */
+ {
+ {0.5f, -0.5f, -0.5f, -0.5f},
+ {M_SQRT1_2, 0, -M_SQRT1_2, 0},
+ {0.5f, 0.5f, -0.5f, 0.5f},
+ {0, M_SQRT1_2, 0, M_SQRT1_2},
+ },
+ /* RV3D_VIEW_TOP */
+ {
+ {1.0f, 0.0f, 0.0f, 0.0f},
+ {M_SQRT1_2, 0, 0, M_SQRT1_2},
+ {0, 0, 0, 1},
+ {-M_SQRT1_2, 0, 0, M_SQRT1_2},
+ },
+ /* RV3D_VIEW_BOTTOM */
+ {
+ {0.0f, -1.0f, 0.0f, 0.0f},
+ {0, -M_SQRT1_2, -M_SQRT1_2, 0},
+ {0, 0, -1, 0},
+ {0, M_SQRT1_2, -M_SQRT1_2, 0},
+ },
+
};
-bool ED_view3d_quat_from_axis_view(const char view, float quat[4])
+bool ED_view3d_quat_from_axis_view(const char view, const char view_axis_roll, float quat[4])
{
+ BLI_assert(view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270);
if (RV3D_VIEW_IS_AXIS(view)) {
- copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]);
+ copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll]);
return true;
}
else {
@@ -1324,35 +1371,28 @@ 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)
+bool ED_view3d_quat_to_axis_view(const float quat[4],
+ const float epsilon,
+ char *r_view,
+ char *r_view_axis_roll)
{
- /* quat values are all unit length */
+ *r_view = RV3D_VIEW_USER;
+ *r_view_axis_roll = RV3D_VIEW_AXIS_ROLL_0;
- char view;
-
- for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
- if (fabsf(angle_signed_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT])) < epsilon) {
- return view;
+ /* quat values are all unit length */
+ for (int view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
+ for (int view_axis_roll = RV3D_VIEW_AXIS_ROLL_0; view_axis_roll <= RV3D_VIEW_AXIS_ROLL_270;
+ view_axis_roll++) {
+ if (fabsf(angle_signed_qtqt(
+ quat, view3d_quat_axis[view - RV3D_VIEW_FRONT][view_axis_roll])) < epsilon) {
+ *r_view = view;
+ *r_view_axis_roll = view_axis_roll;
+ return true;
+ }
}
}
- return RV3D_VIEW_USER;
-}
-
-/**
- * Returns true if input view quaternion is aligned view axis in direction & angle.
- */
-bool ED_view3d_quat_is_axis_aligned(const float viewquat[4])
-{
- float mat[3][3];
- quat_to_mat3(mat, viewquat);
- for (int row = 0; row < 3; row++) {
- int axis = axis_dominant_v3_single(mat[row]);
- if (fabsf(fabsf(mat[row][axis]) - 1.0f) > 1e-4f) {
- return false;
- }
- }
- return true;
+ return false;
}
char ED_view3d_lock_view_from_index(int index)
@@ -1391,7 +1431,7 @@ char ED_view3d_axis_view_opposite(char view)
bool ED_view3d_lock(RegionView3D *rv3d)
{
- return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->viewquat);
+ return ED_view3d_quat_from_axis_view(rv3d->view, rv3d->view_axis_roll, rv3d->viewquat);
}
/** \} */