Merge branch 'blender-v4.0-release' into main

This commit is contained in:
Germano Cavalcante 2023-10-10 11:31:35 -03:00
commit 7d7ca7b90d
4 changed files with 58 additions and 43 deletions

@ -142,15 +142,14 @@ typedef struct BVHRayCastData {
} BVHRayCastData; } BVHRayCastData;
typedef struct BVHNearestProjectedData { typedef struct BVHNearestProjectedData {
const BVHTree *tree;
struct DistProjectedAABBPrecalc precalc; struct DistProjectedAABBPrecalc precalc;
bool closest_axis[3]; bool closest_axis[3];
float clip_plane[6][4];
int clip_plane_len;
BVHTree_NearestProjectedCallback callback; BVHTree_NearestProjectedCallback callback;
void *userdata; void *userdata;
BVHTreeNearest nearest; BVHTreeNearest nearest;
int clip_plane_len;
float clip_plane[0][4];
} BVHNearestProjectedData; } BVHNearestProjectedData;
typedef struct BVHIntersectPlaneData { typedef struct BVHIntersectPlaneData {
@ -2340,54 +2339,57 @@ int BLI_bvhtree_find_nearest_projected(const BVHTree *tree,
{ {
BVHNode *root = tree->nodes[tree->leaf_num]; BVHNode *root = tree->nodes[tree->leaf_num];
if (root != NULL) { if (root != NULL) {
BVHNearestProjectedData data; BVHNearestProjectedData *data = (BVHNearestProjectedData *)alloca(
dist_squared_to_projected_aabb_precalc(&data.precalc, projmat, winsize, mval); sizeof(*data) + (sizeof(*clip_plane) * max_ii(1, clip_plane_len)));
data.callback = callback; dist_squared_to_projected_aabb_precalc(&data->precalc, projmat, winsize, mval);
data.userdata = userdata;
data->callback = callback;
data->userdata = userdata;
if (clip_plane) { if (clip_plane) {
data.clip_plane_len = clip_plane_len; data->clip_plane_len = clip_plane_len;
for (int i = 0; i < data.clip_plane_len; i++) { for (int i = 0; i < clip_plane_len; i++) {
copy_v4_v4(data.clip_plane[i], clip_plane[i]); copy_v4_v4(data->clip_plane[i], clip_plane[i]);
} }
} }
else { else {
data.clip_plane_len = 1; data->clip_plane_len = 1;
planes_from_projmat(projmat, NULL, NULL, NULL, NULL, data.clip_plane[0], NULL); planes_from_projmat(projmat, NULL, NULL, NULL, NULL, data->clip_plane[0], NULL);
} }
if (nearest) { if (nearest) {
memcpy(&data.nearest, nearest, sizeof(*nearest)); memcpy(&data->nearest, nearest, sizeof(*nearest));
} }
else { else {
data.nearest.index = -1; data->nearest.index = -1;
data.nearest.dist_sq = FLT_MAX; data->nearest.dist_sq = FLT_MAX;
} }
{ {
const float bb_min[3] = {root->bv[0], root->bv[2], root->bv[4]}; const float bb_min[3] = {root->bv[0], root->bv[2], root->bv[4]};
const float bb_max[3] = {root->bv[1], root->bv[3], root->bv[5]}; const float bb_max[3] = {root->bv[1], root->bv[3], root->bv[5]};
int isect_type = isect_aabb_planes_v3(data.clip_plane, data.clip_plane_len, bb_min, bb_max); int isect_type = isect_aabb_planes_v3(
data->clip_plane, data->clip_plane_len, bb_min, bb_max);
if (isect_type != 0 && if (isect_type != 0 &&
dist_squared_to_projected_aabb(&data.precalc, bb_min, bb_max, data.closest_axis) <= dist_squared_to_projected_aabb(&data->precalc, bb_min, bb_max, data->closest_axis) <=
data.nearest.dist_sq) data->nearest.dist_sq)
{ {
if (isect_type == 1) { if (isect_type == 1) {
bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(&data, root); bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(data, root);
} }
else { else {
bvhtree_nearest_projected_dfs_recursive(&data, root); bvhtree_nearest_projected_dfs_recursive(data, root);
} }
} }
} }
if (nearest) { if (nearest) {
memcpy(nearest, &data.nearest, sizeof(*nearest)); memcpy(nearest, &data->nearest, sizeof(*nearest));
} }
return data.nearest.index; return data->nearest.index;
} }
return -1; return -1;
} }

@ -561,20 +561,22 @@ bool ED_view3d_win_to_ray_clipped(Depsgraph *depsgraph,
* \param region: The region (used for the window width and height). * \param region: The region (used for the window width and height).
* \param v3d: The 3d viewport (used for near clipping value). * \param v3d: The 3d viewport (used for near clipping value).
* \param mval: The area relative 2d location (such as `event->mval`, converted into float[2]). * \param mval: The area relative 2d location (such as `event->mval`, converted into float[2]).
* \param do_clip_planes: Optionally clip the start of the ray by the view clipping planes.
* \param r_ray_co: The world-space point where the ray intersects the window plane. * \param r_ray_co: The world-space point where the ray intersects the window plane.
* \param r_ray_normal: The normalized world-space direction of towards mval. * \param r_ray_normal: The normalized world-space direction of towards mval.
* \param r_ray_start: The world-space starting point of the ray. * \param r_ray_start: The world-space starting point of the ray.
* \param do_clip_planes: Optionally clip the start of the ray by the view clipping planes. * \param r_ray_end: The world-space end point of the segment.
* \return success, false if the ray is totally clipped. * \return success, false if the ray is totally clipped.
*/ */
bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph, bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph,
const ARegion *region, const ARegion *region,
const View3D *v3d, const View3D *v3d,
const float mval[2], const float mval[2],
const bool do_clip_planes,
float r_ray_co[3], float r_ray_co[3],
float r_ray_normal[3], float r_ray_normal[3],
float r_ray_start[3], float r_ray_start[3],
bool do_clip_planes); float r_ray_end[3]);
/** /**
* Calculate a 3d viewpoint and direction vector from 2d window coordinates. * Calculate a 3d viewpoint and direction vector from 2d window coordinates.
* This ray_start is located at the viewpoint, ray_normal is the direction towards `mval`. * This ray_start is located at the viewpoint, ray_normal is the direction towards `mval`.

@ -372,20 +372,19 @@ bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph,
const ARegion *region, const ARegion *region,
const View3D *v3d, const View3D *v3d,
const float mval[2], const float mval[2],
const bool do_clip_planes,
float r_ray_co[3], float r_ray_co[3],
float r_ray_normal[3], float r_ray_normal[3],
float r_ray_start[3], float r_ray_start[3],
bool do_clip_planes) float r_ray_end[3])
{ {
float ray_end[3];
view3d_win_to_ray_segment( view3d_win_to_ray_segment(
depsgraph, region, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end); depsgraph, region, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, r_ray_end);
/* bounds clipping */ /* bounds clipping */
if (do_clip_planes) { if (do_clip_planes) {
return ED_view3d_clip_segment( return ED_view3d_clip_segment(
static_cast<const RegionView3D *>(region->regiondata), r_ray_start, ray_end); static_cast<const RegionView3D *>(region->regiondata), r_ray_start, r_ray_end);
} }
return true; return true;
@ -400,7 +399,7 @@ bool ED_view3d_win_to_ray_clipped(Depsgraph *depsgraph,
const bool do_clip_planes) const bool do_clip_planes)
{ {
return ED_view3d_win_to_ray_clipped_ex( return ED_view3d_win_to_ray_clipped_ex(
depsgraph, region, v3d, mval, nullptr, r_ray_normal, r_ray_start, do_clip_planes); depsgraph, region, v3d, mval, do_clip_planes, nullptr, r_ray_normal, r_ray_start, nullptr);
} }
void ED_view3d_win_to_ray(const ARegion *region, void ED_view3d_win_to_ray(const ARegion *region,

@ -1257,21 +1257,33 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
float r_face_nor[3]) float r_face_nor[3])
{ {
eSnapMode retval = SCE_SNAP_TO_NONE; eSnapMode retval = SCE_SNAP_TO_NONE;
float ray_depth_max = BVH_RAYCAST_DIST_MAX;
bool use_occlusion_test = params->use_occlusion_test && !XRAY_ENABLED(v3d); bool use_occlusion_test = params->use_occlusion_test && !XRAY_ENABLED(v3d);
if (use_occlusion_test || (snap_to_flag & SCE_SNAP_TO_FACE)) { if (use_occlusion_test || (snap_to_flag & SCE_SNAP_TO_FACE)) {
if (!ED_view3d_win_to_ray_clipped_ex(depsgraph, const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
region, float3 ray_end;
v3d, ED_view3d_win_to_ray_clipped_ex(depsgraph,
mval, region,
nullptr, v3d,
sctx->runtime.ray_dir, mval,
sctx->runtime.ray_start, false,
true)) nullptr,
{ sctx->runtime.ray_dir,
snap_to_flag &= ~SCE_SNAP_TO_FACE; sctx->runtime.ray_start,
use_occlusion_test = false; ray_end);
if (rv3d->rflag & RV3D_CLIPPING) {
if (clip_segment_v3_plane_n(
sctx->runtime.ray_start, ray_end, rv3d->clip, 6, sctx->runtime.ray_start, ray_end))
{
ray_depth_max = math::dot(ray_end - sctx->runtime.ray_start, sctx->runtime.ray_dir);
}
else {
snap_to_flag &= ~SCE_SNAP_TO_FACE;
use_occlusion_test = false;
}
} }
} }
@ -1283,7 +1295,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
params, params,
sctx->runtime.ray_start, sctx->runtime.ray_start,
sctx->runtime.ray_dir, sctx->runtime.ray_dir,
BVH_RAYCAST_DIST_MAX, ray_depth_max,
mval, mval,
init_co, init_co,
prev_co, prev_co,
@ -1465,7 +1477,7 @@ bool ED_transform_snap_object_project_all_view3d_ex(SnapObjectContext *sctx,
float ray_start[3], ray_normal[3]; float ray_start[3], ray_normal[3];
if (!ED_view3d_win_to_ray_clipped_ex( if (!ED_view3d_win_to_ray_clipped_ex(
depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true)) depsgraph, region, v3d, mval, true, nullptr, ray_normal, ray_start, nullptr))
{ {
return false; return false;
} }