/// <summary> /// Reset the manipulator state for a new set of selection transforms /// </summary> /// <param name="pivotSettings">The manipulator pivot settings</param> /// <param name="selectionTransforms">The array of selected transforms</param> /// <param name="activeTransform">The active selected transform</param> public void Reset(ManipulatorPivotSettings pivotSettings, Transform[] selectionTransforms, Transform activeTransform) { var pivotPosition = pivotSettings.GetPivotPosition(activeTransform, selectionTransforms); var pivotRotation = pivotSettings.pivotRotation == PivotRotation.Global || activeTransform == null ? Quaternion.identity : activeTransform.rotation; m_Manipulator.SetPose(pivotPosition, pivotRotation); m_TargetPosition = pivotPosition; m_TargetRotation = pivotRotation; m_EasedPosition = pivotPosition; m_EasedRotation = pivotRotation; m_StartRotation = m_TargetRotation; m_TargetScale = Vector3.one; m_PositionOffsetScale = Vector3.one; m_PositionOffsetRotation = Quaternion.identity; // Save the initial position, rotation, and scale relative to the manipulator m_PositionOffsets.Clear(); m_RotationOffsets.Clear(); m_ScaleOffsets.Clear(); m_Manipulator.SetTargetTransforms(selectionTransforms, activeTransform); foreach (var transform in selectionTransforms) { m_PositionOffsets.Add(transform, transform.position - pivotPosition); m_ScaleOffsets.Add(transform, transform.localScale); m_RotationOffsets.Add(transform, Quaternion.Inverse(pivotRotation) * transform.rotation); } }
/// <summary> /// Update the manipulator transform with a new target pose /// </summary> /// <param name="pivotSettings">The manipulator pivot settings</param> /// <param name="translateEase">How much the manipulator should move towards its target, where 0 is no movement and 1 is directly to the target </param> /// <param name="rotateEase">How much the manipulator should rotate towards its target, where 0 is no rotation and 1 is directly to the target</param> public void UpdateManipulatorTransform(ManipulatorPivotSettings pivotSettings, float translateEase = 1f, float rotateEase = 1f) { m_EasedPosition = Vector3.Lerp(m_EasedPosition, m_TargetPosition, translateEase); m_EasedRotation = Quaternion.Slerp(m_EasedRotation, m_TargetRotation, rotateEase); // Manipulator does not rotate when in global mode var newRotation = pivotSettings.pivotRotation == PivotRotation.Global ? Quaternion.identity : m_EasedRotation; m_Manipulator.SetPose(m_EasedPosition, newRotation); }
/// <summary> /// Updates the selection transforms based on the current manipulator's state /// </summary> /// <param name="pivotSettings">The current pivot settings to use.</param> /// <param name="targetTransforms">The transforms to affect</param> public void UpdateSelection(ManipulatorPivotSettings pivotSettings, Transform[] targetTransforms) { if (targetTransforms.Length <= 0) { return; } #if UNITY_EDITOR Undo.RecordObjects(targetTransforms, "Move"); #endif foreach (var transform in targetTransforms) { if (transform == null) { Debug.LogWarning($"Manipulator {m_Manipulator.gameObject} selection cannot update a null transform in the list."); continue; } if (!m_RotationOffsets.ContainsKey(transform) || !m_PositionOffsets.ContainsKey(transform) || !m_ScaleOffsets.ContainsKey(transform)) { Debug.LogWarning($"Manipulator {m_Manipulator.gameObject} cannot update transform {transform} because it was not listed when the state was last reset.", transform); continue; } var targetRotation = m_EasedRotation * m_RotationOffsets[transform]; if (transform.rotation != targetRotation) { transform.rotation = targetRotation; } if (pivotSettings.pivotGrouping == PivotGrouping.Group) // Rotate and scale the transform's offset from the group pivot { m_PositionOffsetRotation = m_EasedRotation * Quaternion.Inverse(m_StartRotation); m_PositionOffsetScale = m_TargetScale; } var targetPosition = m_EasedPosition + Vector3.Scale(m_PositionOffsetScale, m_PositionOffsetRotation * m_PositionOffsets[transform]); if (transform.position != targetPosition) { transform.position = targetPosition; } var targetScale = Vector3.Scale(m_TargetScale, m_ScaleOffsets[transform]); if (transform.localScale != targetScale) { transform.localScale = targetScale; } } }