< Summary

Class:GDX.Vector3Extensions
Assembly:GDX
File(s):D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/Vector3Extensions.cs
Covered lines:68
Uncovered lines:0
Coverable lines:68
Total lines:197
Line coverage:100% (68 of 68)
Covered branches:0
Total branches:0
Covered methods:7
Total methods:7
Method coverage:100% (7 of 7)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Approximately(...)0%330100%
DistanceSqr(...)0%110100%
HorizontalDistance(...)0%110100%
DistanceToRay(...)0%110100%
Midpoint(...)0%110100%
NearestIndex(...)0%660100%
TryParseVector3(...)0%660100%

File(s)

D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/Vector3Extensions.cs

#LineLine coverage
 1// Copyright (c) 2020-2022 dotBunny Inc.
 2// dotBunny licenses this file to you under the BSL-1.0 license.
 3// See the LICENSE file in the project root for more information.
 4
 5#if !UNITY_DOTSRUNTIME
 6
 7using System.Runtime.CompilerServices;
 8using UnityEngine;
 9using Unity.Mathematics;
 10
 11namespace GDX
 12{
 13    /// <summary>
 14    ///     <see cref="Vector3" /> Based Extension Methods
 15    /// </summary>
 16    /// <exception cref="UnsupportedRuntimeException">Not supported on DOTS Runtime.</exception>
 17    [VisualScriptingCompatible(2)]
 18    public static class Vector3Extensions
 19    {
 20        /// <summary>
 21        ///     Is one <see cref="Vector3" /> approximately similar to another <see cref="Vector3" />?
 22        /// </summary>
 23        /// <remarks>Includes optimized Unity.Mathematics approach.</remarks>
 24        /// <param name="targetVector3">Point A</param>
 25        /// <param name="otherVector3">Point B</param>
 26        /// <returns>Are the two <see cref="Vector3" /> approximately the same?</returns>
 27        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 28        public static bool Approximately(this Vector3 targetVector3, Vector3 otherVector3)
 829        {
 830            float moddedEpsilon = Mathf.Epsilon * 8f;
 31            const float k_BaseMultiplier = 1E-06f;
 832            return math.abs(otherVector3.x - targetVector3.x) < math.max(
 33                       k_BaseMultiplier * math.max(math.abs(targetVector3.x), math.abs(otherVector3.x)),
 34                       moddedEpsilon) &&
 35                   math.abs(otherVector3.y - targetVector3.y) < math.max(
 36                       k_BaseMultiplier * math.max(math.abs(targetVector3.y), math.abs(otherVector3.y)),
 37                       moddedEpsilon) &&
 38                   math.abs(otherVector3.z - targetVector3.z) < math.max(
 39                       k_BaseMultiplier * math.max(math.abs(targetVector3.z), math.abs(otherVector3.z)),
 40                       moddedEpsilon);
 41
 842        }
 43
 44        /// <summary>
 45        ///     Calculate the squared distance between two <see cref="Vector3"/>.
 46        /// </summary>
 47        /// <remarks>
 48        ///     <para>Based on https://en.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance.</para>
 49        /// </remarks>
 50        /// <param name="targetVector3">Point A</param>
 51        /// <param name="otherVector3">Point B</param>
 52        /// <returns>The squared distance.</returns>
 53        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 54        public static float DistanceSqr(this Vector3 targetVector3, Vector3 otherVector3)
 155        {
 156            float x = targetVector3.x - otherVector3.x;
 157            float y = targetVector3.y - otherVector3.y;
 158            float z = targetVector3.z - otherVector3.z;
 159            return x * x + y * y + z * z;
 160        }
 61
 62        /// <summary>
 63        ///     Get the horizontal distance between two <see cref="Vector3"/> points.
 64        /// </summary>
 65        /// <remarks>Ignores the Y-axis completely.</remarks>
 66        /// <param name="targetVector3">Point A</param>
 67        /// <param name="otherVector3">Point B</param>
 68        /// <returns>The horizontal distance.</returns>
 69        public static float HorizontalDistance(this Vector3 targetVector3, Vector3 otherVector3)
 170        {
 171            float num1 = targetVector3.x - otherVector3.x;
 172            float num2 = targetVector3.z - otherVector3.z;
 173            return (float)math.sqrt(num1 * (double)num1 + num2 * (double)num2);
 174        }
 75
 76        /// <summary>
 77        /// Calculate the distance from a <see cref="Vector3"/> to a <see cref="Ray"/>.
 78        /// </summary>
 79        /// <param name="targetVector3">The position.</param>
 80        /// <param name="targetRay">The line.</param>
 81        /// <returns>The distance.</returns>
 82        public static float DistanceToRay(this Vector3 targetVector3, Ray targetRay)
 183        {
 184            return Vector3.Cross(targetRay.direction, targetVector3 - targetRay.origin).magnitude;
 185        }
 86
 87        /// <summary>
 88        ///     Get the midpoint between two <see cref="Vector3" />s.
 89        /// </summary>
 90        /// <param name="targetVector3">Point A</param>
 91        /// <param name="otherVector3">Point B</param>
 92        /// <returns>The midpoint between <paramref name="targetVector3" /> and <paramref name="otherVector3" />.</retur
 93        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 94        public static Vector3 Midpoint(this Vector3 targetVector3, Vector3 otherVector3)
 195        {
 196            return new Vector3(
 97                targetVector3.x + (otherVector3.x - targetVector3.x) * 0.5f,
 98                targetVector3.y + (otherVector3.y - targetVector3.y) * 0.5f,
 99                targetVector3.z + (otherVector3.z - targetVector3.z) * 0.5f
 100            );
 1101        }
 102
 103        /// <summary>
 104        ///     Find the index of the <see cref="Vector3" /> in <paramref name="otherVector3" /> that is nearest to the
 105        ///     <paramref name="targetVector3" />.
 106        /// </summary>
 107        /// <param name="targetVector3">The <see cref="Vector3" /> to use as the point of reference.</param>
 108        /// <param name="otherVector3">An array of <see cref="Vector3" /> positions to evaluate for which one is nearest
 109        /// <returns>
 110        ///     The index of the nearest <paramref name="otherVector3" /> element to <paramref name="targetVector3" />.
 111        ///     Returning -1 if the the <paramref name="otherVector3" /> has no elements or is null.
 112        /// </returns>
 113        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 114        public static int NearestIndex(this Vector3 targetVector3, Vector3[] otherVector3)
 2115        {
 116            // We found nothing to compare against
 2117            if (otherVector3 == null || otherVector3.Length == 0)
 1118            {
 1119                return -1;
 120            }
 121
 1122            float closestSquareMagnitude = float.PositiveInfinity;
 1123            int closestIndex = -1;
 1124            int otherVector3Length = otherVector3.Length;
 125
 126            // Loop through the provided points and figure out what is closest (close enough).
 12127            for (int i = 0; i < otherVector3Length; i++)
 5128            {
 5129                float squareDistance = (otherVector3[i] - targetVector3).sqrMagnitude;
 5130                if (float.IsNaN(squareDistance) || !(squareDistance < closestSquareMagnitude))
 3131                {
 3132                    continue;
 133                }
 134
 2135                closestSquareMagnitude = squareDistance;
 2136                closestIndex = i;
 2137            }
 138
 1139            return closestIndex;
 2140        }
 141
 142        /// <summary>
 143        ///     Attempt to parse a <see cref="string" /> into a <see cref="Vector3" />.
 144        /// </summary>
 145        /// <remarks>This isn't great for runtime performance, it should be used predominantly when reconstructing data.
 146        /// <param name="targetString">The <see cref="string" /> to convert into a <see cref="Vector3" /> if possible.</
 147        /// <param name="outputVector3">The outputted <see cref="Vector3" />.</param>
 148        /// <returns>true/false if the conversion was successful.</returns>
 149        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 150        public static bool TryParseVector3(this string targetString, out Vector3 outputVector3)
 7151        {
 152            // Find split points
 7153            int firstSplit = targetString.IndexOf(',', 0);
 7154            if (firstSplit == -1)
 1155            {
 1156                outputVector3 = Vector3.zero;
 1157                return false;
 158            }
 159
 6160            int secondSplit = targetString.IndexOf(',', firstSplit + 1);
 6161            if (secondSplit == -1)
 1162            {
 1163                outputVector3 = Vector3.zero;
 1164                return false;
 165            }
 166
 167            // Get source parts
 5168            string sourceX = targetString.Substring(0, firstSplit);
 5169            string sourceY = targetString.Substring(firstSplit + 1, secondSplit - (firstSplit + 1));
 5170            string sourceZ = targetString.Substring(secondSplit + 1);
 171
 172            // Parse components
 5173            if (!float.TryParse(sourceX, out float parsedX))
 1174            {
 1175                outputVector3 = Vector3.zero;
 1176                return false;
 177            }
 178
 4179            if (!float.TryParse(sourceY, out float parsedY))
 1180            {
 1181                outputVector3 = Vector3.zero;
 1182                return false;
 183            }
 184
 3185            if (!float.TryParse(sourceZ, out float parsedZ))
 1186            {
 1187                outputVector3 = Vector3.zero;
 1188                return false;
 189            }
 190
 191            // Everything looks good, assign the values
 2192            outputVector3 = new Vector3(parsedX, parsedY, parsedZ);
 2193            return true;
 7194        }
 195    }
 196}
 197#endif