mixedreality/com.microsoft.mixedreality..../SDK/Features/Input/Handlers/Constraints/RotationAxisConstraint.cs

78 lines
2.5 KiB
C#

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.MixedReality.Toolkit.Utilities;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.UI
{
/// <summary>
/// Component for limiting the rotation axes for ObjectManipulator
/// or BoundsControl
/// </summary>
public class RotationAxisConstraint : TransformConstraint
{
#region Properties
[SerializeField]
[EnumFlags]
[Tooltip("Constrain rotation about an axis")]
private AxisFlags constraintOnRotation = 0;
/// <summary>
/// Constrain rotation about an axis
/// </summary>
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;
/// <summary>
/// Gets or sets whether the constraints should be applied in local space of the object being manipulated or world space.
/// </summary>
public bool UseLocalSpaceForConstraint
{
get => useLocalSpaceForConstraint;
set => useLocalSpaceForConstraint = value;
}
public override TransformFlags ConstraintType => TransformFlags.Rotate;
#endregion Properties
#region Public Methods
/// <summary>
/// Removes rotation about given axis if its flag is found
/// in ConstraintOnRotation
/// </summary>
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
}
}