Transform: Use the new BLI_bvhtree_find_nearest_projected function to snap.
This commit is contained in:
parent
8cbf402eb6
commit
bf7c46cae0
|
@ -897,8 +897,8 @@ static void cb_mlooptri_verts_get(
|
|||
|
||||
static bool test_projected_vert_dist(
|
||||
struct DistProjectedAABBPrecalc *neasrest_precalc,
|
||||
const float depth_range[2], const float co[3],
|
||||
const bool is_persp,
|
||||
const float depth_range[2],
|
||||
const bool is_persp, const float co[3],
|
||||
float *dist_px_sq, float r_co[3])
|
||||
{
|
||||
float w;
|
||||
|
@ -934,15 +934,15 @@ static bool test_projected_edge_dist(
|
|||
float *dist_px_sq, float r_co[3])
|
||||
{
|
||||
|
||||
float tmp_co[3], dummy_depth;
|
||||
float near_co[3], dummy_depth;
|
||||
dist_squared_ray_to_seg_v3(
|
||||
neasrest_precalc->ray_origin,
|
||||
neasrest_precalc->ray_direction,
|
||||
va, vb, tmp_co, &dummy_depth);
|
||||
va, vb, near_co, &dummy_depth);
|
||||
|
||||
return test_projected_vert_dist(
|
||||
neasrest_precalc, depth_range,
|
||||
tmp_co, is_persp, dist_px_sq, r_co);
|
||||
is_persp, near_co, dist_px_sq, r_co);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -958,8 +958,6 @@ typedef void (*Nearest2DGetTriEdgesCallback)(const int index, int e_index[3], vo
|
|||
typedef void (*Nearest2DCopyVertNoCallback)(const int index, float r_no[3], void *data);
|
||||
|
||||
typedef struct Nearest2dUserData {
|
||||
struct DistProjectedAABBPrecalc data_precalc;
|
||||
bool r_axis_closest[3];
|
||||
bool is_persp;
|
||||
float depth_range[2];
|
||||
short snap_to;
|
||||
|
@ -971,32 +969,13 @@ typedef struct Nearest2dUserData {
|
|||
Nearest2DGetTriEdgesCallback get_tri_edges_index;
|
||||
Nearest2DCopyVertNoCallback copy_vert_no;
|
||||
|
||||
float dist_px_sq;
|
||||
int index;
|
||||
float co[3];
|
||||
float no[3];
|
||||
} Nearest2dUserData;
|
||||
|
||||
|
||||
static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *user_data)
|
||||
{
|
||||
Nearest2dUserData *data = user_data;
|
||||
const float bbmin[3] = {bounds[0].min, bounds[1].min, bounds[2].min};
|
||||
const float bbmax[3] = {bounds[0].max, bounds[1].max, bounds[2].max};
|
||||
const float rdist = dist_squared_to_projected_aabb(
|
||||
&data->data_precalc, bbmin, bbmax, data->r_axis_closest);
|
||||
return rdist < data->dist_px_sq;
|
||||
}
|
||||
|
||||
static bool cb_nearest_walk_order(
|
||||
const BVHTreeAxisRange *UNUSED(bounds), char axis, void *userdata)
|
||||
{
|
||||
const bool *r_axis_closest = ((struct Nearest2dUserData *)userdata)->r_axis_closest;
|
||||
return r_axis_closest[axis];
|
||||
}
|
||||
|
||||
static bool cb_walk_leaf_snap_vert(
|
||||
const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
|
||||
static void cb_walk_leaf_snap_vert(
|
||||
void *userdata, int index,
|
||||
struct DistProjectedAABBPrecalc *precalc,
|
||||
BVHTreeNearest *nearest)
|
||||
{
|
||||
struct Nearest2dUserData *data = userdata;
|
||||
|
||||
|
@ -1004,20 +983,22 @@ static bool cb_walk_leaf_snap_vert(
|
|||
data->get_vert_co(index, &co, data->userdata);
|
||||
|
||||
if (test_projected_vert_dist(
|
||||
&data->data_precalc,
|
||||
data->depth_range, co,
|
||||
precalc,
|
||||
data->depth_range,
|
||||
data->is_persp,
|
||||
&data->dist_px_sq,
|
||||
data->co))
|
||||
co,
|
||||
&nearest->dist_sq,
|
||||
nearest->co))
|
||||
{
|
||||
data->copy_vert_no(index, data->no, data->userdata);
|
||||
data->index = index;
|
||||
data->copy_vert_no(index, nearest->no, data->userdata);
|
||||
nearest->index = index;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cb_walk_leaf_snap_edge(
|
||||
const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
|
||||
static void cb_walk_leaf_snap_edge(
|
||||
void *userdata, int index,
|
||||
struct DistProjectedAABBPrecalc *precalc,
|
||||
BVHTreeNearest *nearest)
|
||||
{
|
||||
struct Nearest2dUserData *data = userdata;
|
||||
|
||||
|
@ -1030,31 +1011,31 @@ static bool cb_walk_leaf_snap_edge(
|
|||
data->get_vert_co(vindex[1], &v_pair[1], data->userdata);
|
||||
|
||||
if (test_projected_edge_dist(
|
||||
&data->data_precalc,
|
||||
precalc,
|
||||
data->depth_range,
|
||||
data->is_persp,
|
||||
v_pair[0], v_pair[1],
|
||||
&data->dist_px_sq,
|
||||
data->co))
|
||||
&nearest->dist_sq,
|
||||
nearest->co))
|
||||
{
|
||||
sub_v3_v3v3(data->no, v_pair[0], v_pair[1]);
|
||||
data->index = index;
|
||||
sub_v3_v3v3(nearest->no, v_pair[0], v_pair[1]);
|
||||
nearest->index = index;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (vindex[i] == data->index) {
|
||||
if (vindex[i] == nearest->index) {
|
||||
continue;
|
||||
}
|
||||
cb_walk_leaf_snap_vert(NULL, vindex[i], userdata);
|
||||
cb_walk_leaf_snap_vert(userdata, vindex[i], precalc, nearest);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cb_walk_leaf_snap_tri(
|
||||
const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
|
||||
static void cb_walk_leaf_snap_tri(
|
||||
void *userdata, int index,
|
||||
struct DistProjectedAABBPrecalc *precalc,
|
||||
BVHTreeNearest *nearest)
|
||||
{
|
||||
struct Nearest2dUserData *data = userdata;
|
||||
|
||||
|
@ -1063,10 +1044,10 @@ static bool cb_walk_leaf_snap_tri(
|
|||
data->get_tri_edges_index(index, eindex, data->userdata);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (eindex[i] != -1) {
|
||||
if (eindex[i] == data->index) {
|
||||
if (eindex[i] == nearest->index) {
|
||||
continue;
|
||||
}
|
||||
cb_walk_leaf_snap_edge(NULL, eindex[i], userdata);
|
||||
cb_walk_leaf_snap_edge(userdata, eindex[i], precalc, nearest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1074,13 +1055,12 @@ static bool cb_walk_leaf_snap_tri(
|
|||
int vindex[3];
|
||||
data->get_tri_verts_index(index, vindex, data->userdata);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (vindex[i] == data->index) {
|
||||
if (vindex[i] == nearest->index) {
|
||||
continue;
|
||||
}
|
||||
cb_walk_leaf_snap_vert(NULL, vindex[i], userdata);
|
||||
cb_walk_leaf_snap_vert(userdata, vindex[i], precalc, nearest);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -1134,10 +1114,10 @@ static bool snapArmature(
|
|||
case SCE_SNAP_MODE_VERTEX:
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
eBone->head, is_persp, &dist_px_sq, r_loc);
|
||||
is_persp, eBone->head, &dist_px_sq, r_loc);
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
eBone->tail, is_persp, &dist_px_sq, r_loc);
|
||||
is_persp, eBone->tail, &dist_px_sq, r_loc);
|
||||
break;
|
||||
case SCE_SNAP_MODE_EDGE:
|
||||
retval |= test_projected_edge_dist(
|
||||
|
@ -1162,10 +1142,10 @@ static bool snapArmature(
|
|||
case SCE_SNAP_MODE_VERTEX:
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
head_vec, is_persp, &dist_px_sq, r_loc);
|
||||
is_persp, head_vec, &dist_px_sq, r_loc);
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
tail_vec, is_persp, &dist_px_sq, r_loc);
|
||||
is_persp, tail_vec, &dist_px_sq, r_loc);
|
||||
break;
|
||||
case SCE_SNAP_MODE_EDGE:
|
||||
retval |= test_projected_edge_dist(
|
||||
|
@ -1239,7 +1219,7 @@ static bool snapCurve(
|
|||
}
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
nu->bezt[u].vec[1], is_persp, &dist_px_sq,
|
||||
is_persp, nu->bezt[u].vec[1], &dist_px_sq,
|
||||
r_loc);
|
||||
/* don't snap if handle is selected (moving), or if it is aligning to a moving handle */
|
||||
if (!(nu->bezt[u].f1 & SELECT) &&
|
||||
|
@ -1247,7 +1227,7 @@ static bool snapCurve(
|
|||
{
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
nu->bezt[u].vec[0], is_persp, &dist_px_sq,
|
||||
is_persp, nu->bezt[u].vec[0], &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
if (!(nu->bezt[u].f3 & SELECT) &&
|
||||
|
@ -1255,7 +1235,7 @@ static bool snapCurve(
|
|||
{
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
nu->bezt[u].vec[2], is_persp, &dist_px_sq,
|
||||
is_persp, nu->bezt[u].vec[2], &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
}
|
||||
|
@ -1266,7 +1246,7 @@ static bool snapCurve(
|
|||
}
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
nu->bp[u].vec, is_persp, &dist_px_sq,
|
||||
is_persp, nu->bp[u].vec, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
}
|
||||
|
@ -1276,13 +1256,13 @@ static bool snapCurve(
|
|||
if (nu->bezt) {
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
nu->bezt[u].vec[1], is_persp, &dist_px_sq,
|
||||
is_persp, nu->bezt[u].vec[1], &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
else {
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
nu->bp[u].vec, is_persp, &dist_px_sq,
|
||||
is_persp, nu->bp[u].vec, &dist_px_sq,
|
||||
r_loc);
|
||||
}
|
||||
}
|
||||
|
@ -1328,11 +1308,11 @@ static bool snapEmpty(
|
|||
|
||||
bool is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
|
||||
float dist_px_sq = SQUARE(*dist_px);
|
||||
float tmp_co[3];
|
||||
copy_v3_v3(tmp_co, obmat[3]);
|
||||
float co[3];
|
||||
copy_v3_v3(co, obmat[3]);
|
||||
if (test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
tmp_co, is_persp, &dist_px_sq, r_loc))
|
||||
is_persp, co, &dist_px_sq, r_loc))
|
||||
{
|
||||
*dist_px = sqrtf(dist_px_sq);
|
||||
*ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
|
||||
|
@ -1423,7 +1403,7 @@ static bool snapCamera(
|
|||
mul_m4_v3(vertex_obmat, bundle_pos);
|
||||
retval |= test_projected_vert_dist(
|
||||
&neasrest_precalc, snapdata->depth_range,
|
||||
bundle_pos, is_persp, &dist_px_sq, r_loc);
|
||||
is_persp, bundle_pos, &dist_px_sq, r_loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1465,23 +1445,22 @@ static bool snapMesh(
|
|||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
|
||||
|
||||
Nearest2dUserData neasrest2d;
|
||||
dist_squared_to_projected_aabb_precalc(
|
||||
&neasrest2d.data_precalc, lpmat, snapdata->win_size, snapdata->mval);
|
||||
|
||||
neasrest2d.r_axis_closest[0] = true;
|
||||
neasrest2d.r_axis_closest[1] = true;
|
||||
neasrest2d.r_axis_closest[2] = true;
|
||||
neasrest2d.dist_px_sq = SQUARE(*dist_px);
|
||||
float dist_px_sq = SQUARE(*dist_px);
|
||||
|
||||
/* Test BoundBox */
|
||||
BoundBox *bb = BKE_mesh_boundbox_get(ob);
|
||||
if (bb) {
|
||||
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
|
||||
float dist_px_sq = dist_squared_to_projected_aabb(
|
||||
&neasrest2d.data_precalc, bb->vec[0], bb->vec[6], neasrest2d.r_axis_closest);
|
||||
|
||||
if (dist_px_sq > neasrest2d.dist_px_sq) {
|
||||
struct DistProjectedAABBPrecalc data_precalc;
|
||||
dist_squared_to_projected_aabb_precalc(
|
||||
&data_precalc, lpmat, snapdata->win_size, snapdata->mval);
|
||||
|
||||
bool dummy[3];
|
||||
float bb_dist_px_sq = dist_squared_to_projected_aabb(
|
||||
&data_precalc, bb->vec[0], bb->vec[6], dummy);
|
||||
|
||||
if (bb_dist_px_sq > dist_px_sq) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
@ -1582,56 +1561,58 @@ static bool snapMesh(
|
|||
* And more... ray_depth is being confused with Z-depth here... (varies only the precision) */
|
||||
const float ray_depth_max_global = *ray_depth + snapdata->depth_range[0];
|
||||
|
||||
neasrest2d.is_persp = snapdata->view_proj == VIEW_PROJ_PERSP;
|
||||
|
||||
neasrest2d.depth_range[0] = snapdata->depth_range[0];
|
||||
neasrest2d.depth_range[1] = ray_depth_max_global;
|
||||
|
||||
neasrest2d.snap_to = snapdata->snap_to;
|
||||
neasrest2d.userdata = treedata;
|
||||
neasrest2d.get_vert_co = (Nearest2DGetVertCoCallback)cb_mvert_co_get;
|
||||
neasrest2d.get_edge_verts_index = (Nearest2DGetEdgeVertsCallback)cb_medge_verts_get;
|
||||
neasrest2d.get_tri_verts_index = (Nearest2DGetTriVertsCallback)cb_mlooptri_verts_get;
|
||||
neasrest2d.get_tri_edges_index = (Nearest2DGetTriEdgesCallback)cb_mlooptri_edges_get;
|
||||
neasrest2d.copy_vert_no = (Nearest2DCopyVertNoCallback)cb_mvert_no_copy;
|
||||
neasrest2d.index = -1;
|
||||
Nearest2dUserData neasrest2d = {
|
||||
.is_persp = snapdata->view_proj == VIEW_PROJ_PERSP,
|
||||
.depth_range = {snapdata->depth_range[0], ray_depth_max_global},
|
||||
.snap_to = snapdata->snap_to,
|
||||
.userdata = treedata,
|
||||
.get_vert_co = (Nearest2DGetVertCoCallback)cb_mvert_co_get,
|
||||
.get_edge_verts_index = (Nearest2DGetEdgeVertsCallback)cb_medge_verts_get,
|
||||
.get_tri_verts_index = (Nearest2DGetTriVertsCallback)cb_mlooptri_verts_get,
|
||||
.get_tri_edges_index = (Nearest2DGetTriEdgesCallback)cb_mlooptri_edges_get,
|
||||
.copy_vert_no = (Nearest2DCopyVertNoCallback)cb_mvert_no_copy,
|
||||
};
|
||||
|
||||
BVHTreeNearest nearest = {
|
||||
.index = -1,
|
||||
.dist_sq = dist_px_sq,
|
||||
};
|
||||
|
||||
if (bvhtree[1]) {
|
||||
/* snap to loose verts */
|
||||
BLI_bvhtree_walk_dfs(
|
||||
bvhtree[1],
|
||||
cb_walk_parent_snap_project, cb_walk_leaf_snap_vert, cb_nearest_walk_order, &neasrest2d);
|
||||
BLI_bvhtree_find_nearest_projected(
|
||||
bvhtree[1], lpmat, snapdata->win_size, snapdata->mval,
|
||||
NULL, 0, &nearest, cb_walk_leaf_snap_vert, &neasrest2d);
|
||||
}
|
||||
|
||||
if (bvhtree[0]) {
|
||||
/* snap to loose edges */
|
||||
BLI_bvhtree_walk_dfs(
|
||||
bvhtree[0],
|
||||
cb_walk_parent_snap_project, cb_walk_leaf_snap_edge, cb_nearest_walk_order, &neasrest2d);
|
||||
BLI_bvhtree_find_nearest_projected(
|
||||
bvhtree[0], lpmat, snapdata->win_size, snapdata->mval,
|
||||
NULL, 0, &nearest, cb_walk_leaf_snap_edge, &neasrest2d);
|
||||
}
|
||||
|
||||
if (treedata->tree) {
|
||||
/* snap to looptris */
|
||||
BLI_bvhtree_walk_dfs(
|
||||
treedata->tree,
|
||||
cb_walk_parent_snap_project, cb_walk_leaf_snap_tri, cb_nearest_walk_order, &neasrest2d);
|
||||
BLI_bvhtree_find_nearest_projected(
|
||||
treedata->tree, lpmat, snapdata->win_size, snapdata->mval,
|
||||
NULL, 0, &nearest, cb_walk_leaf_snap_tri, &neasrest2d);
|
||||
}
|
||||
|
||||
if (neasrest2d.index != -1) {
|
||||
if (nearest.index != -1) {
|
||||
float imat[4][4];
|
||||
float timat[3][3]; /* transpose inverse matrix for normals */
|
||||
invert_m4_m4(imat, obmat);
|
||||
transpose_m3_m4(timat, imat);
|
||||
|
||||
copy_v3_v3(r_loc, neasrest2d.co);
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
if (r_no) {
|
||||
copy_v3_v3(r_no, neasrest2d.no);
|
||||
copy_v3_v3(r_no, nearest.no);
|
||||
mul_m3_v3(timat, r_no);
|
||||
normalize_v3(r_no);
|
||||
}
|
||||
*dist_px = sqrtf(neasrest2d.dist_px_sq);
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
*ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
|
||||
|
||||
retval = true;
|
||||
|
@ -1733,7 +1714,6 @@ static bool snapEditMesh(
|
|||
}
|
||||
|
||||
Nearest2dUserData neasrest2d = {
|
||||
.r_axis_closest = {true, true, true},
|
||||
.is_persp = snapdata->view_proj == VIEW_PROJ_PERSP,
|
||||
.depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
|
||||
.snap_to = snapdata->snap_to,
|
||||
|
@ -1741,36 +1721,37 @@ static bool snapEditMesh(
|
|||
.get_vert_co = (Nearest2DGetVertCoCallback)cb_bvert_co_get,
|
||||
.get_edge_verts_index = (Nearest2DGetEdgeVertsCallback)cb_bedge_verts_get,
|
||||
.copy_vert_no = (Nearest2DCopyVertNoCallback)cb_bvert_no_copy,
|
||||
.dist_px_sq = SQUARE(*dist_px),
|
||||
.index = -1};
|
||||
};
|
||||
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
|
||||
dist_squared_to_projected_aabb_precalc(
|
||||
&neasrest2d.data_precalc, lpmat, snapdata->win_size, snapdata->mval);
|
||||
BVHTreeNearest nearest = {
|
||||
.index = -1,
|
||||
.dist_sq = SQUARE(*dist_px),
|
||||
};
|
||||
|
||||
BVHTree_WalkLeafCallback cb_walk_leaf =
|
||||
BVHTree_NearestProjectedCallback cb_walk_leaf =
|
||||
(snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
|
||||
cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
|
||||
|
||||
BLI_bvhtree_walk_dfs(
|
||||
treedata->tree,
|
||||
cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
|
||||
float lpmat[4][4];
|
||||
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
|
||||
BLI_bvhtree_find_nearest_projected(
|
||||
treedata->tree, lpmat, snapdata->win_size, snapdata->mval,
|
||||
NULL, 0, &nearest, cb_walk_leaf, &neasrest2d);
|
||||
|
||||
if (neasrest2d.index != -1) {
|
||||
if (nearest.index != -1) {
|
||||
float imat[4][4];
|
||||
float timat[3][3]; /* transpose inverse matrix for normals */
|
||||
invert_m4_m4(imat, obmat);
|
||||
transpose_m3_m4(timat, imat);
|
||||
|
||||
copy_v3_v3(r_loc, neasrest2d.co);
|
||||
copy_v3_v3(r_loc, nearest.co);
|
||||
mul_m4_v3(obmat, r_loc);
|
||||
if (r_no) {
|
||||
copy_v3_v3(r_no, neasrest2d.no);
|
||||
copy_v3_v3(r_no, nearest.no);
|
||||
mul_m3_v3(timat, r_no);
|
||||
normalize_v3(r_no);
|
||||
}
|
||||
*dist_px = sqrtf(neasrest2d.dist_px_sq);
|
||||
*dist_px = sqrtf(nearest.dist_sq);
|
||||
*ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
|
||||
|
||||
retval = true;
|
||||
|
|
Loading…
Reference in New Issue