From 0abdcb00238c66dd263740c1d7bb751e18240ed2 Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Fri, 1 Jul 2022 10:26:59 +0100 Subject: [PATCH 1/4] More intuitive angle-snapping behavior (and minor refactor) --- Assets/Scripts/SelectionManager.cs | 24 ++++++++++++++++++++++ Assets/Scripts/Widgets/GrabWidget.cs | 30 +++------------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Assets/Scripts/SelectionManager.cs b/Assets/Scripts/SelectionManager.cs index 1034fd6646..ba7457713b 100644 --- a/Assets/Scripts/SelectionManager.cs +++ b/Assets/Scripts/SelectionManager.cs @@ -977,6 +977,30 @@ public void SetSnappingGridSize(int snapIndex) } } + public Quaternion QuantizeAngle(Quaternion rotation) + { + if (SnappingAngle == 0) return Quaternion.identity; + float round(float val) { return Mathf.Round(val / SnappingAngle) * SnappingAngle;} + Vector3 euler = rotation.eulerAngles; + float y = euler.y; + euler = new Vector3(round(euler.x), 0, round(euler.z)); + rotation = Quaternion.Euler(euler); + rotation *= Quaternion.Euler(0, round(y), 0); + return rotation; + } + + public Vector3 SnapToGrid(Vector3 position) + { + if (SnappingGridSize == 0) return position; + Vector3 localCanvasPos = App.ActiveCanvas.transform.worldToLocalMatrix.MultiplyPoint3x4(position); + float round(float val) { return Mathf.Round(val / SnappingGridSize) * SnappingGridSize; } + Vector3 roundedCanvasPos = new Vector3( + round(localCanvasPos.x), + round(localCanvasPos.y), + round(localCanvasPos.z) + ); + return App.ActiveCanvas.transform.localToWorldMatrix.MultiplyPoint3x4(roundedCanvasPos); + } } diff --git a/Assets/Scripts/Widgets/GrabWidget.cs b/Assets/Scripts/Widgets/GrabWidget.cs index 16689db073..6e58fd7c38 100644 --- a/Assets/Scripts/Widgets/GrabWidget.cs +++ b/Assets/Scripts/Widgets/GrabWidget.cs @@ -1211,7 +1211,7 @@ virtual protected TrTransform GetSnappedTransform(TrTransform xf_GS) if (SelectionManager.m_Instance.CurrentSnapAngleIndex != 0) { var rot_CS = xf_GS.rotation * App.Scene.Pose.rotation.TrueInverse(); - Quaternion nearestSnapRotation_CS = QuantizeAngle(rot_CS); + Quaternion nearestSnapRotation_CS = SelectionManager.m_Instance.QuantizeAngle(rot_CS); float snapAngle = SelectionManager.m_Instance.SnappingAngle; float stickiness = m_ValidSnapRotationStickyAngle / 90f; @@ -1236,36 +1236,12 @@ virtual protected TrTransform GetSnappedTransform(TrTransform xf_GS) if (SelectionManager.m_Instance.CurrentSnapGridIndex != 0) { - outXf_GS.translation = SnapToGrid(outXf_GS.translation); + outXf_GS.translation = SelectionManager.m_Instance.SnapToGrid(outXf_GS.translation); } return outXf_GS; } - - private Quaternion QuantizeAngle(Quaternion rotation) - { - var snapAngle = SelectionManager.m_Instance.SnappingAngle; - float round(float val) { return Mathf.Round(val / snapAngle) * snapAngle; } - - Vector3 euler = rotation.eulerAngles; - euler = new Vector3(round(euler.x), round(euler.y), round(euler.z)); - return Quaternion.Euler(euler); - } - - public static Vector3 SnapToGrid(Vector3 position) - { - float gridSize = SelectionManager.m_Instance.SnappingGridSize; - Vector3 localCanvasPos = App.ActiveCanvas.transform.worldToLocalMatrix.MultiplyPoint3x4(position); - float round(float val) { return Mathf.Round(val / gridSize) * gridSize; } - Vector3 roundedCanvasPos = new Vector3( - round(localCanvasPos.x), - round(localCanvasPos.y), - round(localCanvasPos.z) - ); - return App.ActiveCanvas.transform.localToWorldMatrix.MultiplyPoint3x4(roundedCanvasPos); - } - - + protected int GetBestSnapRotationIndex(Quaternion rot) { float fNearestDot = 0.0f; From 72903a29e1bbe4a57f9c5c15ed2fe7f26e10fc2c Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Fri, 1 Jul 2022 10:28:31 +0100 Subject: [PATCH 2/4] dotnet-format --- Assets/Scripts/SelectionManager.cs | 4 ++-- Assets/Scripts/Widgets/GrabWidget.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/SelectionManager.cs b/Assets/Scripts/SelectionManager.cs index ba7457713b..52106883ed 100644 --- a/Assets/Scripts/SelectionManager.cs +++ b/Assets/Scripts/SelectionManager.cs @@ -980,7 +980,7 @@ public void SetSnappingGridSize(int snapIndex) public Quaternion QuantizeAngle(Quaternion rotation) { if (SnappingAngle == 0) return Quaternion.identity; - float round(float val) { return Mathf.Round(val / SnappingAngle) * SnappingAngle;} + float round(float val) { return Mathf.Round(val / SnappingAngle) * SnappingAngle; } Vector3 euler = rotation.eulerAngles; float y = euler.y; euler = new Vector3(round(euler.x), 0, round(euler.z)); @@ -988,7 +988,7 @@ public Quaternion QuantizeAngle(Quaternion rotation) rotation *= Quaternion.Euler(0, round(y), 0); return rotation; } - + public Vector3 SnapToGrid(Vector3 position) { if (SnappingGridSize == 0) return position; diff --git a/Assets/Scripts/Widgets/GrabWidget.cs b/Assets/Scripts/Widgets/GrabWidget.cs index 6e58fd7c38..24d12bb415 100644 --- a/Assets/Scripts/Widgets/GrabWidget.cs +++ b/Assets/Scripts/Widgets/GrabWidget.cs @@ -1241,7 +1241,7 @@ virtual protected TrTransform GetSnappedTransform(TrTransform xf_GS) return outXf_GS; } - + protected int GetBestSnapRotationIndex(Quaternion rot) { float fNearestDot = 0.0f; From b88e163cc7d6b71f0948b4f343999c98cb66ec4f Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Mon, 4 Jul 2022 11:02:39 +0100 Subject: [PATCH 3/4] Better comments in angle quantize method --- Assets/Scripts/SelectionManager.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Assets/Scripts/SelectionManager.cs b/Assets/Scripts/SelectionManager.cs index 52106883ed..32a9618b56 100644 --- a/Assets/Scripts/SelectionManager.cs +++ b/Assets/Scripts/SelectionManager.cs @@ -979,13 +979,22 @@ public void SetSnappingGridSize(int snapIndex) public Quaternion QuantizeAngle(Quaternion rotation) { + // Currently a snapping angle of "0" means "no-snapping". It might in future mean "snap to whole rotations only" if (SnappingAngle == 0) return Quaternion.identity; + float round(float val) { return Mathf.Round(val / SnappingAngle) * SnappingAngle; } + Vector3 euler = rotation.eulerAngles; float y = euler.y; + + // First snap to x and z to get a rotation around the origin euler = new Vector3(round(euler.x), 0, round(euler.z)); rotation = Quaternion.Euler(euler); + + // Snap to the local y last to handle snapping around the x/z axis + // (Snapping x/y/z all at once results in counter-intuitive results) rotation *= Quaternion.Euler(0, round(y), 0); + return rotation; } From cdb6c494050654505d1b5efd16492ab6cd1eb387 Mon Sep 17 00:00:00 2001 From: Andy Baker Date: Mon, 4 Jul 2022 11:12:27 +0100 Subject: [PATCH 4/4] dotnet-format Sigh... --- Assets/Scripts/SelectionManager.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Assets/Scripts/SelectionManager.cs b/Assets/Scripts/SelectionManager.cs index 32a9618b56..53d0231fae 100644 --- a/Assets/Scripts/SelectionManager.cs +++ b/Assets/Scripts/SelectionManager.cs @@ -981,20 +981,20 @@ public Quaternion QuantizeAngle(Quaternion rotation) { // Currently a snapping angle of "0" means "no-snapping". It might in future mean "snap to whole rotations only" if (SnappingAngle == 0) return Quaternion.identity; - + float round(float val) { return Mathf.Round(val / SnappingAngle) * SnappingAngle; } - + Vector3 euler = rotation.eulerAngles; float y = euler.y; - + // First snap to x and z to get a rotation around the origin euler = new Vector3(round(euler.x), 0, round(euler.z)); rotation = Quaternion.Euler(euler); - + // Snap to the local y last to handle snapping around the x/z axis // (Snapping x/y/z all at once results in counter-intuitive results) rotation *= Quaternion.Euler(0, round(y), 0); - + return rotation; }