/****************************************************************************** * Copyright (C) Ultraleap, Inc. 2011-2021. * * * * Use subject to the terms of the Apache License 2.0 available at * * http://www.apache.org/licenses/LICENSE-2.0, or another agreement * * between Ultraleap and you, your company or other organization. * ******************************************************************************/ namespace Leap { using System; /// /// The LeapQuaternion struct represents a rotation in three-dimensional space. /// @since 3.1.2 /// [System.Obsolete("This code will be moved to a legacy package in the next major version of the plugin. Use Unity's Quaternion instead. If you believe that it needs to be kept in tracking, please open a discussion on the GitHub forum (https://github.com/ultraleap/UnityPlugin/discussions)")] [Serializable] public struct LeapQuaternion : IEquatable { /// /// Creates a new LeapQuaternion with the specified component values. /// @since 3.1.2 /// public LeapQuaternion(float x, float y, float z, float w) : this() { this.x = x; this.y = y; this.z = z; this.w = w; } /// /// Copies the specified LeapQuaternion. /// @since 3.1.2 /// public LeapQuaternion(LeapQuaternion quaternion) : this() { x = quaternion.x; y = quaternion.y; z = quaternion.z; w = quaternion.w; } /// /// Copies the specified LEAP_QUATERNION. /// @since 3.1.2 /// public LeapQuaternion(LeapInternal.LEAP_QUATERNION quaternion) : this() { x = quaternion.x; y = quaternion.y; z = quaternion.z; w = quaternion.w; } /// /// Returns a string containing this quaternion in a human readable format: (x, y, z). /// @since 3.1.2 /// public override string ToString() { return "(" + x + ", " + y + ", " + z + ", " + w + ")"; } /// /// Compare LeapQuaternion equality component-wise. /// @since 3.1.2 /// public bool Equals(LeapQuaternion v) { return x.NearlyEquals(v.x) && y.NearlyEquals(v.y) && z.NearlyEquals(v.z) && w.NearlyEquals(v.w); } public override bool Equals(Object obj) { return obj is LeapQuaternion && Equals((LeapQuaternion)obj); } /// /// Returns true if all of the quaternion's components are finite. If any /// component is NaN or infinite, then this returns false. /// @since 3.1.2 /// public bool IsValid() { return !(float.IsNaN(x) || float.IsInfinity(x) || float.IsNaN(y) || float.IsInfinity(y) || float.IsNaN(z) || float.IsInfinity(z) || float.IsNaN(w) || float.IsInfinity(w)); } public float x; public float y; public float z; public float w; /// /// The magnitude, or length, of this quaternion. /// @since 3.1.2 /// public float Magnitude { get { return (float)Math.Sqrt(x * x + y * y + z * z + w * w); } } /// /// The square of the magnitude, or length, of this quaternion. /// @since 3.1.2 /// public float MagnitudeSquared { get { return x * x + y * y + z * z + w * w; } } /// /// A normalized copy of this quaternion. /// @since 3.1.2 /// public LeapQuaternion Normalized { get { float denom = MagnitudeSquared; if (denom <= CSharpExtensions.Constants.EPSILON) { return Identity; } denom = 1.0f / (float)Math.Sqrt(denom); return new LeapQuaternion(x * denom, y * denom, z * denom, w * denom); } } /// /// Concatenates the rotation described by this quaternion with the one provided /// and returns the result. /// @since 3.1.2 /// public LeapQuaternion Multiply(LeapQuaternion rhs) { return new LeapQuaternion( w * rhs.x + x * rhs.w + y * rhs.z - z * rhs.y, w * rhs.y + y * rhs.w + z * rhs.x - x * rhs.z, w * rhs.z + z * rhs.w + x * rhs.y - y * rhs.x, w * rhs.w - x * rhs.x - y * rhs.y - z * rhs.z); } /// /// The identity quaternion. /// @since 3.1.2 /// public static readonly LeapQuaternion Identity = new LeapQuaternion(0, 0, 0, 1); public override int GetHashCode() { unchecked // Overflow is fine, just wrap { int hash = 17; hash = hash * 23 + x.GetHashCode(); hash = hash * 23 + y.GetHashCode(); hash = hash * 23 + z.GetHashCode(); hash = hash * 23 + w.GetHashCode(); return hash; } } } }