// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.Collections; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.Utilities { [Serializable] public struct MixedRealityTransform : IEqualityComparer { /// /// Constructor. /// public MixedRealityTransform(Transform transform) { this.pose = new MixedRealityPose(transform.position, transform.rotation); this.scale = transform.localScale; } /// /// Constructor. /// public MixedRealityTransform(Vector3 position, Quaternion rotation, Vector3 scale) { this.pose = new MixedRealityPose(position, rotation); this.scale = scale; } /// /// Create a transform with only given position /// public static MixedRealityTransform NewTranslate(Vector3 position) { return new MixedRealityTransform(position, Quaternion.identity, Vector3.one); } /// /// Create a transform with only given rotation /// public static MixedRealityTransform NewRotate(Quaternion rotation) { return new MixedRealityTransform(Vector3.zero, rotation, Vector3.one); } /// /// Create a transform with only given scale /// public static MixedRealityTransform NewScale(Vector3 scale) { return new MixedRealityTransform(Vector3.zero, Quaternion.identity, scale); } /// /// The default value for a Six DoF Transform. /// public static MixedRealityTransform Identity { get; } = new MixedRealityTransform(Vector3.zero, Quaternion.identity, Vector3.one); [SerializeField] [Tooltip("The pose (position and rotation) of the transform")] private MixedRealityPose pose; /// /// The position of the transform. /// public Vector3 Position { get { return pose.Position; } set { pose.Position = value; } } /// /// The rotation of the transform. /// public Quaternion Rotation { get { return pose.Rotation; } set { pose.Rotation = value; } } [SerializeField] [Tooltip("The scale of the transform.")] private Vector3 scale; /// /// The scale of the transform. /// public Vector3 Scale { get { return scale; } set { scale = value; } } public static MixedRealityTransform operator +(MixedRealityTransform left, MixedRealityTransform right) { return new MixedRealityTransform(left.Position + right.Position, left.Rotation * right.Rotation, Vector3.Scale(left.Scale, right.Scale)); } public static bool operator ==(MixedRealityTransform left, MixedRealityTransform right) { return left.Equals(right); } public static bool operator !=(MixedRealityTransform left, MixedRealityTransform right) { return !left.Equals(right); } public override string ToString() { return $"{pose.Position} | {pose.Rotation} | {scale}"; } /// /// The Z axis of the pose in world space. /// public Vector3 Forward => (pose.Rotation * Vector3.Scale(scale, Vector3.forward)).normalized; /// /// The Y axis of the pose in world space. /// public Vector3 Up => (pose.Rotation * Vector3.Scale(scale, Vector3.up)).normalized; /// /// The X axis of the pose in world space. /// public Vector3 Right => (pose.Rotation * Vector3.Scale(scale, Vector3.right)).normalized; #region IEqualityComparer Implementation /// bool IEqualityComparer.Equals(object left, object right) { if (ReferenceEquals(null, left) || ReferenceEquals(null, right)) { return false; } if (!(left is MixedRealityTransform) || !(right is MixedRealityTransform)) { return false; } return ((MixedRealityTransform)left).Equals((MixedRealityTransform)right); } public bool Equals(MixedRealityTransform other) { return Position == other.Position && Rotation.Equals(other.Rotation); } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } return obj is MixedRealityTransform transform && Equals(transform); } /// int IEqualityComparer.GetHashCode(object obj) { return obj is MixedRealityTransform transform ? transform.GetHashCode() : 0; } public override int GetHashCode() { return base.GetHashCode(); } #endregion IEqualityComparer Implementation } }