// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using Microsoft.MixedReality.Toolkit.Utilities; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.UI { /// /// Component for limiting the rotation axes for ObjectManipulator /// or BoundsControl /// public class RotationAxisConstraint : TransformConstraint { #region Properties [SerializeField] [EnumFlags] [Tooltip("Constrain rotation about an axis")] private AxisFlags constraintOnRotation = 0; /// /// Constrain rotation about an axis /// public AxisFlags ConstraintOnRotation { get => constraintOnRotation; set => constraintOnRotation = value; } [SerializeField] [Tooltip("Check if object rotation should be in local space of object being manipulated instead of world space.")] private bool useLocalSpaceForConstraint = false; /// /// Gets or sets whether the constraints should be applied in local space of the object being manipulated or world space. /// public bool UseLocalSpaceForConstraint { get => useLocalSpaceForConstraint; set => useLocalSpaceForConstraint = value; } public override TransformFlags ConstraintType => TransformFlags.Rotate; #endregion Properties #region Public Methods /// /// Removes rotation about given axis if its flag is found /// in ConstraintOnRotation /// public override void ApplyConstraint(ref MixedRealityTransform transform) { Quaternion rotation = transform.Rotation * Quaternion.Inverse(worldPoseOnManipulationStart.Rotation); Vector3 eulers = rotation.eulerAngles; if (constraintOnRotation.IsMaskSet(AxisFlags.XAxis)) { eulers.x = 0; } if (constraintOnRotation.IsMaskSet(AxisFlags.YAxis)) { eulers.y = 0; } if (constraintOnRotation.IsMaskSet(AxisFlags.ZAxis)) { eulers.z = 0; } transform.Rotation = useLocalSpaceForConstraint ? worldPoseOnManipulationStart.Rotation * Quaternion.Euler(eulers) : Quaternion.Euler(eulers) * worldPoseOnManipulationStart.Rotation; } #endregion Public Methods } }