Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2016-07-09 10:09:47 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2016-07-09 10:09:47 +0300
commit56ad4520cda00a6b75a6ae475510ce14c2574631 (patch)
treeb21c4af2da7a1f8f82cdcbc46de625d48e188fe2 /source/blender/editors/transform
parent4e95617769c4c951a0f921feb30bc4312f86ce58 (diff)
parent1b45c52734a8320322c120c7580080e6fbbc4da6 (diff)
Merge branch 'master' into strand_editmode
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform.c22
-rw-r--r--source/blender/editors/transform/transform_constraints.c9
-rw-r--r--source/blender/editors/transform/transform_conversions.c2
-rw-r--r--source/blender/editors/transform/transform_generics.c2
-rw-r--r--source/blender/editors/transform/transform_manipulator.c6
-rw-r--r--source/blender/editors/transform/transform_snap_object.c1126
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(