diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2016-07-09 10:09:47 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2016-07-09 10:09:47 +0300 |
commit | 56ad4520cda00a6b75a6ae475510ce14c2574631 (patch) | |
tree | b21c4af2da7a1f8f82cdcbc46de625d48e188fe2 /source/blender/editors/transform | |
parent | 4e95617769c4c951a0f921feb30bc4312f86ce58 (diff) | |
parent | 1b45c52734a8320322c120c7580080e6fbbc4da6 (diff) |
Merge branch 'master' into strand_editmode
Diffstat (limited to 'source/blender/editors/transform')
6 files changed, 451 insertions, 716 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 95864474fc0..f18493e4b34 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -100,7 +100,6 @@ static void doVertSlide(TransInfo *t, float perc); static void drawEdgeSlide(TransInfo *t); static void drawVertSlide(TransInfo *t); -static void len_v3_ensure(float v[3], const float length); static void postInputRotation(TransInfo *t, float values[3]); static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around); @@ -4957,9 +4956,7 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2])) project_v3_v3v3(vec, vec, axis); } } - normalize_v3(vec); - mul_v3_fl(vec, distance); - mul_v3_fl(vec, td->factor); + normalize_v3_length(vec, distance * td->factor); add_v3_v3v3(td->loc, td->iloc, vec); } @@ -5753,13 +5750,6 @@ static void interp_line_v3_v3v3v3(float p[3], const float v1[3], const float v2[ } } - -static void len_v3_ensure(float v[3], const float length) -{ - normalize_v3(v); - mul_v3_fl(v, length); -} - /** * Find the closest point on the ngon on the opposite side. * used to set the edge slide distance for ngons. @@ -5823,7 +5813,7 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l, if (l->e == e_next) { if (i) { - len_v3_ensure(vec_accum, vec_accum_len / (float)i); + normalize_v3_length(vec_accum, vec_accum_len / (float)i); } else { /* When there is no edge to slide along, @@ -5843,7 +5833,7 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l, cross_v3_v3v3(vec_accum, l_tmp->f->no, tdir); #if 0 /* rough guess, we can do better! */ - len_v3_ensure(vec_accum, (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f); + normalize_v3_length(vec_accum, (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f); #else /* be clever, check the opposite ngon edge to slide into. * this gives best results */ @@ -5858,7 +5848,7 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l, dist = (BM_edge_calc_length(e_prev) + BM_edge_calc_length(e_next)) / 2.0f; } - len_v3_ensure(vec_accum, dist); + normalize_v3_length(vec_accum, dist); } #endif } @@ -5879,7 +5869,7 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l, if (BM_loop_other_edge_loop(l, v)->e == e_next) { if (i) { - len_v3_ensure(vec_accum, vec_accum_len / (float)i); + normalize_v3_length(vec_accum, vec_accum_len / (float)i); } copy_v3_v3(r_slide_vec, vec_accum); @@ -5890,7 +5880,7 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l, ((l = l->radial_next) != l_first)); if (i) { - len_v3_ensure(vec_accum, vec_accum_len / (float)i); + normalize_v3_length(vec_accum, vec_accum_len / (float)i); } copy_v3_v3(r_slide_vec, vec_accum); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 13cc0c22778..d7b670b6476 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -187,9 +187,7 @@ static void viewAxisCorrectCenter(TransInfo *t, float t_con_center[3]) if (l < min_dist) { float diff[3]; - normalize_v3_v3(diff, t->viewinv[2]); - mul_v3_fl(diff, min_dist - l); - + normalize_v3_v3_length(diff, t->viewinv[2], min_dist - l); sub_v3_v3(t_con_center, diff); } } @@ -225,9 +223,8 @@ static void axisProjection(TransInfo *t, const float axis[3], const float in[3], if (factor < 0.0f) factor *= -factor; else factor *= factor; - copy_v3_v3(out, axis); - normalize_v3(out); - mul_v3_fl(out, -factor); /* -factor makes move down going backwards */ + /* -factor makes move down going backwards */ + normalize_v3_v3_length(out, axis, -factor); } else { float v[3], i1[3], i2[3]; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 6d0651e174c..82ad5148c06 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -6641,7 +6641,7 @@ static void createTransObject(bContext *C, TransInfo *t) } /* select linked objects, but skip them later */ - if (ob->id.lib != NULL) { + if (ID_IS_LINKED_DATABLOCK(ob)) { td->flag |= TD_SKIP; } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index ebb427fed67..71b142dabac 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -564,7 +564,7 @@ static void recalcData_nla(TransInfo *t) } /* Use RNA to write the values to ensure that constraints on these are obeyed - * (e.g. for transition strips, the values are taken from the neighbours) + * (e.g. for transition strips, the values are taken from the neighbors) * * NOTE: we write these twice to avoid truncation errors which can arise when * moving the strips a large distance using numeric input [#33852] diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 992fde0cce3..309ad22e31c 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -995,8 +995,7 @@ static void draw_manipulator_rotate( vec[0] = 0; // XXX (float)(t->mouse.imval[0] - t->center2d[0]); vec[1] = 0; // XXX (float)(t->mouse.imval[1] - t->center2d[1]); vec[2] = 0.0f; - normalize_v3(vec); - mul_v3_fl(vec, 1.2f * size); + normalize_v3_length(vec, 1.2f * size); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3fv(vec); @@ -1516,8 +1515,7 @@ static void draw_manipulator_rotate_cyl( vec[0] = 0; // XXX (float)(t->mouse.imval[0] - t->center2d[0]); vec[1] = 0; // XXX (float)(t->mouse.imval[1] - t->center2d[1]); vec[2] = 0.0f; - normalize_v3(vec); - mul_v3_fl(vec, 1.2f * size); + normalize_v3_length(vec, 1.2f * size); glBegin(GL_LINES); glVertex3f(0.0, 0.0, 0.0); glVertex3fv(vec); diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index e85b686b5b3..59dfe18139a 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -221,170 +221,115 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH /** \name Internal Object Snapping API * \{ */ -static bool snapEdge( - const ARegion *ar, const float v1co[3], const short v1no[3], const float v2co[3], const short v2no[3], - float obmat[4][4], float timat[3][3], const float mval_fl[2], - const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], +#define V3_MUL_ELEM(a, b) \ + (a)[0] * (b)[0], \ + (a)[1] * (b)[1], \ + (a)[2] * (b)[2] + +static bool test_vert( + const float vco[3], const float vno[3], const float ray_co[3], const float ray_dir[3], + const float ray_depth_range[2], const float scale[3], const bool is_persp, /* read/write args */ - float *ray_depth, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ - float r_loc[3], float r_no[3]) + float r_co[3], float r_no[3]) { - float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3]; - int result; - bool retval = false; + const float vco_sc[3] = {V3_MUL_ELEM(vco, scale)}; + const float co_sc[3] = {V3_MUL_ELEM(ray_co, scale)}; + const float dir_sc[3] = {V3_MUL_ELEM(ray_dir, scale)}; - copy_v3_v3(ray_end, ray_normal_local); - mul_v3_fl(ray_end, 2000); - add_v3_v3v3(ray_end, ray_start_local, ray_end); - - /* dvec used but we don't care about result */ - result = isect_line_line_v3(v1co, v2co, ray_start_local, ray_end, intersect, dvec); + float depth; + float dist_sq = dist_squared_to_ray_v3(co_sc, dir_sc, vco_sc, &depth); - if (result) { - float edge_loc[3], vec[3]; - float mul; + if (depth < ray_depth_range[0]) { + return false; + } - /* check for behind ray_start */ - sub_v3_v3v3(dvec, intersect, ray_start_local); + if (is_persp) { + dist_sq /= SQUARE(depth); + } - sub_v3_v3v3(edge_loc, v1co, v2co); - sub_v3_v3v3(vec, intersect, v2co); + if ((dist_sq < *dist_to_ray_sq) && (depth < *ray_depth)) { + *dist_to_ray_sq = dist_sq; - mul = dot_v3v3(vec, edge_loc) / dot_v3v3(edge_loc, edge_loc); + copy_v3_v3(r_co, vco); - if (mul > 1) { - mul = 1; - copy_v3_v3(intersect, v1co); - } - else if (mul < 0) { - mul = 0; - copy_v3_v3(intersect, v2co); + if (vno) { + copy_v3_v3(r_no, vno); } - if (dot_v3v3(ray_normal_local, dvec) > 0) { - float location[3]; - float new_depth; - float screen_loc[2]; - float new_dist; - - copy_v3_v3(location, intersect); - - mul_m4_v3(obmat, location); - - new_depth = len_v3v3(location, ray_start); - - if (ED_view3d_project_float_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - new_dist = len_manhattan_v2v2(mval_fl, screen_loc); - } - else { - new_dist = TRANSFORM_DIST_MAX_PX; - } - - /* 10% threshold if edge is closer but a bit further - * this takes care of series of connected edges a bit slanted w.r.t the viewport - * otherwise, it would stick to the verts of the closest edge and not slide along merrily - * */ - if (new_dist <= *dist_px && new_depth < *ray_depth * 1.001f) { - float n1[3], n2[3]; - - *ray_depth = new_depth; - retval = true; - - sub_v3_v3v3(edge_loc, v1co, v2co); - sub_v3_v3v3(vec, intersect, v2co); - - mul = dot_v3v3(vec, edge_loc) / dot_v3v3(edge_loc, edge_loc); - - if (r_no) { - normal_short_to_float_v3(n1, v1no); - normal_short_to_float_v3(n2, v2no); - interp_v3_v3v3(r_no, n2, n1, mul); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - } - - copy_v3_v3(r_loc, location); - - *dist_px = new_dist; - } - } + *ray_depth = depth; + return true; } - - return retval; + return false; } -static bool snapVertex( - const ARegion *ar, const float vco[3], const float vno[3], - float obmat[4][4], float timat[3][3], const float mval_fl[2], - const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], +static bool test_edge( + const float v1[3], const float v2[3], const float ray_co[3], const float ray_dir[3], + const float ray_depth_range[2], const float scale[3], const bool is_persp, /* read/write args */ - float *ray_depth, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ - float r_loc[3], float r_no[3]) + float r_co[3], float r_no[3]) { - bool retval = false; - float dvec[3]; + const float v1_sc[3] = {V3_MUL_ELEM(v1, scale)}; + const float v2_sc[3] = {V3_MUL_ELEM(v2, scale)}; + const float co_sc[3] = {V3_MUL_ELEM(ray_co, scale)}; + const float dir_sc[3] = {V3_MUL_ELEM(ray_dir, scale)}; - sub_v3_v3v3(dvec, vco, ray_start_local); - - if (dot_v3v3(ray_normal_local, dvec) > 0) { - float location[3]; - float new_depth; - float screen_loc[2]; - float new_dist; - - copy_v3_v3(location, vco); - - mul_m4_v3(obmat, location); - - new_depth = len_v3v3(location, ray_start); + float tmp_co[3], depth; + float dist_sq = dist_squared_ray_to_seg_v3(co_sc, dir_sc, v1_sc, v2_sc, tmp_co, &depth); - if (ED_view3d_project_float_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { - new_dist = len_manhattan_v2v2(mval_fl, screen_loc); - } - else { - new_dist = TRANSFORM_DIST_MAX_PX; - } + if (depth < ray_depth_range[0]) { + return false; + } + if (is_persp) { + dist_sq /= SQUARE(depth); + } - if (new_dist <= *dist_px && new_depth < *ray_depth) { - *ray_depth = new_depth; - retval = true; + if ((dist_sq < *dist_to_ray_sq) && (depth < *ray_depth)) { + *dist_to_ray_sq = dist_sq; - copy_v3_v3(r_loc, location); + tmp_co[0] /= scale[0]; + tmp_co[1] /= scale[1]; + tmp_co[2] /= scale[2]; - if (r_no) { - copy_v3_v3(r_no, vno); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - } + copy_v3_v3(r_co, tmp_co); - *dist_px = new_dist; + if (r_no) { + sub_v3_v3v3(r_no, v1, v2); } - } - return retval; + *ray_depth = depth; + return true; + } + return false; } +#undef V3_MUL_ELEM + static bool snapArmature( - const ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], + Object *ob, bArmature *arm, float obmat[4][4], + const short snap_to, const bool is_persp, + const float ray_origin[3], const float ray_normal[3], const float ray_depth_range[2], /* read/write args */ - float *ray_depth, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ float r_loc[3], float *UNUSED(r_no)) { float imat[4][4]; - float ray_start_local[3], ray_normal_local[3]; + float ray_origin_local[3], ray_normal_local[3]; bool retval = false; invert_m4_m4(imat, obmat); - mul_v3_m4v3(ray_start_local, imat, ray_start); + mul_v3_m4v3(ray_origin_local, imat, ray_origin); mul_v3_mat3_m4v3(ray_normal_local, imat, ray_normal); + float ob_scale[3]; + mat4_to_size(ob_scale, obmat); + if (arm->edbo) { EditBone *eBone; @@ -394,21 +339,20 @@ static bool snapArmature( if ((eBone->flag & (BONE_HIDDEN_A | BONE_ROOTSEL | BONE_TIPSEL)) == 0) { switch (snap_to) { case SCE_SNAP_MODE_VERTEX: - retval |= snapVertex( - ar, eBone->head, NULL, obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, ray_depth, + retval |= test_vert( + eBone->head, NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); - retval |= snapVertex( - ar, eBone->tail, NULL, obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, ray_depth, + retval |= test_vert( + eBone->tail, NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); break; case SCE_SNAP_MODE_EDGE: - retval |= snapEdge( - ar, eBone->head, NULL, eBone->tail, NULL, - obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, - ray_depth, r_loc, NULL); + retval |= test_edge( + eBone->head, eBone->tail, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, + r_loc, NULL); break; } } @@ -428,41 +372,43 @@ static bool snapArmature( switch (snap_to) { case SCE_SNAP_MODE_VERTEX: - retval |= snapVertex( - ar, head_vec, NULL, obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, - ray_depth, r_loc, NULL); - retval |= snapVertex( - ar, tail_vec, NULL, obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, ray_depth, + retval |= test_vert( + head_vec, NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, + r_loc, NULL); + retval |= test_vert( + tail_vec, NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); break; case SCE_SNAP_MODE_EDGE: - retval |= snapEdge( - ar, head_vec, NULL, tail_vec, NULL, - obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, - ray_depth, r_loc, NULL); + retval |= test_edge( + head_vec, tail_vec, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, + r_loc, NULL); break; } } } } - - return retval; + if (retval) { + mul_m4_v3(obmat, r_loc); + return true; + } + return false; } static bool snapCurve( - const ARegion *ar, Object *ob, Curve *cu, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], + Object *ob, Curve *cu, float obmat[4][4], + const short snap_to, const bool is_persp, + const float ray_origin[3], const float ray_normal[3], const float ray_depth_range[2], /* read/write args */ - float *ray_depth, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ float r_loc[3], float *UNUSED(r_no)) { float imat[4][4]; - float ray_start_local[3], ray_normal_local[3]; + float ray_origin_local[3], ray_normal_local[3]; bool retval = false; int u; @@ -475,12 +421,15 @@ static bool snapCurve( invert_m4_m4(imat, obmat); - copy_v3_v3(ray_start_local, ray_start); + copy_v3_v3(ray_origin_local, ray_origin); copy_v3_v3(ray_normal_local, ray_normal); - mul_m4_v3(imat, ray_start_local); + mul_m4_v3(imat, ray_origin_local); mul_mat3_m4_v3(imat, ray_normal_local); + float ob_scale[3]; + mat4_to_size(ob_scale, obmat); + for (nu = (ob->mode == OB_MODE_EDIT ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) { for (u = 0; u < nu->pntsu; u++) { switch (snap_to) { @@ -492,28 +441,25 @@ static bool snapCurve( if (nu->bezt[u].f2 & SELECT || nu->bezt[u].hide != 0) { break; } - retval |= snapVertex( - ar, nu->bezt[u].vec[1], NULL, obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, - ray_depth, dist_px, + retval |= test_vert( + nu->bezt[u].vec[1], NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); /* don't snap if handle is selected (moving), or if it is aligning to a moving handle */ if (!(nu->bezt[u].f1 & SELECT) && !(nu->bezt[u].h1 & HD_ALIGN && nu->bezt[u].f3 & SELECT)) { - retval |= snapVertex( - ar, nu->bezt[u].vec[0], NULL, obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, - ray_depth, dist_px, + retval |= test_vert( + nu->bezt[u].vec[0], NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); } if (!(nu->bezt[u].f3 & SELECT) && !(nu->bezt[u].h2 & HD_ALIGN && nu->bezt[u].f1 & SELECT)) { - retval |= snapVertex( - ar, nu->bezt[u].vec[2], NULL, obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, - ray_depth, dist_px, + retval |= test_vert( + nu->bezt[u].vec[2], NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); } } @@ -522,10 +468,9 @@ static bool snapCurve( if (nu->bp[u].f1 & SELECT || nu->bp[u].hide != 0) { break; } - retval |= snapVertex( - ar, nu->bp[u].vec, NULL, obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, - ray_depth, dist_px, + retval |= test_vert( + nu->bp[u].vec, NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); } } @@ -533,17 +478,15 @@ static bool snapCurve( /* curve is not visible outside editmode if nurb length less than two */ if (nu->pntsu > 1) { if (nu->bezt) { - retval |= snapVertex( - ar, nu->bezt[u].vec[1], NULL, obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, - ray_depth, dist_px, + retval |= test_vert( + nu->bezt[u].vec[1], NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); } else { - retval |= snapVertex( - ar, nu->bp[u].vec, NULL, obmat, NULL, mval, - ray_start, ray_start_local, ray_normal_local, - ray_depth, dist_px, + retval |= test_vert( + nu->bp[u].vec, NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); } } @@ -555,43 +498,38 @@ static bool snapCurve( } } } - return retval; + if (retval) { + mul_m4_v3(obmat, r_loc); + return true; + } + return false; } /* may extend later (for now just snaps to empty center) */ static bool snapEmpty( - const ARegion *ar, Object *ob, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], + Object *ob, float obmat[4][4], + const short snap_to, const bool is_persp, + const float ray_origin[3], const float ray_normal[3], const float ray_depth_range[2], /* read/write args */ - float *ray_depth, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ float r_loc[3], float *UNUSED(r_no)) { - float imat[4][4]; - float ray_start_local[3], ray_normal_local[3]; bool retval = false; if (ob->transflag & OB_DUPLI) { return retval; } /* for now only vertex supported */ - if (snap_to != SCE_SNAP_MODE_VERTEX) { - return retval; - } - - invert_m4_m4(imat, obmat); - - mul_v3_m4v3(ray_start_local, imat, ray_start); - mul_v3_mat3_m4v3(ray_normal_local, imat, ray_normal); - switch (snap_to) { case SCE_SNAP_MODE_VERTEX: { - const float zero_co[3] = {0.0f}; - retval |= snapVertex( - ar, zero_co, NULL, obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, ray_depth, + float ob_loc[3], ob_scale[3] = {1.0, 1.0, 1.0}; + copy_v3_v3(ob_loc, obmat[3]); + + retval |= test_vert( + ob_loc, NULL, ray_origin, ray_normal, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); break; } @@ -603,11 +541,11 @@ static bool snapEmpty( } static bool snapCamera( - const ARegion *ar, Scene *scene, Object *object, float obmat[4][4], - const float mval[2], const short snap_to, - const float ray_start[3], const float ray_normal[3], + Scene *scene, Object *object, float obmat[4][4], + const short snap_to, const bool is_persp, + const float ray_origin[3], const float ray_normal[3], const float ray_depth_range[2], /* read/write args */ - float *ray_depth, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ float r_loc[3], float *UNUSED(r_no)) { @@ -615,7 +553,7 @@ static bool snapCamera( bool retval = false; MovieClip *clip = BKE_object_movieclip_get(scene, object, false); MovieTracking *tracking; - float ray_start_local[3], ray_normal_local[3]; + float ray_origin_local[3], ray_normal_local[3]; if (clip == NULL) { return retval; @@ -646,7 +584,7 @@ static bool snapCamera( reconstructed_camera_imat[4][4]; float (*vertex_obmat)[4]; - copy_v3_v3(ray_start_local, ray_start); + copy_v3_v3(ray_origin_local, ray_origin); copy_v3_v3(ray_normal_local, ray_normal); if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) { @@ -665,21 +603,26 @@ static bool snapCamera( copy_v3_v3(bundle_pos, track->bundle_pos); if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - mul_m4_v3(orig_camera_imat, ray_start_local); + mul_m4_v3(orig_camera_imat, ray_origin_local); mul_mat3_m4_v3(orig_camera_imat, ray_normal_local); vertex_obmat = orig_camera_mat; } else { mul_m4_v3(reconstructed_camera_imat, bundle_pos); - mul_m4_v3(imat, ray_start_local); + mul_m4_v3(imat, ray_origin_local); mul_mat3_m4_v3(imat, ray_normal_local); vertex_obmat = obmat; } - retval |= snapVertex( - ar, bundle_pos, NULL, vertex_obmat, NULL, mval, dist_px, - ray_start, ray_start_local, ray_normal_local, ray_depth, + float ob_scale[3]; + mat4_to_size(ob_scale, vertex_obmat); + + retval |= test_vert( + bundle_pos, NULL, ray_origin_local, ray_normal_local, + ray_depth_range, ob_scale, is_persp, ray_depth, dist_to_ray_sq, r_loc, NULL); + + mul_m4_v3(vertex_obmat, r_loc); } } @@ -706,111 +649,6 @@ struct NearestDM_Data { float *ray_depth; }; -static bool test_vert( - const float vco[3], const float vno[3], const float ray_co[3], const float ray_dir[3], - const float ray_depth_range[2], const float scale[3], const bool is_persp, - /* read/write args */ - float *ray_depth, float *dist_to_ray_sq, - /* return args */ - float r_co[3], float r_no[3]) -{ - const float vco_sc[3] = { - vco[0] * scale[0], - vco[1] * scale[1], - vco[2] * scale[2], - }; - const float co_sc[3] = { - ray_co[0] * scale[0], - ray_co[1] * scale[1], - ray_co[2] * scale[2], - }; - const float dir_sc[3] = { - ray_dir[0] * scale[0], - ray_dir[1] * scale[1], - ray_dir[2] * scale[2], - }; - - float depth; - float dist_sq = dist_squared_to_ray_v3(co_sc, dir_sc, vco_sc, &depth); - - if (depth < ray_depth_range[0]) - return false; - - if (is_persp) - dist_sq /= SQUARE(depth); - - if ((dist_sq < *dist_to_ray_sq) && (depth < *ray_depth)) { - *dist_to_ray_sq = dist_sq; - - copy_v3_v3(r_co, vco); - - if (vno) { - copy_v3_v3(r_no, vno); - } - - *ray_depth = depth; - return true; - } - return false; -} - -static bool test_edge( - const float v1[3], const float v2[3], const float ray_co[3], const float ray_dir[3], - const float ray_depth_range[2], const float scale[3], const bool is_persp, - /* read/write args */ - float *ray_depth, float *dist_to_ray_sq, - /* return args */ - float r_co[3], float r_no[3]) -{ - const float v1_sc[3] = { - v1[0] * scale[0], - v1[1] * scale[1], - v1[2] * scale[2], - }; - const float v2_sc[3] = { - v2[0] * scale[0], - v2[1] * scale[1], - v2[2] * scale[2], - }; - const float co_sc[3] = { - ray_co[0] * scale[0], - ray_co[1] * scale[1], - ray_co[2] * scale[2], - }; - const float dir_sc[3] = { - ray_dir[0] * scale[0], - ray_dir[1] * scale[1], - ray_dir[2] * scale[2], - }; - - float tmp_co[3], depth; - float dist_sq = dist_squared_ray_to_seg_v3(co_sc, dir_sc, v1_sc, v2_sc, tmp_co, &depth); - - if (depth < ray_depth_range[0]) - return false; - - if (is_persp) - dist_sq /= SQUARE(depth); - - if ((dist_sq < *dist_to_ray_sq) && (depth < *ray_depth)) { - *dist_to_ray_sq = dist_sq; - - tmp_co[0] /= scale[0]; - tmp_co[1] /= scale[1]; - tmp_co[2] /= scale[2]; - - copy_v3_v3(r_co, tmp_co); - - if (r_no) { - sub_v3_v3v3(r_no, v1, v2); - } - - *ray_depth = depth; - return true; - } - return false; -} - static void test_vert_depth_cb( void *userdata, const float origin[3], const float dir[3], const float scale[3], int index, BVHTreeNearest *nearest) @@ -850,10 +688,10 @@ static void test_edge_depth_cb( static bool snapDerivedMesh( SnapObjectContext *sctx, Object *ob, DerivedMesh *dm, float obmat[4][4], const unsigned int ob_index, - const short snap_to, bool do_bb, + const short snap_to, const bool is_persp, bool do_bb, const float ray_origin[3], const float ray_start[3], const float ray_normal[3], const float ray_depth_range[2], /* read/write args */ - float *ray_depth, float *dist_to_ray_sq, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ float r_loc[3], float r_no[3], int *r_index, ListBase *r_hit_list) @@ -877,7 +715,6 @@ static bool snapDerivedMesh( } { - const bool is_persp = sctx->use_v3d && ((RegionView3D *)sctx->v3d_data.ar->regiondata)->is_persp; bool need_ray_start_correction_init = (snap_to == SCE_SNAP_MODE_FACE) && sctx->use_v3d && !is_persp; float imat[4][4]; @@ -985,189 +822,146 @@ static bool snapDerivedMesh( break; } } - switch (snap_to) { - case SCE_SNAP_MODE_FACE: - { - /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already - * been *inside* boundbox, leading to snap failures (see T38409). - * Note also ar might be null (see T38435), in this case we assume ray_start is ok! - */ - if (sctx->use_v3d && !is_persp) { /* do_ray_start_correction */ - if (need_ray_start_correction_init) { - /* We *need* a reasonably valid len_diff in this case. - * Use BHVTree to find the closest face from ray_start_local. - */ - if (treedata && treedata->tree != NULL) { - BVHTreeNearest nearest; - nearest.index = -1; - nearest.dist_sq = FLT_MAX; - /* Compute and store result. */ - BLI_bvhtree_find_nearest( - treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata); - if (nearest.index != -1) { - float dvec[3]; - sub_v3_v3v3(dvec, nearest.co, ray_start_local); - len_diff = dot_v3v3(dvec, ray_normal_local); - } - } - } - float ray_org_local[3]; - copy_v3_v3(ray_org_local, 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. + if (snap_to == SCE_SNAP_MODE_FACE) { + /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already + * been *inside* boundbox, leading to snap failures (see T38409). + * Note also ar might be null (see T38435), in this case we assume ray_start is ok! + */ + if (sctx->use_v3d && !is_persp) { /* do_ray_start_correction */ + if (need_ray_start_correction_init) { + /* We *need* a reasonably valid len_diff in this case. + * Use BHVTree to find the closest face from ray_start_local. */ - len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ - madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local, - len_diff + ray_depth_range[0]); - local_depth -= len_diff; - } - else { - len_diff = 0.0f; - } - if (r_hit_list) { - struct RayCastAll_Data data; - - data.bvhdata = treedata; - data.raycast_callback = treedata->raycast_callback; - data.obmat = obmat; - data.timat = timat; - data.len_diff = len_diff; - data.local_scale = local_scale; - data.ob = ob; - data.ob_uuid = ob_index; - data.dm = dm; - data.hit_list = r_hit_list; - data.retval = retval; - - BLI_bvhtree_ray_cast_all( - treedata->tree, ray_start_local, ray_normal_local, 0.0f, - *ray_depth, raycast_all_cb, &data); - - retval = data.retval; - } - else { - BVHTreeRayHit hit; - - hit.index = -1; - hit.dist = local_depth; - - if (treedata->tree && - BLI_bvhtree_ray_cast( - treedata->tree, ray_start_local, ray_normal_local, 0.0f, - &hit, treedata->raycast_callback, treedata) != -1) - { - hit.dist += len_diff; - hit.dist /= local_scale; - if (hit.dist <= *ray_depth) { - *ray_depth = hit.dist; - copy_v3_v3(r_loc, hit.co); - copy_v3_v3(r_no, hit.no); - - /* back to worldspace */ - mul_m4_v3(obmat, r_loc); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - - retval = true; - - if (r_index) { - *r_index = dm_looptri_to_poly_index(dm, &treedata->looptri[hit.index]); - } + if (treedata && treedata->tree != NULL) { + BVHTreeNearest nearest; + nearest.index = -1; + nearest.dist_sq = FLT_MAX; + /* Compute and store result. */ + BLI_bvhtree_find_nearest( + treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata); + if (nearest.index != -1) { + float dvec[3]; + sub_v3_v3v3(dvec, nearest.co, ray_start_local); + len_diff = dot_v3v3(dvec, ray_normal_local); } } } - break; - } - case SCE_SNAP_MODE_VERTEX: - { float ray_org_local[3]; copy_v3_v3(ray_org_local, ray_origin); mul_m4_v3(imat, ray_org_local); - BVHTreeNearest nearest; - - nearest.index = -1; - nearest.dist_sq = *dist_to_ray_sq; - - struct NearestDM_Data userdata; - userdata.bvhdata = treedata; - userdata.is_persp = is_persp; - userdata.ray_depth_range = ray_depth_range; - userdata.ray_depth = ray_depth; + /* 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. + */ + len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ + madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local, + len_diff + ray_depth_range[0]); + local_depth -= len_diff; + } + else { + len_diff = 0.0f; + } + if (r_hit_list) { + struct RayCastAll_Data data; + + data.bvhdata = treedata; + data.raycast_callback = treedata->raycast_callback; + data.obmat = obmat; + data.timat = timat; + data.len_diff = len_diff; + data.local_scale = local_scale; + data.ob = ob; + data.ob_uuid = ob_index; + data.dm = dm; + data.hit_list = r_hit_list; + data.retval = retval; + + BLI_bvhtree_ray_cast_all( + treedata->tree, ray_start_local, ray_normal_local, 0.0f, + *ray_depth, raycast_all_cb, &data); + + retval = data.retval; + } + else { + BVHTreeRayHit hit; - float ob_scale[3]; - mat4_to_size(ob_scale, obmat); + hit.index = -1; + hit.dist = local_depth; - if (treedata->tree && ( - is_persp ? - BLI_bvhtree_find_nearest_to_ray_angle( - treedata->tree, ray_org_local, ray_normal_local, - true, ob_scale, &nearest, test_vert_depth_cb, &userdata) : - BLI_bvhtree_find_nearest_to_ray( - treedata->tree, ray_org_local, ray_normal_local, - true, ob_scale, &nearest, test_vert_depth_cb, &userdata)) != -1) + if (treedata->tree && + BLI_bvhtree_ray_cast( + treedata->tree, ray_start_local, ray_normal_local, 0.0f, + &hit, treedata->raycast_callback, treedata) != -1) { - copy_v3_v3(r_loc, nearest.co); - mul_m4_v3(obmat, r_loc); - if (r_no) { - copy_v3_v3(r_no, nearest.no); + hit.dist += len_diff; + hit.dist /= local_scale; + if (hit.dist <= *ray_depth) { + *ray_depth = hit.dist; + copy_v3_v3(r_loc, hit.co); + copy_v3_v3(r_no, hit.no); + + /* back to worldspace */ + mul_m4_v3(obmat, r_loc); mul_m3_v3(timat, r_no); normalize_v3(r_no); - } - *dist_px *= nearest.dist_sq / (*dist_to_ray_sq); - *dist_to_ray_sq = nearest.dist_sq; - retval = true; + retval = true; + + if (r_index) { + *r_index = dm_looptri_to_poly_index(dm, &treedata->looptri[hit.index]); + } + } } - break; } - case SCE_SNAP_MODE_EDGE: - { - float ray_org_local[3]; + } + else { + /* Vert & edge use nearly identical logic. */ + BLI_assert(ELEM(snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)); - copy_v3_v3(ray_org_local, ray_origin); - mul_m4_v3(imat, ray_org_local); + float ray_org_local[3]; - BVHTreeNearest nearest; + copy_v3_v3(ray_org_local, ray_origin); + mul_m4_v3(imat, ray_org_local); - nearest.index = -1; - nearest.dist_sq = *dist_to_ray_sq; + BVHTreeNearest nearest; - struct NearestDM_Data userdata; - userdata.bvhdata = treedata; - userdata.is_persp = is_persp; - userdata.ray_depth_range = ray_depth_range; - userdata.ray_depth = ray_depth; + nearest.index = -1; + nearest.dist_sq = *dist_to_ray_sq; - float ob_scale[3]; - mat4_to_size(ob_scale, obmat); + struct NearestDM_Data userdata; + userdata.bvhdata = treedata; + userdata.is_persp = is_persp; + userdata.ray_depth_range = ray_depth_range; + userdata.ray_depth = ray_depth; - if (treedata->tree && ( - is_persp ? - BLI_bvhtree_find_nearest_to_ray_angle( - treedata->tree, ray_org_local, ray_normal_local, - true, ob_scale, &nearest, test_edge_depth_cb, &userdata) : - BLI_bvhtree_find_nearest_to_ray( - treedata->tree, ray_org_local, ray_normal_local, - true, ob_scale, &nearest, test_edge_depth_cb, &userdata)) != -1) - { - copy_v3_v3(r_loc, nearest.co); - mul_m4_v3(obmat, r_loc); - if (r_no) { - copy_v3_v3(r_no, nearest.no); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - } - *dist_px *= nearest.dist_sq / (*dist_to_ray_sq); - *dist_to_ray_sq = nearest.dist_sq; + float ob_scale[3]; + mat4_to_size(ob_scale, obmat); + + BVHTree_NearestToRayCallback callback = + (snap_to == SCE_SNAP_MODE_VERTEX) ? + test_vert_depth_cb : test_edge_depth_cb; - retval = true; + if (treedata->tree && + (is_persp ? + BLI_bvhtree_find_nearest_to_ray_angle( + treedata->tree, ray_org_local, ray_normal_local, + true, ob_scale, &nearest, callback, &userdata) : + BLI_bvhtree_find_nearest_to_ray( + treedata->tree, ray_org_local, ray_normal_local, + true, ob_scale, &nearest, callback, &userdata)) != -1) + { + copy_v3_v3(r_loc, nearest.co); + mul_m4_v3(obmat, r_loc); + if (r_no) { + copy_v3_v3(r_no, nearest.no); + mul_m3_v3(timat, r_no); + normalize_v3(r_no); } - break; + *dist_to_ray_sq = nearest.dist_sq; + + retval = true; } } @@ -1218,7 +1012,7 @@ static void test_bmedge_depth_cb( static bool snapEditMesh( SnapObjectContext *sctx, Object *ob, BMEditMesh *em, float obmat[4][4], const unsigned int ob_index, - float *dist_px, const short snap_to, + const short snap_to, const bool is_persp, const float ray_origin[3], const float ray_start[3], const float ray_normal[3], const float ray_depth_range[2], /* read/write args */ float *ray_depth, float *dist_to_ray_sq, @@ -1245,8 +1039,6 @@ static bool snapEditMesh( } { - const bool is_persp = (sctx->use_v3d && ((RegionView3D *)sctx->v3d_data.ar->regiondata)->is_persp); - float imat[4][4]; float timat[3][3]; /* transpose inverse matrix for normals */ float ray_normal_local[3]; @@ -1351,197 +1143,153 @@ static bool snapEditMesh( } } - switch (snap_to) { - case SCE_SNAP_MODE_FACE: - { - float ray_start_local[3]; - copy_v3_v3(ray_start_local, ray_start); - mul_m4_v3(imat, ray_start_local); - - /* local scale in normal direction */ - float local_scale = normalize_v3(ray_normal_local); - float local_depth = *ray_depth; - if (local_depth != BVH_RAYCAST_DIST_MAX) { - local_depth *= local_scale; - } + if (snap_to == SCE_SNAP_MODE_FACE) { + float ray_start_local[3]; + copy_v3_v3(ray_start_local, ray_start); + mul_m4_v3(imat, ray_start_local); - /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already - * been *inside* boundbox, leading to snap failures (see T38409). - * Note also ar might be null (see T38435), in this case we assume ray_start is ok! + /* local scale in normal direction */ + float local_scale = normalize_v3(ray_normal_local); + float local_depth = *ray_depth; + if (local_depth != BVH_RAYCAST_DIST_MAX) { + local_depth *= local_scale; + } + + /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already + * been *inside* boundbox, leading to snap failures (see T38409). + * Note also ar might be null (see T38435), in this case we assume ray_start is ok! + */ + float len_diff = 0.0f; + if (sctx->use_v3d && !is_persp) { /* do_ray_start_correction */ + /* We *need* a reasonably valid len_diff in this case. + * Use BHVTree to find the closest face from ray_start_local. */ - float len_diff = 0.0f; - if (sctx->use_v3d && !is_persp) { /* do_ray_start_correction */ - /* We *need* a reasonably valid len_diff in this case. - * Use BHVTree to find the closest face from ray_start_local. - */ - if (treedata && treedata->tree != NULL) { - BVHTreeNearest nearest; - nearest.index = -1; - nearest.dist_sq = FLT_MAX; - /* Compute and store result. */ - if (BLI_bvhtree_find_nearest( - treedata->tree, ray_start_local, &nearest, NULL, NULL) != -1) - { - float dvec[3]; - sub_v3_v3v3(dvec, nearest.co, ray_start_local); - len_diff = dot_v3v3(dvec, ray_normal_local); - float ray_org_local[3]; - - copy_v3_v3(ray_org_local, 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. - */ - len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ - madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local, - len_diff + ray_depth_range[0]); - local_depth -= len_diff; - } - } - } - if (r_hit_list) { - struct RayCastAll_Data data; - - data.bvhdata = treedata; - data.raycast_callback = treedata->raycast_callback; - data.obmat = obmat; - data.timat = timat; - data.len_diff = len_diff; - data.local_scale = local_scale; - data.ob = ob; - data.ob_uuid = ob_index; - data.dm = NULL; - data.hit_list = r_hit_list; - data.retval = retval; - - BLI_bvhtree_ray_cast_all( - treedata->tree, ray_start_local, ray_normal_local, 0.0f, - *ray_depth, raycast_all_cb, &data); - - retval = data.retval; - } - else { - BVHTreeRayHit hit; + if (treedata && treedata->tree != NULL) { + BVHTreeNearest nearest; + nearest.index = -1; + nearest.dist_sq = FLT_MAX; + /* Compute and store result. */ + if (BLI_bvhtree_find_nearest( + treedata->tree, ray_start_local, &nearest, NULL, NULL) != -1) + { + float dvec[3]; + sub_v3_v3v3(dvec, nearest.co, ray_start_local); + len_diff = dot_v3v3(dvec, ray_normal_local); + float ray_org_local[3]; - hit.index = -1; - hit.dist = local_depth; + copy_v3_v3(ray_org_local, ray_origin); + mul_m4_v3(imat, ray_org_local); - if (treedata->tree && - BLI_bvhtree_ray_cast( - treedata->tree, ray_start_local, ray_normal_local, 0.0f, - &hit, treedata->raycast_callback, treedata) != -1) - { - hit.dist += len_diff; - hit.dist /= local_scale; - if (hit.dist <= *ray_depth) { - *ray_depth = hit.dist; - copy_v3_v3(r_loc, hit.co); - copy_v3_v3(r_no, hit.no); - - /* back to worldspace */ - mul_m4_v3(obmat, r_loc); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - - retval = true; - - if (r_index) { - *r_index = hit.index; - } - } + /* 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. + */ + len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */ + madd_v3_v3v3fl(ray_start_local, ray_org_local, ray_normal_local, + len_diff + ray_depth_range[0]); + local_depth -= len_diff; } } - break; } - case SCE_SNAP_MODE_EDGE: - { - float ray_org_local[3]; - - copy_v3_v3(ray_org_local, ray_origin); - mul_m4_v3(imat, ray_org_local); - - BVHTreeNearest nearest; - - nearest.index = -1; - nearest.dist_sq = *dist_to_ray_sq; - - struct NearestDM_Data userdata; - userdata.bvhdata = em; - userdata.is_persp = is_persp; - userdata.ray_depth_range = ray_depth_range; - userdata.ray_depth = ray_depth; + if (r_hit_list) { + struct RayCastAll_Data data; + + data.bvhdata = treedata; + data.raycast_callback = treedata->raycast_callback; + data.obmat = obmat; + data.timat = timat; + data.len_diff = len_diff; + data.local_scale = local_scale; + data.ob = ob; + data.ob_uuid = ob_index; + data.dm = NULL; + data.hit_list = r_hit_list; + data.retval = retval; + + BLI_bvhtree_ray_cast_all( + treedata->tree, ray_start_local, ray_normal_local, 0.0f, + *ray_depth, raycast_all_cb, &data); + + retval = data.retval; + } + else { + BVHTreeRayHit hit; - float ob_scale[3]; - mat4_to_size(ob_scale, obmat); + hit.index = -1; + hit.dist = local_depth; - if (treedata->tree && ( - is_persp ? - BLI_bvhtree_find_nearest_to_ray_angle( - treedata->tree, ray_org_local, ray_normal_local, - false, ob_scale, &nearest, test_bmedge_depth_cb, &userdata) : - BLI_bvhtree_find_nearest_to_ray( - treedata->tree, ray_org_local, ray_normal_local, - false, ob_scale, &nearest, test_bmedge_depth_cb, &userdata)) != -1) + if (treedata->tree && + BLI_bvhtree_ray_cast( + treedata->tree, ray_start_local, ray_normal_local, 0.0f, + &hit, treedata->raycast_callback, treedata) != -1) { - copy_v3_v3(r_loc, nearest.co); - mul_m4_v3(obmat, r_loc); - if (r_no) { - copy_v3_v3(r_no, nearest.no); + hit.dist += len_diff; + hit.dist /= local_scale; + if (hit.dist <= *ray_depth) { + *ray_depth = hit.dist; + copy_v3_v3(r_loc, hit.co); + copy_v3_v3(r_no, hit.no); + + /* back to worldspace */ + mul_m4_v3(obmat, r_loc); mul_m3_v3(timat, r_no); normalize_v3(r_no); - } - *dist_px *= nearest.dist_sq / (*dist_to_ray_sq); - *dist_to_ray_sq = nearest.dist_sq; - retval = true; + retval = true; + + if (r_index) { + *r_index = hit.index; + } + } } - break; } - case SCE_SNAP_MODE_VERTEX: - { - float ray_org_local[3]; + } + else { + /* Vert & edge use nearly identical logic. */ + BLI_assert(ELEM(snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)); - copy_v3_v3(ray_org_local, ray_origin); - mul_m4_v3(imat, ray_org_local); + float ray_org_local[3]; - BVHTreeNearest nearest; + copy_v3_v3(ray_org_local, ray_origin); + mul_m4_v3(imat, ray_org_local); - nearest.index = -1; - nearest.dist_sq = *dist_to_ray_sq; + BVHTreeNearest nearest; - struct NearestDM_Data userdata; - userdata.bvhdata = em; - userdata.is_persp = is_persp; - userdata.ray_depth_range = ray_depth_range; - userdata.ray_depth = ray_depth; + nearest.index = -1; + nearest.dist_sq = *dist_to_ray_sq; - float ob_scale[3]; - mat4_to_size(ob_scale, obmat); + struct NearestDM_Data userdata; + userdata.bvhdata = em; + userdata.is_persp = is_persp; + userdata.ray_depth_range = ray_depth_range; + userdata.ray_depth = ray_depth; - if (treedata->tree && ( - is_persp ? - BLI_bvhtree_find_nearest_to_ray_angle( - treedata->tree, ray_org_local, ray_normal_local, - false, ob_scale, &nearest, test_bmvert_depth_cb, &userdata) : - BLI_bvhtree_find_nearest_to_ray( - treedata->tree, ray_org_local, ray_normal_local, - false, ob_scale, &nearest, test_bmedge_depth_cb, &userdata)) != -1) - { - copy_v3_v3(r_loc, nearest.co); - mul_m4_v3(obmat, r_loc); - if (r_no) { - copy_v3_v3(r_no, nearest.no); - mul_m3_v3(timat, r_no); - normalize_v3(r_no); - } - *dist_px *= nearest.dist_sq / (*dist_to_ray_sq); - *dist_to_ray_sq = nearest.dist_sq; + float ob_scale[3]; + mat4_to_size(ob_scale, obmat); - retval = true; + BVHTree_NearestToRayCallback callback = + (snap_to == SCE_SNAP_MODE_VERTEX) ? + test_bmvert_depth_cb : test_bmedge_depth_cb; + + if (treedata->tree && + (is_persp ? + BLI_bvhtree_find_nearest_to_ray_angle( + treedata->tree, ray_org_local, ray_normal_local, + false, ob_scale, &nearest, callback, &userdata) : + BLI_bvhtree_find_nearest_to_ray( + treedata->tree, ray_org_local, ray_normal_local, + false, ob_scale, &nearest, callback, &userdata)) != -1) + { + copy_v3_v3(r_loc, nearest.co); + mul_m4_v3(obmat, r_loc); + if (r_no) { + copy_v3_v3(r_no, nearest.no); + mul_m3_v3(timat, r_no); + normalize_v3(r_no); } - break; + *dist_to_ray_sq = nearest.dist_sq; + + retval = true; } } @@ -1567,16 +1315,16 @@ static bool snapEditMesh( static bool snapObject( SnapObjectContext *sctx, Object *ob, float obmat[4][4], const unsigned int ob_index, - bool use_obedit, const short snap_to, const float mval[2], + bool use_obedit, const short snap_to, const float ray_origin[3], const float ray_start[3], const float ray_normal[3], const float ray_depth_range[2], /* read/write args */ - float *ray_depth, float *dist_to_ray_sq, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4], ListBase *r_hit_list) { - const ARegion *ar = sctx->v3d_data.ar; + const bool is_persp = sctx->use_v3d && ((RegionView3D *)sctx->v3d_data.ar->regiondata)->is_persp; bool retval = false; if (ob->type == OB_MESH) { @@ -1586,7 +1334,7 @@ static bool snapObject( em = BKE_editmesh_from_object(ob); retval = snapEditMesh( sctx, ob, em, obmat, ob_index, - dist_px, snap_to, + snap_to, is_persp, ray_origin, ray_start, ray_normal, ray_depth_range, ray_depth, dist_to_ray_sq, r_loc, r_no, r_index, @@ -1605,9 +1353,9 @@ static bool snapObject( } retval = snapDerivedMesh( sctx, ob, dm, obmat, ob_index, - snap_to, true, + snap_to, is_persp, true, ray_origin, ray_start, ray_normal, ray_depth_range, - ray_depth, dist_to_ray_sq, dist_px, + ray_depth, dist_to_ray_sq, r_loc, r_no, r_index, r_hit_list); @@ -1616,30 +1364,30 @@ static bool snapObject( } else if (ob->type == OB_ARMATURE) { retval = snapArmature( - ar, ob, ob->data, obmat, mval, snap_to, - ray_start, ray_normal, - ray_depth, dist_px, + ob, ob->data, obmat, snap_to, is_persp, + ray_origin, ray_normal, ray_depth_range, + ray_depth, dist_to_ray_sq, r_loc, r_no); } else if (ob->type == OB_CURVE) { retval = snapCurve( - ar, ob, ob->data, obmat, mval, snap_to, - ray_start, ray_normal, - ray_depth, dist_px, + ob, ob->data, obmat, snap_to, is_persp, + ray_origin, ray_normal, ray_depth_range, + ray_depth, dist_to_ray_sq, r_loc, r_no); } else if (ob->type == OB_EMPTY) { retval = snapEmpty( - ar, ob, obmat, mval, snap_to, - ray_start, ray_normal, - ray_depth, dist_px, + ob, obmat, snap_to, is_persp, + ray_origin, ray_normal, ray_depth_range, + ray_depth, dist_to_ray_sq, r_loc, r_no); } else if (ob->type == OB_CAMERA) { retval = snapCamera( - ar, sctx->scene, ob, obmat, mval, snap_to, - ray_start, ray_normal, - ray_depth, dist_px, + sctx->scene, ob, obmat, snap_to, is_persp, + ray_origin, ray_normal, ray_depth_range, + ray_depth, dist_to_ray_sq, r_loc, r_no); } @@ -1666,7 +1414,6 @@ static bool snapObject( * \param snap_select: from enum SnapSelect. * * \param use_object_edit_cage: Uses the coordinates of BMesh (if any) to do the snapping. - * \param mval: Optional screen-space 2D location we're snapping to (may phase out). * \param ray_origin: ray_start before being moved toward the ray_normal at the distance from vew3d clip_min. * \param ray_start: ray_origin moved for the start clipping plane (clip_min). * \param ray_normal: Unit length direction of the ray. @@ -1678,9 +1425,6 @@ static bool snapObject( * \param dist_to_ray_sq: Real distance (3D) or Tangent (view cone radius at distance 1.0) squared. * resulting of the function #dist_px_to_dist3d_or_tangent. * - * \param dist_px: Pixel distance to element, - * note that this will eventually be replaced entirely by \a dist_to_ray_sq. - * * Output Args * ----------- * @@ -1696,10 +1440,10 @@ static bool snapObject( static bool snapObjectsRay( SnapObjectContext *sctx, const unsigned short snap_to, const SnapSelect snap_select, - const bool use_object_edit_cage, const float mval[2], + const bool use_object_edit_cage, const float ray_origin[3], const float ray_start[3], const float ray_normal[3], /* read/write args */ - float *ray_depth, float *dist_to_ray_sq, float *dist_px, + float *ray_depth, float *dist_to_ray_sq, /* return args */ float r_loc[3], float r_no[3], int *r_index, Object **r_ob, float r_obmat[4][4], @@ -1729,9 +1473,9 @@ static bool snapObjectsRay( retval |= snapObject( sctx, ob, ob->obmat, ob_index++, - false, snap_to, mval, + false, snap_to, ray_origin, ray_start, ray_normal, ray_depth_range, - ray_depth, dist_to_ray_sq, dist_px, + ray_depth, dist_to_ray_sq, r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list); } @@ -1765,9 +1509,9 @@ static bool snapObjectsRay( retval |= snapObject( sctx, dupli_snap, dupli_ob->mat, ob_index++, - use_obedit_dupli, snap_to, mval, + use_obedit_dupli, snap_to, ray_origin, ray_start, ray_normal, ray_depth_range, - ray_depth, dist_to_ray_sq, dist_px, + ray_depth, dist_to_ray_sq, r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list); } @@ -1779,9 +1523,9 @@ static bool snapObjectsRay( retval |= snapObject( sctx, ob_snap, ob->obmat, ob_index++, - use_obedit, snap_to, mval, + use_obedit, snap_to, ray_origin, ray_start, ray_normal, ray_depth_range, - ray_depth, dist_to_ray_sq, dist_px, + ray_depth, dist_to_ray_sq, r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list); } } @@ -1893,9 +1637,8 @@ bool ED_transform_snap_object_project_ray_ex( return snapObjectsRay( sctx, snap_to, params->snap_select, params->use_object_edit_cage, - NULL, ray_start, ray_start, ray_normal, - ray_depth, &dist_to_ray_sq, NULL, + ray_depth, &dist_to_ray_sq, r_loc, r_no, r_index, r_ob, r_obmat, NULL); } @@ -1926,9 +1669,9 @@ bool ED_transform_snap_object_project_ray_all( bool retval = snapObjectsRay( sctx, - snap_to, params->snap_select, params->use_object_edit_cage, NULL, + snap_to, params->snap_select, params->use_object_edit_cage, ray_start, ray_start, ray_normal, - &ray_depth, &dist_to_ray_sq, NULL, + &ray_depth, &dist_to_ray_sq, NULL, NULL, NULL, NULL, NULL, r_hit_list); @@ -2102,9 +1845,9 @@ bool ED_transform_snap_object_project_view3d_ex( return false; } - float dist_to_ray_sq; - { - float radius = dist_px_to_dist3d_or_tangent(sctx->v3d_data.ar, *dist_px); + float radius, dist_to_ray_sq = 0.0f; + if (dist_px) { + radius = dist_px_to_dist3d_or_tangent(sctx->v3d_data.ar, *dist_px); /** * Workaround to use of cone (Instead of project the radius on view plane): * In perspective view, the radius of the cone may decrease depending on the ray direction. @@ -2122,13 +1865,20 @@ bool ED_transform_snap_object_project_view3d_ex( dist_to_ray_sq = SQUARE(radius); } - return snapObjectsRay( + if (snapObjectsRay( sctx, snap_to, params->snap_select, params->use_object_edit_cage, - mval, ray_origin, ray_start, ray_normal, - ray_depth, &dist_to_ray_sq, dist_px, - r_loc, r_no, r_index, NULL, NULL, NULL); + ray_depth, &dist_to_ray_sq, + r_loc, r_no, r_index, NULL, NULL, NULL)) + { + if (dist_px) { + *dist_px *= sqrtf(dist_to_ray_sq) / radius; + } + return true; + } + + return false; } bool ED_transform_snap_object_project_view3d( |