diff options
author | Germano <germano.costa@ig.com.br> | 2018-05-15 20:14:25 +0300 |
---|---|---|
committer | Germano <germano.costa@ig.com.br> | 2018-05-15 20:14:25 +0300 |
commit | 717dd4cecd2ea8eaa7b3bbfb5a5c7ec65f0337c0 (patch) | |
tree | d481c84a541de479ebccd8004168d42d7e47a322 /source | |
parent | a2dd6fa58b66912bdebcc07c504212bac617f253 (diff) |
BLI_kdopbvh: Reference clip_planes callback to find nearest projected.
Clip_planes are an important parameter to be used in callbacks.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_kdopbvh.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_kdopbvh.c | 10 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap_object.c | 121 |
3 files changed, 79 insertions, 53 deletions
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 76c3b6ef3fd..e7cbe05d713 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -107,6 +107,7 @@ typedef void (*BVHTree_RangeQuery)(void *userdata, int index, const float co[3], typedef void (*BVHTree_NearestProjectedCallback)( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 5571636be63..b3adf3106c1 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -2040,7 +2040,10 @@ static void bvhtree_nearest_projected_dfs_recursive( { if (node->totnode == 0) { if (data->callback) { - data->callback(data->userdata, node->index, &data->precalc, &data->nearest); + data->callback( + data->userdata, node->index, &data->precalc, + NULL, 0, + &data->nearest); } else { data->nearest.index = node->index; @@ -2089,7 +2092,10 @@ static void bvhtree_nearest_projected_with_clipplane_test_dfs_recursive( { if (node->totnode == 0) { if (data->callback) { - data->callback(data->userdata, node->index, &data->precalc, &data->nearest); + data->callback( + data->userdata, node->index, &data->precalc, + data->clip_plane, data->clip_plane_len, + &data->nearest); } else { data->nearest.index = node->index; diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index c4e3636b617..4e9fd01ba8a 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -85,7 +85,6 @@ typedef struct SnapData { float pmat[4][4]; /* perspective matrix */ float win_size[2];/* win x and y */ enum eViewProj view_proj; - float depth_range[2]; } SnapData; typedef struct SnapObjectData { @@ -213,8 +212,7 @@ static void iter_snap_objects( static void snap_data_set( SnapData *snapdata, const ARegion *ar, const unsigned short snap_to, const enum eViewProj view_proj, - const float mval[2], const float ray_start[3], const float ray_direction[3], - const float depth_range[2]) + const float mval[2], const float ray_start[3], const float ray_direction[3]) { copy_m4_m4(snapdata->pmat, ((RegionView3D *)ar->regiondata)->persmat); snapdata->win_size[0] = ar->winx; @@ -224,7 +222,6 @@ static void snap_data_set( copy_v3_v3(snapdata->ray_start, ray_start); copy_v3_v3(snapdata->ray_dir, ray_direction); snapdata->view_proj = view_proj; - copy_v2_v2(snapdata->depth_range, depth_range); } @@ -900,29 +897,27 @@ static void cb_mlooptri_verts_get( } static bool test_projected_vert_dist( - const struct DistProjectedAABBPrecalc *neasrest_precalc, - const float depth_range[2], + const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, const bool is_persp, const float co[3], float *dist_px_sq, float r_co[3]) { - float w; - if (is_persp) { - w = mul_project_m4_v3_zfac(neasrest_precalc->pmat, co); - if (w < depth_range[0] || w > depth_range[1]) { - return false; - } + if (!isect_point_planes_v3_negated(clip_plane, clip_plane_len, co)) { + //printf("snap_point behind clip plane\n"); + return false; } float co2d[2] = { - (dot_m4_v3_row_x(neasrest_precalc->pmat, co) + neasrest_precalc->pmat[3][0]), - (dot_m4_v3_row_y(neasrest_precalc->pmat, co) + neasrest_precalc->pmat[3][1]), + dot_m4_v3_row_x(precalc->pmat, co) + precalc->pmat[3][0], + dot_m4_v3_row_y(precalc->pmat, co) + precalc->pmat[3][1], }; if (is_persp) { + float w = mul_project_m4_v3_zfac(precalc->pmat, co); mul_v2_fl(co2d, 1.0f / w); } - const float dist_sq = len_squared_v2v2(neasrest_precalc->mval, co2d); + const float dist_sq = len_squared_v2v2(precalc->mval, co2d); if (dist_sq < *dist_px_sq) { copy_v3_v3(r_co, co); *dist_px_sq = dist_sq; @@ -932,20 +927,20 @@ static bool test_projected_vert_dist( } static bool test_projected_edge_dist( - const struct DistProjectedAABBPrecalc *neasrest_precalc, - const float depth_range[2], const bool is_persp, - const float va[3], const float vb[3], + const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, + const bool is_persp, const float va[3], const float vb[3], float *dist_px_sq, float r_co[3]) { float near_co[3], dummy_depth; dist_squared_ray_to_seg_v3( - neasrest_precalc->ray_origin, - neasrest_precalc->ray_direction, + precalc->ray_origin, + precalc->ray_direction, va, vb, near_co, &dummy_depth); return test_projected_vert_dist( - neasrest_precalc, depth_range, + precalc, clip_plane, clip_plane_len, is_persp, near_co, dist_px_sq, r_co); } @@ -979,6 +974,7 @@ typedef struct Nearest2dUserData { static void cb_walk_leaf_snap_vert( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest) { struct Nearest2dUserData *data = userdata; @@ -988,9 +984,9 @@ static void cb_walk_leaf_snap_vert( if (test_projected_vert_dist( precalc, - data->depth_range, - data->is_persp, - co, + clip_plane, + clip_plane_len, + data->is_persp, co, &nearest->dist_sq, nearest->co)) { @@ -1002,6 +998,7 @@ static void cb_walk_leaf_snap_vert( static void cb_walk_leaf_snap_edge( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest) { struct Nearest2dUserData *data = userdata; @@ -1016,7 +1013,8 @@ static void cb_walk_leaf_snap_edge( if (test_projected_edge_dist( precalc, - data->depth_range, + clip_plane, + clip_plane_len, data->is_persp, v_pair[0], v_pair[1], &nearest->dist_sq, @@ -1031,7 +1029,9 @@ static void cb_walk_leaf_snap_edge( if (vindex[i] == nearest->index) { continue; } - cb_walk_leaf_snap_vert(userdata, vindex[i], precalc, nearest); + cb_walk_leaf_snap_vert( + userdata, vindex[i], precalc, + clip_plane, clip_plane_len, nearest); } } } @@ -1039,6 +1039,7 @@ static void cb_walk_leaf_snap_edge( static void cb_walk_leaf_snap_tri( void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, + const float (*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest) { struct Nearest2dUserData *data = userdata; @@ -1051,7 +1052,9 @@ static void cb_walk_leaf_snap_tri( if (eindex[i] == nearest->index) { continue; } - cb_walk_leaf_snap_edge(userdata, eindex[i], precalc, nearest); + cb_walk_leaf_snap_edge( + userdata, eindex[i], precalc, + clip_plane, clip_plane_len, nearest); } } } @@ -1062,7 +1065,9 @@ static void cb_walk_leaf_snap_tri( if (vindex[i] == nearest->index) { continue; } - cb_walk_leaf_snap_vert(userdata, vindex[i], precalc, nearest); + cb_walk_leaf_snap_vert( + userdata, vindex[i], precalc, + clip_plane, clip_plane_len, nearest); } } } @@ -1108,6 +1113,11 @@ static bool snapArmature( } bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; + float clip_plane_local[4]; + planes_from_projmat( + lpmat, + NULL, NULL, NULL, NULL, + clip_plane_local, NULL); if (arm->edbo) { for (EditBone *eBone = arm->edbo->first; eBone; eBone = eBone->next) { @@ -1117,15 +1127,15 @@ static bool snapArmature( switch (snapdata->snap_to) { case SCE_SNAP_MODE_VERTEX: retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, eBone->head, &dist_px_sq, r_loc); retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, eBone->tail, &dist_px_sq, r_loc); break; case SCE_SNAP_MODE_EDGE: retval |= test_projected_edge_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, eBone->head, eBone->tail, &dist_px_sq, r_loc); break; @@ -1145,15 +1155,15 @@ static bool snapArmature( switch (snapdata->snap_to) { case SCE_SNAP_MODE_VERTEX: retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, head_vec, &dist_px_sq, r_loc); retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, tail_vec, &dist_px_sq, r_loc); break; case SCE_SNAP_MODE_EDGE: retval |= test_projected_edge_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, head_vec, tail_vec, &dist_px_sq, r_loc); break; @@ -1209,6 +1219,11 @@ static bool snapCurve( } bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; + float clip_plane_local[4]; + planes_from_projmat( + lpmat, + NULL, NULL, NULL, NULL, + clip_plane_local, NULL); for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { for (int u = 0; u < nu->pntsu; u++) { @@ -1222,7 +1237,7 @@ static bool snapCurve( break; } retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, nu->bezt[u].vec[1], &dist_px_sq, r_loc); /* don't snap if handle is selected (moving), or if it is aligning to a moving handle */ @@ -1230,7 +1245,7 @@ static bool snapCurve( !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) { retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, nu->bezt[u].vec[0], &dist_px_sq, r_loc); } @@ -1238,7 +1253,7 @@ static bool snapCurve( !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) { retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, nu->bezt[u].vec[2], &dist_px_sq, r_loc); } @@ -1249,7 +1264,7 @@ static bool snapCurve( break; } retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, nu->bp[u].vec, &dist_px_sq, r_loc); } @@ -1259,13 +1274,13 @@ static bool snapCurve( if (nu->pntsu > 1) { if (nu->bezt) { retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, nu->bezt[u].vec[1], &dist_px_sq, r_loc); } else { retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, nu->bp[u].vec, &dist_px_sq, r_loc); } @@ -1309,11 +1324,17 @@ static bool snapEmpty( &neasrest_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval); bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; + float clip_plane_local[4]; + planes_from_projmat( + snapdata->pmat, + NULL, NULL, NULL, NULL, + clip_plane_local, NULL); + float dist_px_sq = SQUARE(*dist_px); float co[3]; copy_v3_v3(co, obmat[3]); if (test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, co, &dist_px_sq, r_loc)) { *dist_px = sqrtf(dist_px_sq); @@ -1337,7 +1358,6 @@ static bool snapCamera( { Scene *scene = sctx->scene; - bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; float dist_px_sq = SQUARE(*dist_px); float orig_camera_mat[4][4], orig_camera_imat[4][4], imat[4][4]; @@ -1367,6 +1387,13 @@ static bool snapCamera( dist_squared_to_projected_aabb_precalc( &neasrest_precalc, snapdata->pmat, snapdata->win_size, snapdata->mval); + bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP; + float clip_plane_local[4]; + planes_from_projmat( + snapdata->pmat, + NULL, NULL, NULL, NULL, + clip_plane_local, NULL); + for (tracking_object = tracking->objects.first; tracking_object; tracking_object = tracking_object->next) @@ -1402,7 +1429,7 @@ static bool snapCamera( mul_m4_v3(vertex_obmat, bundle_pos); retval |= test_projected_vert_dist( - &neasrest_precalc, snapdata->depth_range, + &neasrest_precalc, clip_plane_local, 1, is_persp, bundle_pos, &dist_px_sq, r_loc); } } @@ -1553,15 +1580,8 @@ static bool snapMesh( } } - /* Warning: the depth_max is currently being used only in perspective view. - * It is not correct to limit the maximum depth for elements obtained with nearest - * since this limitation depends on the normal and the size of the occlusion face. - * And more... ray_depth is being confused with Z-depth here... (varies only the precision) */ - const float ray_depth_max_global = *ray_depth + snapdata->depth_range[0]; - Nearest2dUserData neasrest2d = { .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP, - .depth_range = {snapdata->depth_range[0], ray_depth_max_global}, .snap_to = snapdata->snap_to, .userdata = treedata, .get_vert_co = (Nearest2DGetVertCoCallback)cb_mvert_co_get, @@ -1713,7 +1733,6 @@ static bool snapEditMesh( Nearest2dUserData neasrest2d = { .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP, - .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]}, .snap_to = snapdata->snap_to, .userdata = treedata->em, .get_vert_co = (Nearest2DGetVertCoCallback)cb_bvert_co_get, |