From 6220b149d4dc93b615e85adc127530cd57a56799 Mon Sep 17 00:00:00 2001 From: Lars Brubaker Date: Fri, 21 May 2021 12:48:03 -0700 Subject: [PATCH] Took out all the strange logic around moving the world position rather than having a center of rotation --- .../RotateControls/RotateCornerControl.cs | 54 ++++++++-------- .../ScaleControls/ScaleDiameterControl.cs | 6 +- .../ScaleControls/ScaleMatrixCornerControl.cs | 2 +- .../ScaleControls/ScaleMatrixEdgeControl.cs | 4 +- .../ScaleWidthDepthCornerControl.cs | 2 +- .../ScaleWidthDepthEdgeControl.cs | 2 +- .../View3D/TrackballTumbleWidgetExtended.cs | 61 +++---------------- Submodules/agg-sharp | 2 +- 8 files changed, 46 insertions(+), 87 deletions(-) diff --git a/MatterControlLib/DesignTools/EditorTools/RotateControls/RotateCornerControl.cs b/MatterControlLib/DesignTools/EditorTools/RotateControls/RotateCornerControl.cs index 8eae0bd8f..f8ab922b4 100644 --- a/MatterControlLib/DesignTools/EditorTools/RotateControls/RotateCornerControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/RotateControls/RotateCornerControl.cs @@ -209,19 +209,19 @@ namespace MatterHackers.Plugins.EditorTools cornerIndexOut = 0; AxisAlignedBoundingBox currentSelectedBounds = objectBeingRotated.GetAxisAlignedBoundingBox(); - Vector3 bestZCornerPosition = Vector3.Zero; + var bestZCornerPosition = Vector3.Zero; int xCornerIndex = 0; - Vector3 bestXCornerPosition = Vector3.Zero; + var bestXCornerPosition = Vector3.Zero; int yCornerIndex = 1; - Vector3 bestYCornerPosition = Vector3.Zero; + var bestYCornerPosition = Vector3.Zero; int zCornerIndex = 2; double bestCornerZ = double.PositiveInfinity; // get the closest z on the bottom in view space for (int cornerIndex = 0; cornerIndex < 4; cornerIndex++) { - Vector3 cornerPosition = currentSelectedBounds.GetBottomCorner(cornerIndex); - Vector3 cornerScreenSpace = Object3DControlContext.World.GetScreenSpace(cornerPosition); + var cornerPosition = currentSelectedBounds.GetBottomCorner(cornerIndex); + var cornerScreenSpace = Object3DControlContext.World.WorldToScreenSpace(cornerPosition); if (cornerScreenSpace.Z < bestCornerZ) { zCornerIndex = cornerIndex; @@ -230,7 +230,7 @@ namespace MatterHackers.Plugins.EditorTools bestZCornerPosition = SetBottomControlHeight(currentSelectedBounds, bestZCornerPosition); - Vector3 testCornerPosition = currentSelectedBounds.GetBottomCorner((cornerIndex + 1) % 4); + var testCornerPosition = currentSelectedBounds.GetBottomCorner((cornerIndex + 1) % 4); if (testCornerPosition.Y == cornerPosition.Y) { xCornerIndex = (cornerIndex + 1) % 4; @@ -283,7 +283,7 @@ namespace MatterHackers.Plugins.EditorTools AxisAlignedBoundingBox currentSelectedBounds = selectedObject.GetAxisAlignedBoundingBox(); var selectedObjectRotationCenter = currentSelectedBounds.Center; - Vector3 cornerForAxis = GetCornerPosition(selectedObject); + var cornerForAxis = GetCornerPosition(selectedObject); // move the rotation center to the correct side of the bounding box selectedObjectRotationCenter[RotationAxis] = cornerForAxis[RotationAxis]; @@ -323,7 +323,7 @@ namespace MatterHackers.Plugins.EditorTools controlCenter = mouseDownInfo.ControlCenter; } - var hitPlane = new PlaneShape(RotationPlanNormal, Vector3Ex.Dot(RotationPlanNormal, controlCenter), null); + var hitPlane = new PlaneShape(RotationPlanNormal, RotationPlanNormal.Dot(controlCenter), null); IntersectInfo hitOnRotationPlane = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay); if (hitOnRotationPlane != null) { @@ -334,7 +334,7 @@ namespace MatterHackers.Plugins.EditorTools selectedObjectRotationCenter = mouseDownInfo.SelectedObjectRotationCenter; } - Vector3 cornerForAxis = GetCornerPosition(selectedItem); + var cornerForAxis = GetCornerPosition(selectedItem); // move the rotation center to the correct side of the bounding box selectedObjectRotationCenter[RotationAxis] = cornerForAxis[RotationAxis]; @@ -455,7 +455,7 @@ namespace MatterHackers.Plugins.EditorTools public override void SetPosition(IObject3D selectedItem, MeshSelectInfo selectInfo) { - Vector3 boxCenter = GetControlCenter(selectedItem); + var boxCenter = GetControlCenter(selectedItem); double distBetweenPixelsWorldSpace = Object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(boxCenter); GetCornerPosition(selectedItem, out int cornerIndexOut); @@ -583,8 +583,8 @@ namespace MatterHackers.Plugins.EditorTools if (mouseMoveInfo != null && MouseDownOnControl) { var unitPosition = new Vector3(Math.Cos(mouseMoveInfo.AngleOfHit), Math.Sin(mouseMoveInfo.AngleOfHit), 0); - Vector3 startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform); - var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); + var startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform); + var center = Vector3.Zero.Transform(rotationCenterTransform); if ((mouseMoveInfo.HitPosition - center).Length > rotationTransformScale * innerRadius) { Object3DControlContext.World.Render3DLine(startPosition, mouseMoveInfo.HitPosition, theme.PrimaryAccentColor, drawEventArgs.ZBuffered); @@ -634,8 +634,8 @@ namespace MatterHackers.Plugins.EditorTools double startAngle = i * snappingRadians; var unitPosition = new Vector3(Math.Cos(startAngle), Math.Sin(startAngle), 0); - Vector3 startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform); - Vector3 endPosition = Vector3Ex.Transform(unitPosition * outerRadius, rotationCenterTransform); + var startPosition = Vector3Ex.Transform(unitPosition * innerRadius, rotationCenterTransform); + var endPosition = Vector3Ex.Transform(unitPosition * outerRadius, rotationCenterTransform); Object3DControlContext.World.Render3DLine(startPosition, endPosition, new Color(theme.TextColor, (int)(254 * alphaValue)), drawEventArgs.ZBuffered); } @@ -657,10 +657,10 @@ namespace MatterHackers.Plugins.EditorTools /// The center of the control in item space. private Vector3 GetControlCenter(IObject3D selectedItem) { - Vector3 boxCenter = GetCornerPosition(selectedItem); + var boxCenter = GetCornerPosition(selectedItem); double distBetweenPixelsWorldSpace = Object3DControlContext.World.GetWorldUnitsPerScreenPixelAtPosition(boxCenter); // figure out which way the corner is relative to the bounds - Vector3 otherSideDelta = GetDeltaToOtherSideXy(selectedItem); + var otherSideDelta = GetDeltaToOtherSideXy(selectedItem); double xSign = otherSideDelta.X > 0 ? 1 : -1; double ySign = otherSideDelta.Y > 0 ? 1 : -1; @@ -678,9 +678,9 @@ namespace MatterHackers.Plugins.EditorTools { AxisAlignedBoundingBox currentSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(); - Vector3 cornerPosition = GetCornerPosition(selectedItem, out int cornerIndex); - Vector3 cornerPositionCcw = currentSelectedBounds.GetBottomCorner((cornerIndex + 1) % 4); - Vector3 cornerPositionCw = currentSelectedBounds.GetBottomCorner((cornerIndex + 3) % 4); + var cornerPosition = GetCornerPosition(selectedItem, out int cornerIndex); + var cornerPositionCcw = currentSelectedBounds.GetBottomCorner((cornerIndex + 1) % 4); + var cornerPositionCw = currentSelectedBounds.GetBottomCorner((cornerIndex + 3) % 4); double xDirection = cornerPositionCcw.X - cornerPosition.X; if (xDirection == 0) @@ -700,7 +700,7 @@ namespace MatterHackers.Plugins.EditorTools private Vector3 GetRotationCenter(IObject3D selectedItem, AxisAlignedBoundingBox currentSelectedBounds) { var rotationCenter = currentSelectedBounds.Center; - Vector3 cornerForAxis = GetCornerPosition(selectedItem); + var cornerForAxis = GetCornerPosition(selectedItem); // move the rotation center to the plane of the control rotationCenter[RotationAxis] = cornerForAxis[RotationAxis]; @@ -718,8 +718,8 @@ namespace MatterHackers.Plugins.EditorTools AxisAlignedBoundingBox currentSelectedBounds = selectedItem.GetAxisAlignedBoundingBox(); - Vector3 controlCenter = GetControlCenter(selectedItem); - Vector3 rotationCenter = GetRotationCenter(selectedItem, currentSelectedBounds); + var controlCenter = GetControlCenter(selectedItem); + var rotationCenter = GetRotationCenter(selectedItem, currentSelectedBounds); if (mouseDownInfo != null) { rotationCenter = mouseDownInfo.SelectedObjectRotationCenter; @@ -734,7 +734,7 @@ namespace MatterHackers.Plugins.EditorTools rotationTransformScale = distBetweenPixelsWorldSpace; rotationCenterTransform = Matrix4X4.CreateScale(distBetweenPixelsWorldSpace) * Matrix4X4.CreateTranslation(rotationCenter); - var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); + var center = Vector3.Zero.Transform(rotationCenterTransform); switch (RotationAxis) { @@ -746,7 +746,7 @@ namespace MatterHackers.Plugins.EditorTools * Matrix4X4.CreateRotation(new Vector3(-MathHelper.Tau / 4, 0, 0)) * rotationCenterTransform; - var center2 = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); + var center2 = Vector3.Zero.Transform(rotationCenterTransform); rotationCenterTransform *= Matrix4X4.CreateTranslation(center - center2); } @@ -760,7 +760,7 @@ namespace MatterHackers.Plugins.EditorTools * Matrix4X4.CreateRotation(new Vector3(0, MathHelper.Tau / 4, 0)) * rotationCenterTransform; - var center2 = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); + var center2 = Vector3.Zero.Transform(rotationCenterTransform); rotationCenterTransform *= Matrix4X4.CreateTranslation(center - center2); } @@ -799,7 +799,7 @@ namespace MatterHackers.Plugins.EditorTools double outerRadius = innerRadius + RingWidth; double snappingMarkRadius = outerRadius + 20 * GuiWidget.DeviceScale; - var center = Vector3Ex.Transform(Vector3.Zero, rotationCenterTransform); + var center = Vector3.Zero.Transform(rotationCenterTransform); if (Math.Abs((mouseMoveInfo.HitPosition - center).Length - rotationTransformScale * snappingMarkRadius) < 20 * rotationTransformScale) { return i; @@ -821,7 +821,7 @@ namespace MatterHackers.Plugins.EditorTools Matrix4X4 rotationCenterTransform = GetRotationTransform(selectedItem, out double radius); var unitPosition = new Vector3(Math.Cos(mouseDownInfo.AngleOfHit), Math.Sin(mouseDownInfo.AngleOfHit), 0); - Vector3 anglePosition = Vector3Ex.Transform(unitPosition * (radius + 100 * GuiWidget.DeviceScale), rotationCenterTransform); + var anglePosition = Vector3Ex.Transform(unitPosition * (radius + 100 * GuiWidget.DeviceScale), rotationCenterTransform); Vector2 angleDisplayPosition = Object3DControlContext.World.GetScreenPosition(anglePosition); diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs index 4ed30d73d..81a3e1fb6 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleDiameterControl.cs @@ -359,7 +359,7 @@ namespace MatterHackers.Plugins.EditorTools for (int i = 0; i < rotations; i++) { Vector3 cornerPosition = GetEdgePosition(selectedItem, MathHelper.Tau * i / rotations, placement); - Vector3 cornerScreenSpace = Object3DControlContext.World.GetScreenSpace(cornerPosition); + Vector3 cornerScreenSpace = Object3DControlContext.World.WorldToScreenSpace(cornerPosition); if (cornerScreenSpace.Z < bestCornerZ) { bestCornerZ = cornerScreenSpace.Z; @@ -380,7 +380,7 @@ namespace MatterHackers.Plugins.EditorTools for (int i = 0; i < 4; i++) { Vector3 cornerPosition = ObjectSpace.GetEdgePosition(selectedItem, i, placement); - Vector3 cornerScreenSpace = Object3DControlContext.World.GetScreenSpace(cornerPosition); + Vector3 cornerScreenSpace = Object3DControlContext.World.WorldToScreenSpace(cornerPosition); if (cornerScreenSpace.Z < bestCornerZ) { bestCornerZ = cornerScreenSpace.Z; @@ -465,7 +465,7 @@ namespace MatterHackers.Plugins.EditorTools for (int i = 0; i < 4; i++) { corner[i] = ObjectSpace.GetCornerPosition(selectedItem, i); - screen[i] = Object3DControlContext.World.GetScreenSpace(corner[i]); + screen[i] = Object3DControlContext.World.WorldToScreenSpace(corner[i]); } var start = corner[0]; diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixCornerControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixCornerControl.cs index 978a9a82f..48abee454 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixCornerControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixCornerControl.cs @@ -209,7 +209,7 @@ namespace MatterHackers.Plugins.EditorTools for (int i = 0; i < 4; i++) { corner[i] = GetCornerPosition(selectedItem, quadrant + i); - screen[i] = Object3DControlContext.World.GetScreenSpace(corner[i]); + screen[i] = Object3DControlContext.World.WorldToScreenSpace(corner[i]); } var start = corner[0]; diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixEdgeControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixEdgeControl.cs index 191d6a0c2..8a9eae28b 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixEdgeControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleMatrixEdgeControl.cs @@ -401,8 +401,8 @@ namespace MatterHackers.Plugins.EditorTools lines.Clear(); Vector3 otherSideDelta = GetDeltaToOtherSideXy(selectedItem, edgeIndex); var cornerPosition = GetCornerPosition(selectedItem, edgeIndex); - var screen1 = Object3DControlContext.World.GetScreenSpace(cornerPosition); - var screen2 = Object3DControlContext.World.GetScreenSpace(GetCornerPosition(selectedItem, (edgeIndex + 1) % 4)); + var screen1 = Object3DControlContext.World.WorldToScreenSpace(cornerPosition); + var screen2 = Object3DControlContext.World.WorldToScreenSpace(GetCornerPosition(selectedItem, (edgeIndex + 1) % 4)); if (screen1.Z < screen2.Z) { diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthCornerControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthCornerControl.cs index 176bf2bc1..650b22c63 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthCornerControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthCornerControl.cs @@ -441,7 +441,7 @@ namespace MatterHackers.Plugins.EditorTools for (int i = 0; i < 4; i++) { corner[i] = ObjectSpace.GetCornerPosition(selectedItem, quadrant + i); - screen[i] = Object3DControlContext.World.GetScreenSpace(corner[i]); + screen[i] = Object3DControlContext.World.WorldToScreenSpace(corner[i]); } var start = corner[0]; diff --git a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs index fd7cd9900..dadcc1988 100644 --- a/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs +++ b/MatterControlLib/DesignTools/EditorTools/ScaleControls/ScaleWidthDepthEdgeControl.cs @@ -448,7 +448,7 @@ namespace MatterHackers.Plugins.EditorTools for (int i = 0; i < 4; i++) { corner[i] = ObjectSpace.GetCornerPosition(selectedItem, edgeIndex + i); - screen[i] = Object3DControlContext.World.GetScreenSpace(corner[i]); + screen[i] = Object3DControlContext.World.WorldToScreenSpace(corner[i]); } var start = corner[0]; diff --git a/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs b/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs index 0168eef66..55448f72b 100644 --- a/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs +++ b/MatterControlLib/PartPreviewWindow/View3D/TrackballTumbleWidgetExtended.cs @@ -12,9 +12,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { public class TrackballTumbleWidgetExtended : GuiWidget { - // tracks the displacement of the camera to accurately rotate, translate and zoom - public Vector3 bedCenter = Vector3.Zero; - public NearFarAction GetNearFar; private readonly MotionQueue motionQueue = new MotionQueue(); private readonly GuiWidget sourceWidget; @@ -23,16 +20,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow private Vector2 currentVelocityPerMs = new Vector2(); private PlaneShape hitPlane; private bool isRotating = false; - private Vector3 lastRotationOrigin = Vector3.Zero; private Vector2 lastScaleMousePosition = Vector2.Zero; private Vector2 rotationStartPosition = Vector2.Zero; private Vector3 mouseDownWorldPosition; - private Object3DControlsLayer Object3DControlLayer; - private Vector3 rotateVec = Vector3.Zero; - private Vector3 rotateVecOriginal = Vector3.Zero; + private readonly Object3DControlsLayer Object3DControlLayer; private RunningInterval runningInterval; - private ThemeConfig theme; - private WorldView world; + private readonly ThemeConfig theme; + private readonly WorldView world; private Vector2 mouseDown; public TrackballTumbleWidgetExtended(WorldView world, GuiWidget sourceWidget, Object3DControlsLayer Object3DControlLayer, ThemeConfig theme) @@ -71,13 +65,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow { Quaternion activeRotationQuaternion = TrackBallController.GetRotationForMove(TrackBallController.ScreenCenter, TrackBallController.TrackBallRadius, rotationStartPosition, mousePosition, false); rotationStartPosition = mousePosition; - world.Translate(rotateVec); - rotateVec = Vector3Ex.TransformVector(rotateVec, world.RotationMatrix); - world.Rotate(activeRotationQuaternion); - - rotateVec = Vector3Ex.TransformVector(rotateVec, Matrix4X4.Invert(world.RotationMatrix)); - world.Translate(-rotateVec); + world.RotateAroundPosition(mouseDownWorldPosition, activeRotationQuaternion); Invalidate(); } @@ -88,7 +77,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow if (isRotating) { isRotating = false; - bedCenter += rotateVecOriginal - rotateVec; Invalidate(); } } @@ -303,27 +291,17 @@ namespace MatterHackers.MatterControl.PartPreviewWindow public void Reset(Vector3 bedCenter) { ZeroVelocity(); - lastRotationOrigin = Vector3.Zero; - rotateVec = Vector3.Zero; - rotateVecOriginal = Vector3.Zero; - this.bedCenter = -bedCenter; mouseDownWorldPosition = bedCenter; } public void SetRotationWithDisplacement(Quaternion rotationQ) { - StartRotateAroundOrigin(Vector2.Zero); + if (isRotating) + { + ZeroVelocity(); + } - var rotationM = Matrix4X4.CreateRotation(rotationQ); - world.Translate(rotateVec); - rotateVec = Vector3Ex.TransformVector(rotateVec, world.RotationMatrix); - - world.RotationMatrix = rotationM; - - rotateVec = Vector3Ex.TransformVector(rotateVec, Matrix4X4.Invert(world.RotationMatrix)); - world.Translate(-rotateVec); - - EndRotateAroundOrigin(); + world.SetRotationHoldPosition(mouseDownWorldPosition, rotationQ); } public void StartRotateAroundOrigin(Vector2 mousePosition) @@ -336,10 +314,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow rotationStartPosition = mousePosition; isRotating = true; - - rotateVec = -mouseDownWorldPosition - bedCenter; - rotateVecOriginal = rotateVec; - lastRotationOrigin = -mouseDownWorldPosition; } public void Translate(Vector2 position) @@ -357,7 +331,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow if (hitAtPosition != null) { var offset = hitAtPosition.HitPosition - mouseDownWorldPosition; - bedCenter += offset; world.Translate(offset); Invalidate(); @@ -386,9 +359,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow var unitsPerPixel = world.GetWorldUnitsPerScreenPixelAtPosition(worldPosition); // calculate the vector between the camera and the intersection position and move the camera along it by ZoomDelta, then set it's direction - Vector3 zoomVec = (worldPosition - world.EyePosition) * zoomDelta * Math.Min(unitsPerPixel * 100, 1); - - bedCenter += zoomVec; + var zoomVec = (worldPosition - world.EyePosition) * zoomDelta * Math.Min(unitsPerPixel * 100, 1); world.Translate(zoomVec); Invalidate(); @@ -451,18 +422,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow } } - private Vector3 IntersectPlane(Vector3 planeNormal, Vector3 rayOrigin, Vector3 rayDirection) - { - var d = Vector3Ex.Dot(planeNormal, rayDirection); - var t = -(Vector3Ex.Dot(rayOrigin, planeNormal) + d) / d; - return rayOrigin + t * rayDirection; - } - - private Vector3 IntersectXYPlane(Vector3 rayOrigin, Vector3 rayDirection) - { - return IntersectPlane(new Vector3(0, 0, 1), rayOrigin, rayDirection); - } - internal class MotionQueue { private readonly List motionQueue = new List(); diff --git a/Submodules/agg-sharp b/Submodules/agg-sharp index 789136c2a..092733abf 160000 --- a/Submodules/agg-sharp +++ b/Submodules/agg-sharp @@ -1 +1 @@ -Subproject commit 789136c2af87bd2f5c065f39ee0a6a84756a1f0b +Subproject commit 092733abf41333c6b7a85f5fda5c23b5256f2345