// 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 translation axes for ObjectManipulator
/// or BoundsControl
///
public class MoveAxisConstraint : TransformConstraint
{
#region Properties
[SerializeField]
[EnumFlags]
[Tooltip("Constrain movement along an axis")]
private AxisFlags constraintOnMovement = 0;
///
/// Constrain movement along an axis
///
public AxisFlags ConstraintOnMovement
{
get => constraintOnMovement;
set => constraintOnMovement = value;
}
[SerializeField]
[Tooltip("Relative to rotation at manipulation start or world")]
private bool useLocalSpaceForConstraint = false;
///
/// Relative to rotation at manipulation start or world
///
public bool UseLocalSpaceForConstraint
{
get => useLocalSpaceForConstraint;
set => useLocalSpaceForConstraint = value;
}
public override TransformFlags ConstraintType => TransformFlags.Move;
#endregion Properties
#region Public Methods
///
/// Removes movement along a given axis if its flag is found
/// in ConstraintOnMovement
///
public override void ApplyConstraint(ref MixedRealityTransform transform)
{
Quaternion inverseRotation = Quaternion.Inverse(worldPoseOnManipulationStart.Rotation);
Vector3 position = transform.Position;
if (constraintOnMovement.IsMaskSet(AxisFlags.XAxis))
{
if (useLocalSpaceForConstraint)
{
position = inverseRotation * position;
position.x = (inverseRotation * worldPoseOnManipulationStart.Position).x;
position = worldPoseOnManipulationStart.Rotation * position;
}
else
{
position.x = worldPoseOnManipulationStart.Position.x;
}
}
if (constraintOnMovement.IsMaskSet(AxisFlags.YAxis))
{
if (useLocalSpaceForConstraint)
{
position = inverseRotation * position;
position.y = (inverseRotation * worldPoseOnManipulationStart.Position).y;
position = worldPoseOnManipulationStart.Rotation * position;
}
else
{
position.y = worldPoseOnManipulationStart.Position.y;
}
}
if (constraintOnMovement.IsMaskSet(AxisFlags.ZAxis))
{
if (useLocalSpaceForConstraint)
{
position = inverseRotation * position;
position.z = (inverseRotation * worldPoseOnManipulationStart.Position).z;
position = worldPoseOnManipulationStart.Rotation * position;
}
else
{
position.z = worldPoseOnManipulationStart.Position.z;
}
}
transform.Position = position;
}
#endregion Public Methods
}
}