diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2017-02-02 23:50:12 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2017-02-02 23:50:12 +0300 |
commit | d85295534b6dad80b9c0db32708f7318ef79e134 (patch) | |
tree | aa317d5ce63509aa5bf20f2db1ed159d4961c733 /source/blender/editors/transform | |
parent | 47b21dd4c6768e0410e4a73350be75bfb1123188 (diff) | |
parent | 9f67367f0aae46f022adb9b47d91c01b35ab9b0f (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/transform_snap_object.c | 128 |
1 files changed, 72 insertions, 56 deletions
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index bed451a32d8..85209b07677 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -387,8 +387,9 @@ typedef struct Nearest2dPrecalc { float ray_direction_local[3]; float ray_inv_dir[3]; - float depth_range[2]; + float ray_min_dist; float pmat[4][4]; /* perspective matrix multiplied by object matrix */ + bool is_persp; float win_half[2]; float mval[2]; @@ -400,13 +401,14 @@ typedef struct Nearest2dPrecalc { */ static void dist_squared_to_projected_aabb_precalc( struct Nearest2dPrecalc *neasrest_precalc, - float lpmat[4][4], const float win_half[2], - const float depth_range[2], const float mval[2], + float lpmat[4][4], bool is_persp, const float win_half[2], + const float ray_min_dist, const float mval[2], const float ray_origin_local[3], const float ray_direction_local[3]) { copy_m4_m4(neasrest_precalc->pmat, lpmat); + neasrest_precalc->is_persp = is_persp; copy_v2_v2(neasrest_precalc->win_half, win_half); - copy_v2_v2(neasrest_precalc->depth_range, depth_range); + neasrest_precalc->ray_min_dist = ray_min_dist; copy_v3_v3(neasrest_precalc->ray_origin_local, ray_origin_local); copy_v3_v3(neasrest_precalc->ray_direction_local, ray_direction_local); @@ -513,11 +515,11 @@ static float dist_squared_to_projected_aabb( #define IGNORE_BEHIND_RAY #ifdef IGNORE_BEHIND_RAY /* `if rtmax < depth_min`, the hit is behind us */ - if (rtmax < data->depth_range[0]) { + if (rtmax < data->ray_min_dist) { /* Test if the entire AABB is behind us */ float depth = depth_get( local_bvmax, data->ray_origin_local, data->ray_direction_local); - if (depth < (data->depth_range[0])) { + if (depth < (data->ray_min_dist)) { return FLT_MAX; } } @@ -528,11 +530,11 @@ static float dist_squared_to_projected_aabb( } #ifdef IGNORE_BEHIND_RAY /* `if rtmin < depth_min`, the hit is behing us */ - else if (rtmin < data->depth_range[0]) { + else if (rtmin < data->ray_min_dist) { /* Test if the entire AABB is behind us */ float depth = depth_get( local_bvmax, data->ray_origin_local, data->ray_direction_local); - if (depth < (data->depth_range[0])) { + if (depth < (data->ray_min_dist)) { return FLT_MAX; } } @@ -549,20 +551,24 @@ static float dist_squared_to_projected_aabb( float scale = fabsf(local_bvmax[main_axis] - local_bvmin[main_axis]); float (*pmat)[4] = data->pmat; - float depth_a = mul_project_m4_v3_zfac(pmat, va); - float depth_b = depth_a + pmat[main_axis][3] * scale; float va2d[2] = { (dot_m4_v3_row_x(pmat, va) + pmat[3][0]), (dot_m4_v3_row_y(pmat, va) + pmat[3][1]), }; float vb2d[2] = { - (va2d[0] + pmat[main_axis][0] * scale) / depth_b, - (va2d[1] + pmat[main_axis][1] * scale) / depth_b, + (va2d[0] + pmat[main_axis][0] * scale), + (va2d[1] + pmat[main_axis][1] * scale), }; - va2d[0] /= depth_a; - va2d[1] /= depth_a; + if (data->is_persp) { + float depth_a = mul_project_m4_v3_zfac(pmat, va); + float depth_b = depth_a + pmat[main_axis][3] * scale; + va2d[0] /= depth_a; + va2d[1] /= depth_a; + vb2d[0] /= depth_b; + vb2d[1] /= depth_b; + } va2d[0] += 1.0f; va2d[1] += 1.0f; @@ -606,13 +612,13 @@ static float dist_squared_to_projected_aabb( static float dist_squared_to_projected_aabb_simple( float lpmat[4][4], const float win_half[2], - const float depth_range[2], const float mval[2], + const float ray_min_dist, const float mval[2], const float ray_origin_local[3], const float ray_direction_local[3], const float bbmin[3], const float bbmax[3]) { struct Nearest2dPrecalc data; dist_squared_to_projected_aabb_precalc( - &data, lpmat, win_half, depth_range, + &data, lpmat, true, win_half, ray_min_dist, mval, ray_origin_local, ray_direction_local); bool dummy[3] = {true, true, true}; @@ -641,11 +647,11 @@ static float dist_aabb_to_plane( typedef struct Nearest2dUserData { struct Nearest2dPrecalc data_precalc; - bool is_persp; float dist_px_sq; bool r_axis_closest[3]; + float depth_range[2]; void *userdata; int index; float co[3]; @@ -674,11 +680,11 @@ static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, vo }; if (test_projected_vert_dist( - neasrest_precalc->depth_range, + data->depth_range, neasrest_precalc->mval, co, neasrest_precalc->pmat, neasrest_precalc->win_half, - data->is_persp, + neasrest_precalc->is_persp, &data->dist_px_sq, data->co)) { @@ -697,11 +703,11 @@ static bool cb_walk_leaf_snap_edge(const BVHTreeAxisRange *UNUSED(bounds), int i get_edge_verts(data->userdata, index, v_pair); if (test_projected_edge_dist( - neasrest_precalc->depth_range, + data->depth_range, neasrest_precalc->mval, neasrest_precalc->pmat, neasrest_precalc->win_half, - data->is_persp, + neasrest_precalc->is_persp, neasrest_precalc->ray_origin_local, neasrest_precalc->ray_direction_local, v_pair[0], v_pair[1], @@ -1114,15 +1120,15 @@ static bool snapDerivedMesh( float lpmat[4][4]; float ray_org_local[3]; - float depth_range_local[2]; + float ray_min_dist; if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) { mul_m4_m4m4(lpmat, snapdata->pmat, obmat); - copy_v3_v3(ray_org_local, snapdata->ray_origin); - mul_m4_v3(imat, ray_org_local); - depth_range_local[0] = snapdata->depth_range[0] * local_scale; - depth_range_local[1] = local_depth + depth_range_local[0]; + ray_min_dist = snapdata->depth_range[0] * local_scale; } + copy_v3_v3(ray_org_local, snapdata->ray_origin); + mul_m4_v3(imat, ray_org_local); + if (do_bb) { BoundBox *bb = BKE_object_boundbox_get(ob); @@ -1136,7 +1142,7 @@ static bool snapDerivedMesh( /* In vertex and edges you need to get the pixel distance from ray to BoundBox, see T46816. */ if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) { float dist_px_sq = dist_squared_to_projected_aabb_simple( - lpmat, snapdata->win_half, snapdata->depth_range, snapdata->mval, + lpmat, snapdata->win_half, ray_min_dist, snapdata->mval, ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]); if (dist_px_sq > SQUARE(*dist_px)) { @@ -1246,11 +1252,6 @@ static bool snapDerivedMesh( * because even in the Orthografic view, in some cases, * the ray can start inside the object (see T50486) */ if (len_diff > 400.0f) { - float ray_org_local[3]; - - copy_v3_v3(ray_org_local, snapdata->ray_origin); - mul_m4_v3(imat, ray_org_local); - /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with * very far away ray_start values (as returned in case of ortho view3d), see T38358. */ @@ -1321,15 +1322,16 @@ static bool snapDerivedMesh( BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_MESH}; Nearest2dUserData neasrest2d = { - .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP, .dist_px_sq = SQUARE(*dist_px), .r_axis_closest = {1.0f, 1.0f, 1.0f}, + .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]}, .userdata = &treedata_type, .index = -1}; dist_squared_to_projected_aabb_precalc( - &neasrest2d.data_precalc, lpmat, snapdata->win_half, - depth_range_local, snapdata->mval, ray_org_local, ray_normal_local); + &neasrest2d.data_precalc, lpmat, + snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half, + ray_min_dist, snapdata->mval, ray_org_local, ray_normal_local); BVHTree_WalkLeafCallback cb_walk_leaf = (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ? @@ -1612,19 +1614,19 @@ static bool snapEditMesh( BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_EDIT_MESH}; Nearest2dUserData neasrest2d = { - .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP, .dist_px_sq = SQUARE(*dist_px), .r_axis_closest = {1.0f, 1.0f, 1.0f}, + .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]}, .userdata = &treedata_type, .index = -1}; - float lpmat[4][4], depth_range_local[2]; + float lpmat[4][4]; mul_m4_m4m4(lpmat, snapdata->pmat, obmat); - depth_range_local[0] = snapdata->depth_range[0] * local_scale; - depth_range_local[1] = local_depth + depth_range_local[0]; dist_squared_to_projected_aabb_precalc( - &neasrest2d.data_precalc, lpmat, snapdata->win_half, - snapdata->depth_range, snapdata->mval, ray_org_local, ray_normal_local); + &neasrest2d.data_precalc, lpmat, + snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half, + (snapdata->depth_range[0] * local_scale), snapdata->mval, + ray_org_local, ray_normal_local); BVHTree_WalkLeafCallback cb_walk_leaf = (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ? @@ -2080,23 +2082,37 @@ static bool transform_snap_context_project_view3d_mixed_impl( BLI_assert(snap_to_flag != 0); BLI_assert((snap_to_flag & ~(1 | 2 | 4)) == 0); - for (int i = 0; i < 3; i++) { - if ((snap_to_flag & (1 << i)) && (is_hit == false || use_depth)) { - - if (ED_transform_snap_object_project_view3d( - sctx, - elem_type[i], params, - mval, dist_px, &ray_depth, - r_co, r_no)) - { - is_hit = true; - if (use_depth == false) { - ray_depth = BVH_RAYCAST_DIST_MAX; - } - else { + if (use_depth) { + const float dist_px_orig = *dist_px; + for (int i = 2; i >= 0; i--) { + if (snap_to_flag & (1 << i)) { + if (i == 0) + *dist_px = dist_px_orig; + if (ED_transform_snap_object_project_view3d( + sctx, + elem_type[i], params, + mval, dist_px, &ray_depth, + r_co, r_no)) + { /* 0.01 is a random but small value to prioritizing * the first elements of the loop */ - ray_depth -= 0.01f; + ray_depth += 0.01f; + is_hit = true; + } + } + } + } + else { + for (int i = 0; i < 3; i++) { + if (snap_to_flag & (1 << i)) { + if (ED_transform_snap_object_project_view3d( + sctx, + elem_type[i], params, + mval, dist_px, &ray_depth, + r_co, r_no)) + { + is_hit = true; + break; } } } |