[Bf-blender-cvs] [950c2ea] master: Transform Snap: Replace pixel limit w/ 'dist_to_ray_sq'
Germano Cavalcante
noreply at git.blender.org
Wed Jul 6 03:42:36 CEST 2016
Commit: 950c2eaf614e895f5856d08faa8e86024b75ef85
Author: Germano Cavalcante
Date: Wed Jul 6 11:34:28 2016 +1000
Branches: master
https://developer.blender.org/rB950c2eaf614e895f5856d08faa8e86024b75ef85
Transform Snap: Replace pixel limit w/ 'dist_to_ray_sq'
When snapping to edge/vert, check the distance to the ray
instead of the screen-space pixel projection.
This also corrects the conversion of `dist_to_ray_sq` to `dist_px` which was being done incorrectly.
While this change was planned, it fixes T48791, caused by error in b01a56ee.
===================================================================
M source/blender/editors/transform/transform_snap_object.c
===================================================================
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index e85b686..c703b87 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;
-
- copy_v3_v3(ray_end, ray_normal_local);
- mul_v3_fl(ray_end, 2000);
- add_v3_v3v3(ray_end, ray_start_local, ray_end);
+ 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)};
- /* 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];
-
- sub_v3_v3v3(dvec, vco, ray_start_local);
+ 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)};
- 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;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list