/****************************************************************************** * 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. * ******************************************************************************/ using UnityEngine; namespace Leap.Unity.Geometry { /// /// A struct very similar to Vector3, but that prevents itself from ever /// being converted to Vector3.zero. If the Direction3's components would ever /// be un-normalizable (normalize to Vector3.zero), it will instead return /// Vector3.forward. (Direction3 implicitly converts to a normalized Vector3.) /// /// Because of this sanitizing behavior, "default(Direction3)" is stored as /// all zero components, but is converted to Vector3.forward upon implicit /// conversion to Vector3. /// [System.Serializable] public struct Direction3 { [SerializeField] private float x; [SerializeField] private float y; [SerializeField] private float z; public Direction3(Vector3 v) { x = v.x; y = v.y; z = v.z; } public Direction3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } /// /// Gets whether this Direction3 will normalize without issue (has nonzero /// magnitude), otherwise the conversion to Vector3 will sanitize to /// Vector3.forward. /// public bool isValid { get { return new Vector3(x, y, z) != Vector3.zero; } } /// Explicitly converts this Direction3 to a Vector3. public Vector3 Vec() { return this; } public static implicit operator Vector3(Direction3 dir) { var normalized = new Vector3(dir.x, dir.y, dir.z).normalized; if (normalized == Vector3.zero) { return Vector3.forward; } return normalized; } public static implicit operator Direction3(Vector3 vec) { return new Direction3(vec); } /// /// Returns whether two Direction3s point in the same direction without /// normalizing either of the underlying vectors. /// /// This method is intended to cheaply match bit-idential Direction3s; it's /// subject to precision error if the magnitudes of the underlying vectors /// are very different. /// public static bool PointsInSameDirection(Direction3 A, Direction3 B) { Vector3 aV = new Vector3(A.x, A.y, A.z); Vector3 bV = new Vector3(B.x, B.y, B.z); return Vector3.Cross(aV, bV).sqrMagnitude == 0f; } } }