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:
authorBastien Montagne <montagne29@wanadoo.fr>2017-02-02 23:50:12 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2017-02-02 23:50:12 +0300
commitd85295534b6dad80b9c0db32708f7318ef79e134 (patch)
treeaa317d5ce63509aa5bf20f2db1ed159d4961c733 /source/blender/editors/transform
parent47b21dd4c6768e0410e4a73350be75bfb1123188 (diff)
parent9f67367f0aae46f022adb9b47d91c01b35ab9b0f (diff)
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r--source/blender/editors/transform/transform_snap_object.c128
1 files changed, 72 insertions, 56 deletions
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index bed451a32d8..85209b07677 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -387,8 +387,9 @@ typedef struct Nearest2dPrecalc {
float ray_direction_local[3];
float ray_inv_dir[3];
- float depth_range[2];
+ float ray_min_dist;
float pmat[4][4]; /* perspective matrix multiplied by object matrix */
+ bool is_persp;
float win_half[2];
float mval[2];
@@ -400,13 +401,14 @@ typedef struct Nearest2dPrecalc {
*/
static void dist_squared_to_projected_aabb_precalc(
struct Nearest2dPrecalc *neasrest_precalc,
- float lpmat[4][4], const float win_half[2],
- const float depth_range[2], const float mval[2],
+ float lpmat[4][4], bool is_persp, const float win_half[2],
+ const float ray_min_dist, const float mval[2],
const float ray_origin_local[3], const float ray_direction_local[3])
{
copy_m4_m4(neasrest_precalc->pmat, lpmat);
+ neasrest_precalc->is_persp = is_persp;
copy_v2_v2(neasrest_precalc->win_half, win_half);
- copy_v2_v2(neasrest_precalc->depth_range, depth_range);
+ neasrest_precalc->ray_min_dist = ray_min_dist;
copy_v3_v3(neasrest_precalc->ray_origin_local, ray_origin_local);
copy_v3_v3(neasrest_precalc->ray_direction_local, ray_direction_local);
@@ -513,11 +515,11 @@ static float dist_squared_to_projected_aabb(
#define IGNORE_BEHIND_RAY
#ifdef IGNORE_BEHIND_RAY
/* `if rtmax < depth_min`, the hit is behind us */
- if (rtmax < data->depth_range[0]) {
+ if (rtmax < data->ray_min_dist) {
/* Test if the entire AABB is behind us */
float depth = depth_get(
local_bvmax, data->ray_origin_local, data->ray_direction_local);
- if (depth < (data->depth_range[0])) {
+ if (depth < (data->ray_min_dist)) {
return FLT_MAX;
}
}
@@ -528,11 +530,11 @@ static float dist_squared_to_projected_aabb(
}
#ifdef IGNORE_BEHIND_RAY
/* `if rtmin < depth_min`, the hit is behing us */
- else if (rtmin < data->depth_range[0]) {
+ else if (rtmin < data->ray_min_dist) {
/* Test if the entire AABB is behind us */
float depth = depth_get(
local_bvmax, data->ray_origin_local, data->ray_direction_local);
- if (depth < (data->depth_range[0])) {
+ if (depth < (data->ray_min_dist)) {
return FLT_MAX;
}
}
@@ -549,20 +551,24 @@ static float dist_squared_to_projected_aabb(
float scale = fabsf(local_bvmax[main_axis] - local_bvmin[main_axis]);
float (*pmat)[4] = data->pmat;
- float depth_a = mul_project_m4_v3_zfac(pmat, va);
- float depth_b = depth_a + pmat[main_axis][3] * scale;
float va2d[2] = {
(dot_m4_v3_row_x(pmat, va) + pmat[3][0]),
(dot_m4_v3_row_y(pmat, va) + pmat[3][1]),
};
float vb2d[2] = {
- (va2d[0] + pmat[main_axis][0] * scale) / depth_b,
- (va2d[1] + pmat[main_axis][1] * scale) / depth_b,
+ (va2d[0] + pmat[main_axis][0] * scale),
+ (va2d[1] + pmat[main_axis][1] * scale),
};
- va2d[0] /= depth_a;
- va2d[1] /= depth_a;
+ if (data->is_persp) {
+ float depth_a = mul_project_m4_v3_zfac(pmat, va);
+ float depth_b = depth_a + pmat[main_axis][3] * scale;
+ va2d[0] /= depth_a;
+ va2d[1] /= depth_a;
+ vb2d[0] /= depth_b;
+ vb2d[1] /= depth_b;
+ }
va2d[0] += 1.0f;
va2d[1] += 1.0f;
@@ -606,13 +612,13 @@ static float dist_squared_to_projected_aabb(
static float dist_squared_to_projected_aabb_simple(
float lpmat[4][4], const float win_half[2],
- const float depth_range[2], const float mval[2],
+ const float ray_min_dist, const float mval[2],
const float ray_origin_local[3], const float ray_direction_local[3],
const float bbmin[3], const float bbmax[3])
{
struct Nearest2dPrecalc data;
dist_squared_to_projected_aabb_precalc(
- &data, lpmat, win_half, depth_range,
+ &data, lpmat, true, win_half, ray_min_dist,
mval, ray_origin_local, ray_direction_local);
bool dummy[3] = {true, true, true};
@@ -641,11 +647,11 @@ static float dist_aabb_to_plane(
typedef struct Nearest2dUserData {
struct Nearest2dPrecalc data_precalc;
- bool is_persp;
float dist_px_sq;
bool r_axis_closest[3];
+ float depth_range[2];
void *userdata;
int index;
float co[3];
@@ -674,11 +680,11 @@ static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, vo
};
if (test_projected_vert_dist(
- neasrest_precalc->depth_range,
+ data->depth_range,
neasrest_precalc->mval, co,
neasrest_precalc->pmat,
neasrest_precalc->win_half,
- data->is_persp,
+ neasrest_precalc->is_persp,
&data->dist_px_sq,
data->co))
{
@@ -697,11 +703,11 @@ static bool cb_walk_leaf_snap_edge(const BVHTreeAxisRange *UNUSED(bounds), int i
get_edge_verts(data->userdata, index, v_pair);
if (test_projected_edge_dist(
- neasrest_precalc->depth_range,
+ data->depth_range,
neasrest_precalc->mval,
neasrest_precalc->pmat,
neasrest_precalc->win_half,
- data->is_persp,
+ neasrest_precalc->is_persp,
neasrest_precalc->ray_origin_local,
neasrest_precalc->ray_direction_local,
v_pair[0], v_pair[1],
@@ -1114,15 +1120,15 @@ static bool snapDerivedMesh(
float lpmat[4][4];
float ray_org_local[3];
- float depth_range_local[2];
+ float ray_min_dist;
if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
- copy_v3_v3(ray_org_local, snapdata->ray_origin);
- mul_m4_v3(imat, ray_org_local);
- depth_range_local[0] = snapdata->depth_range[0] * local_scale;
- depth_range_local[1] = local_depth + depth_range_local[0];
+ ray_min_dist = snapdata->depth_range[0] * local_scale;
}
+ copy_v3_v3(ray_org_local, snapdata->ray_origin);
+ mul_m4_v3(imat, ray_org_local);
+
if (do_bb) {
BoundBox *bb = BKE_object_boundbox_get(ob);
@@ -1136,7 +1142,7 @@ static bool snapDerivedMesh(
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see T46816. */
if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
float dist_px_sq = dist_squared_to_projected_aabb_simple(
- lpmat, snapdata->win_half, snapdata->depth_range, snapdata->mval,
+ lpmat, snapdata->win_half, ray_min_dist, snapdata->mval,
ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]);
if (dist_px_sq > SQUARE(*dist_px))
{
@@ -1246,11 +1252,6 @@ static bool snapDerivedMesh(
* because even in the Orthografic view, in some cases,
* the ray can start inside the object (see T50486) */
if (len_diff > 400.0f) {
- float ray_org_local[3];
-
- copy_v3_v3(ray_org_local, snapdata->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.
*/
@@ -1321,15 +1322,16 @@ static bool snapDerivedMesh(
BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_MESH};
Nearest2dUserData neasrest2d = {
- .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP,
.dist_px_sq = SQUARE(*dist_px),
.r_axis_closest = {1.0f, 1.0f, 1.0f},
+ .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
.userdata = &treedata_type,
.index = -1};
dist_squared_to_projected_aabb_precalc(
- &neasrest2d.data_precalc, lpmat, snapdata->win_half,
- depth_range_local, snapdata->mval, ray_org_local, ray_normal_local);
+ &neasrest2d.data_precalc, lpmat,
+ snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
+ ray_min_dist, snapdata->mval, ray_org_local, ray_normal_local);
BVHTree_WalkLeafCallback cb_walk_leaf =
(snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
@@ -1612,19 +1614,19 @@ static bool snapEditMesh(
BVHTreeFromMeshType treedata_type = {.userdata = treedata, .type = SNAP_EDIT_MESH};
Nearest2dUserData neasrest2d = {
- .is_persp = snapdata->view_proj == VIEW_PROJ_PERSP,
.dist_px_sq = SQUARE(*dist_px),
.r_axis_closest = {1.0f, 1.0f, 1.0f},
+ .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
.userdata = &treedata_type,
.index = -1};
- float lpmat[4][4], depth_range_local[2];
+ float lpmat[4][4];
mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
- depth_range_local[0] = snapdata->depth_range[0] * local_scale;
- depth_range_local[1] = local_depth + depth_range_local[0];
dist_squared_to_projected_aabb_precalc(
- &neasrest2d.data_precalc, lpmat, snapdata->win_half,
- snapdata->depth_range, snapdata->mval, ray_org_local, ray_normal_local);
+ &neasrest2d.data_precalc, lpmat,
+ snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
+ (snapdata->depth_range[0] * local_scale), snapdata->mval,
+ ray_org_local, ray_normal_local);
BVHTree_WalkLeafCallback cb_walk_leaf =
(snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
@@ -2080,23 +2082,37 @@ static bool transform_snap_context_project_view3d_mixed_impl(
BLI_assert(snap_to_flag != 0);
BLI_assert((snap_to_flag & ~(1 | 2 | 4)) == 0);
- for (int i = 0; i < 3; i++) {
- if ((snap_to_flag & (1 << i)) && (is_hit == false || use_depth)) {
-
- if (ED_transform_snap_object_project_view3d(
- sctx,
- elem_type[i], params,
- mval, dist_px, &ray_depth,
- r_co, r_no))
- {
- is_hit = true;
- if (use_depth == false) {
- ray_depth = BVH_RAYCAST_DIST_MAX;
- }
- else {
+ if (use_depth) {
+ const float dist_px_orig = *dist_px;
+ for (int i = 2; i >= 0; i--) {
+ if (snap_to_flag & (1 << i)) {
+ if (i == 0)
+ *dist_px = dist_px_orig;
+ if (ED_transform_snap_object_project_view3d(
+ sctx,
+ elem_type[i], params,
+ mval, dist_px, &ray_depth,
+ r_co, r_no))
+ {
/* 0.01 is a random but small value to prioritizing
* the first elements of the loop */
- ray_depth -= 0.01f;
+ ray_depth += 0.01f;
+ is_hit = true;
+ }
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < 3; i++) {
+ if (snap_to_flag & (1 << i)) {
+ if (ED_transform_snap_object_project_view3d(
+ sctx,
+ elem_type[i], params,
+ mval, dist_px, &ray_depth,
+ r_co, r_no))
+ {
+ is_hit = true;
+ break;
}
}
}