From 6d2d6acc49daf64ca78778dbc2d5a1dd5c2c0629 Mon Sep 17 00:00:00 2001 From: fortsnek9348 Date: Fri, 4 Mar 2022 23:09:18 +0000 Subject: [PATCH] Ensure a minimum height when going from perspective to ortho. --- .../View3D/TrackballTumbleWidgetExtended.cs | 40 +++++++++++++++++-- Submodules/agg-sharp | 2 +- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs b/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs index 5f39067aa..c72a99efe 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs @@ -43,9 +43,27 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { private const double PerspectiveMinZoomDist = 3; private const double PerspectiveMaxZoomDist = 2300; - // Currently: 2.4852813742385704, 1905.3823869162372 - private static readonly double OrthographicMinZoomWorldspaceHeight = PerspectiveMinZoomDist * Math.Tan(MathHelper.DegreesToRadians(WorldView.DefaultPerspectiveVFOVDegrees) / 2) * 2; - private static readonly double OrthographicMaxZoomWorldspaceHeight = PerspectiveMaxZoomDist * Math.Tan(MathHelper.DegreesToRadians(WorldView.DefaultPerspectiveVFOVDegrees) / 2) * 2; + + // Currently 2.7614237491539679 + private double OrthographicMinZoomWorldspaceHeight + { + get + { + // Get the Z plane height at the perspective limit. + // By coincidence, these are currently about the same, with byPerspectiveZoomLimit being slightly less at 2.4852813742385704. + double byPerspectiveZoomLimit = WorldView.CalcPerspectiveHeight(PerspectiveMinZoomDist, WorldView.DefaultPerspectiveVFOVDegrees); + double byWorldViewLimit = WorldView.OrthographicProjectionMinimumHeight * Vector3.UnitY.TransformVector(this.world.InverseModelviewMatrix).Length; + return Math.Max(byPerspectiveZoomLimit, byWorldViewLimit); + } + } + + // Currently 1905.3823869162372 + private double OrthographicMaxZoomWorldspaceHeight => WorldView.CalcPerspectiveHeight(PerspectiveMaxZoomDist, WorldView.DefaultPerspectiveVFOVDegrees); + + // When switching the projection from perspective to orthographic, ensure this minimum height. + // Will tend to be used when fully zoomed into the hit plane, and then the ref position indicator will appear to drift during the animation. + // The resulting projection might be undesired, but at least it would be non-zero. + private double PerspectiveToOrthographicMinViewspaceHeight => WorldView.OrthographicProjectionMinimumHeight; public NearFarAction GetNearFar; private readonly MotionQueue motionQueue = new MotionQueue(); @@ -685,6 +703,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow Vector3 viewspaceRefPosition = worldspaceRefPosition.TransformPosition(this.world.ModelviewMatrix); // Don't let this become negative when the ref position is behind the camera. double refPlaneHeightInViewspace = Math.Abs(this.world.GetViewspaceHeightAtPosition(viewspaceRefPosition)); + + double refViewspaceZ = viewspaceRefPosition.Z; + + // Ensure a minimum when going from perspective (in case the camera is zoomed all the way into the hit plane). + if (toOrthographic) + { + double minViewspaceHeight = PerspectiveToOrthographicMinViewspaceHeight; + if (refPlaneHeightInViewspace < minViewspaceHeight) + { + // If this happens, the ref position indicator will appear to drift during the animation. + refPlaneHeightInViewspace = minViewspaceHeight; + refViewspaceZ = -WorldView.CalcPerspectiveDistance(minViewspaceHeight, this.world.VFovDegrees); + } + } double refFOV = MathHelper.DegreesToRadians( toOrthographic @@ -706,7 +738,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow double fov = toOrthographic ? refFOV * (1 - t) : refFOV * t; double dist = refPlaneHeightInViewspace / 2 / Math.Tan(fov / 2); - double eyeZ = viewspaceRefPosition.Z + dist; + double eyeZ = refViewspaceZ + dist; Vector3 viewspaceEyePosition = new Vector3(0, 0, eyeZ); diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 4c22416f0..992a40c44 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 4c22416f074835246ab2b0f15f25356c02838b89 +Subproject commit 992a40c44497b380e3cb2ece129ebed66f8838ba