diff --git a/source/blender/editors/include/ED_view3d.hh b/source/blender/editors/include/ED_view3d.hh index c87c4bee636..e7ad7761388 100644 --- a/source/blender/editors/include/ED_view3d.hh +++ b/source/blender/editors/include/ED_view3d.hh @@ -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`. diff --git a/source/blender/editors/space_view3d/view3d_project.cc b/source/blender/editors/space_view3d/view3d_project.cc index 6635d2b7212..20168a57dc5 100644 --- a/source/blender/editors/space_view3d/view3d_project.cc +++ b/source/blender/editors/space_view3d/view3d_project.cc @@ -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(region->regiondata), r_ray_start, ray_end); + static_cast(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, diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 6212da72780..054fc683d4a 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -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(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; }