diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-08-07 11:27:21 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-08-07 11:27:21 +0300 |
commit | c3ef1f8db3c420612aecf40359533cb043615208 (patch) | |
tree | 92497b922815845be0045edda80d4693f58756bc | |
parent | 7fcf1f2d9c1ae4a014f3016500d4e9618346889e (diff) |
3D View: utility function to set the depth from a location
Avoids having to do projection/offset calculations inline.
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_utils.c | 30 |
2 files changed, 33 insertions, 0 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index fef3ff0749f..1b8d65bbca4 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -686,6 +686,9 @@ void ED_view3d_lock_clear(struct View3D *v3d); float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float dist_fallback); void ED_view3d_distance_set(struct RegionView3D *rv3d, const float dist); +bool ED_view3d_distance_set_from_location(struct RegionView3D *rv3d, + const float dist_co[3], + const float dist_min); float ED_scene_grid_scale(struct Scene *scene, const char **grid_unit); float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit); diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index bb8c1a40a05..5e57522eb65 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -1261,6 +1261,36 @@ void ED_view3d_distance_set(RegionView3D *rv3d, const float dist) rv3d->dist = dist; } +/** + * Change the distance & offset to match the depth of \a dist_co along the view axis. + * + * \param dist_co: A world-space location to use for the new depth. + * \param dist_min: Resulting distances below this will be ignored. + * \return Success if the distance was set. + */ +bool ED_view3d_distance_set_from_location(RegionView3D *rv3d, + const float dist_co[3], + const float dist_min) +{ + float viewinv[4]; + invert_qt_qt_normalized(viewinv, rv3d->viewquat); + + float tvec[3] = {0.0f, 0.0f, -1.0f}; + mul_qt_v3(viewinv, tvec); + + float dist_co_local[3]; + negate_v3_v3(dist_co_local, rv3d->ofs); + sub_v3_v3v3(dist_co_local, dist_co, dist_co_local); + const float delta = dot_v3v3(tvec, dist_co_local); + const float dist_new = rv3d->dist + delta; + if (dist_new >= dist_min) { + madd_v3_v3fl(rv3d->ofs, tvec, -delta); + rv3d->dist = dist_new; + return true; + } + return false; +} + /** \} */ /* -------------------------------------------------------------------- */ |