Fix Snap to Face ignoring back Clip Planes

Snap to Face ignoring some clip planes is an old behavior, but it is
not desirable as the snap is made to non-visible geometry.
This commit is contained in:
Germano Cavalcante
2023-10-10 11:30:15 -03:00
parent c351de8b2a
commit 02ee5a7693
3 changed files with 34 additions and 21 deletions

View File

@@ -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 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 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_normal: The normalized world-space direction of towards mval.
* \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.
*/
bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph,
const ARegion *region,
const View3D *v3d,
const float mval[2],
const bool do_clip_planes,
float r_ray_co[3],
float r_ray_normal[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.
* This ray_start is located at the viewpoint, ray_normal is the direction towards `mval`.

View File

@@ -372,20 +372,19 @@ bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph,
const ARegion *region,
const View3D *v3d,
const float mval[2],
const bool do_clip_planes,
float r_ray_co[3],
float r_ray_normal[3],
float r_ray_start[3],
bool do_clip_planes)
float r_ray_end[3])
{
float ray_end[3];
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 */
if (do_clip_planes) {
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;
@@ -400,7 +399,7 @@ bool ED_view3d_win_to_ray_clipped(Depsgraph *depsgraph,
const bool do_clip_planes)
{
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,

View File

@@ -1257,21 +1257,33 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx,
float r_face_nor[3])
{
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);
if (use_occlusion_test || (snap_to_flag & SCE_SNAP_TO_FACE)) {
if (!ED_view3d_win_to_ray_clipped_ex(depsgraph,
region,
v3d,
mval,
nullptr,
sctx->runtime.ray_dir,
sctx->runtime.ray_start,
true))
{
snap_to_flag &= ~SCE_SNAP_TO_FACE;
use_occlusion_test = false;
const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
float3 ray_end;
ED_view3d_win_to_ray_clipped_ex(depsgraph,
region,
v3d,
mval,
false,
nullptr,
sctx->runtime.ray_dir,
sctx->runtime.ray_start,
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,
sctx->runtime.ray_start,
sctx->runtime.ray_dir,
BVH_RAYCAST_DIST_MAX,
ray_depth_max,
mval,
init_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];
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;
}