From 8643383b295482ffdf5f81e575bff9bdfacc2d2e Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 21 Nov 2023 13:36:26 -0300 Subject: [PATCH] Fix #114596: snap to face nearest failing with transformed objects In 7f89063161 it was incorrectly assumed that object space was not applied to the variable `co`. --- .../transform/transform_snap_object.cc | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 169857a7132..68c93edb7ea 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -665,7 +665,6 @@ static void nearest_world_tree_co(BVHTree *tree, BVHTree_NearestPointCallback nearest_cb, void *treedata, const float3 &co, - const blender::float4x4 &obmat, BVHTreeNearest *r_nearest) { r_nearest->index = -1; @@ -673,9 +672,6 @@ static void nearest_world_tree_co(BVHTree *tree, r_nearest->dist_sq = FLT_MAX; BLI_bvhtree_find_nearest(tree, co, r_nearest, nearest_cb, treedata); - - float3 vec = float3(r_nearest->co) - co; - r_nearest->dist_sq = math::length(math::transform_direction(obmat, vec)); } bool nearest_world_tree(SnapObjectContext *sctx, @@ -690,19 +686,21 @@ bool nearest_world_tree(SnapObjectContext *sctx, float3 curr_co = math::transform_point(imat, sctx->runtime.curr_co); BVHTreeNearest nearest{}; - float original_distance; + float3 vec; if (sctx->runtime.params.keep_on_same_target) { - nearest_world_tree_co(tree, nearest_cb, treedata, init_co, obmat, &nearest); - original_distance = nearest.dist_sq; + nearest_world_tree_co(tree, nearest_cb, treedata, init_co, &nearest); + vec = float3(nearest.co) - init_co; } else { /* NOTE: when `params->face_nearest_steps == 1`, the return variables of function below contain * the answer. We could return immediately after updating r_loc, r_no, r_index, but that would * also complicate the code. Foregoing slight optimization for code clarity. */ - nearest_world_tree_co(tree, nearest_cb, treedata, curr_co, obmat, &nearest); + nearest_world_tree_co(tree, nearest_cb, treedata, curr_co, &nearest); + vec = float3(nearest.co) - curr_co; } - if (r_nearest->dist_sq <= nearest.dist_sq) { + float original_distance = math::length(math::transform_direction(obmat, vec)); + if (r_nearest->dist_sq <= original_distance) { return false; } @@ -715,7 +713,7 @@ bool nearest_world_tree(SnapObjectContext *sctx, float3 co = init_co; for (int i = 0; i < sctx->runtime.params.face_nearest_steps; i++) { co += delta; - nearest_world_tree_co(tree, nearest_cb, treedata, co, obmat, &nearest); + nearest_world_tree_co(tree, nearest_cb, treedata, co, &nearest); co = nearest.co; } @@ -727,7 +725,8 @@ bool nearest_world_tree(SnapObjectContext *sctx, /* Recalculate the distance. * When multiple steps are tested, we cannot depend on the distance calculated for * `nearest.dist_sq`, as it reduces with each step. */ - r_nearest->dist_sq = math::distance_squared(sctx->runtime.curr_co, co); + vec = co - curr_co; + r_nearest->dist_sq = math::length(math::transform_direction(obmat, vec)); } return true; }