diff --git a/Assets/Scripts/Widgets/GrabWidget.cs b/Assets/Scripts/Widgets/GrabWidget.cs index e0d0b7dc0..64dcc9876 100644 --- a/Assets/Scripts/Widgets/GrabWidget.cs +++ b/Assets/Scripts/Widgets/GrabWidget.cs @@ -138,6 +138,7 @@ protected Transform[] HighlightMeshXfs protected List m_ValidSnapRotations_SS; protected int m_PrevValidSnapRotationIndex; protected Transform m_SnapGhost; + public Transform SnapGhost => m_SnapGhost; protected bool m_bWasSnapping = false; protected bool m_CustomShowHide = false; @@ -1265,6 +1266,10 @@ virtual protected TrTransform GetSnappedTransform(TrTransform xf_GS) // Calculate the nearest snap angle var rot_CS = xf_GS.rotation * App.Scene.Pose.rotation.TrueInverse(); Quaternion nearestSnapRotation_CS = SelectionManager.m_Instance.QuantizeAngle(rot_CS); + // TODO From stash + var outXf_CS = App.Scene.Pose.inverse * xf_GS; + // var rot_CS = outXf_CS.rotation; + // Quaternion nearestSnapRotation_CS = QuantizeAngle(rot_CS); // Decide whether to snap to the old or the new snap angle float snapAngle = SelectionManager.m_Instance.SnappingAngle; @@ -1279,9 +1284,10 @@ virtual protected TrTransform GetSnappedTransform(TrTransform xf_GS) } } + outXf_CS.rotation = m_PrevSnapRotation; + // Apply the resulting change in rotation to the original transform - var rotationDelta = m_PrevSnapRotation * Quaternion.Inverse(rot_CS); - outXf_GS.rotation = rotationDelta * outXf_GS.rotation; + outXf_GS = App.ActiveCanvas.Pose * outXf_CS; Quaternion qDelta = outXf_GS.rotation * Quaternion.Inverse(xf_GS.rotation); Vector3 grabSpot = InputManager.m_Instance.GetControllerPosition(m_InteractingController); @@ -1841,6 +1847,7 @@ virtual protected void OnUserBeginInteracting() if (m_AllowSnapping) { WidgetManager.m_Instance.SetHomeOwner(transform); + m_SnapGhost.gameObject.SetActive(true); } if (m_RecordMovements) diff --git a/Assets/Scripts/Widgets/SelectionWidget.cs b/Assets/Scripts/Widgets/SelectionWidget.cs index 610aa6dba..d2f23f541 100644 --- a/Assets/Scripts/Widgets/SelectionWidget.cs +++ b/Assets/Scripts/Widgets/SelectionWidget.cs @@ -35,6 +35,7 @@ public class SelectionWidget : GrabWidget private Dictionary m_LastIntersectionResult; private int m_IntersectionFrame; private Vector2 m_SizeRange; + private Transform m_SubSnapGhost; public override bool AllowDormancy { @@ -57,6 +58,7 @@ override protected void Awake() m_LastIntersectionResult[InputManager.ControllerName.Wand] = -1; m_CustomShowHide = true; ResetSizeRange(); + m_SnapGhost = m_SnapGhostPrefab; InitSnapGhost(m_SnapGhostPrefab, App.Scene.SelectionCanvas.transform); } @@ -311,10 +313,41 @@ override protected void OnUserBeginInteracting() m_Pin.WobblePin(m_InteractingController); } - if (m_SnapGhost && m_AllowSnapping) + if (m_AllowSnapping) { - m_SnapGhost.gameObject.SetActive(true); - m_SnapGhost.localScale = m_SelectionBounds_CS.Value.size; + // For consistency - in simple cases like a single stroke or widget selected, use that as the snap ghost directly + // For multiple selections use a bounding cuboid + // Otherwise it's confusing for the user that the behaviour of the Selection Tool is different to selecting widgets directly. + Transform ghostPrefab; + int numStrokes = SelectionManager.m_Instance.SelectedStrokes.Count(); + int numWidgets = SelectionManager.m_Instance.SelectedWidgets.Count(); + if (numStrokes == 0 && numWidgets == 1) + { + GrabWidget widget = SelectionManager.m_Instance.SelectedWidgets.ToList()[0]; + TrTransform widgetTr = widget.LocalTransform; + m_SubSnapGhost = Instantiate(widget.SnapGhost, m_SnapGhost); + m_SnapGhost.gameObject.SetActive(true); + m_SubSnapGhost.localPosition = widgetTr.translation; + m_SubSnapGhost.localRotation = widgetTr.rotation; + m_SubSnapGhost.localScale = widget.transform.localScale; + m_SubSnapGhost.gameObject.SetActive(true); + } + else if (numStrokes == 1 && numWidgets == 0) + { + Transform strokeTr = SelectionManager.m_Instance.SelectedStrokes.ToList()[0].StrokeTransform; + ghostPrefab = strokeTr; + if (m_SnapGhost == null) InitSnapGhost(ghostPrefab, App.Scene.SelectionCanvas.transform); + m_SnapGhost.transform.localPosition = strokeTr.localPosition; + m_SnapGhost.transform.localRotation = strokeTr.localRotation; + m_SnapGhost.transform.localScale = strokeTr.localScale; + } + else + { + ghostPrefab = m_SnapGhostPrefab; + m_SnapGhost.localScale = m_SelectionBounds_CS.Value.size; + InitSnapGhost(ghostPrefab, App.Scene.SelectionCanvas.transform); + m_SnapGhost.gameObject.SetActive(true); + } } }