ZeroByter

Unity Mathf Source Code

Jul 25th, 2018
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 16.99 KB | None | 0 0
  1. // Unity C# reference source
  2. // Copyright (c) Unity Technologies. For terms of use, see
  3. // https://unity3d.com/legal/licenses/Unity_Reference_Only_License
  4.  
  5. using System;
  6. using System.Threading;
  7. using uei = UnityEngine.Internal;
  8.  
  9. namespace UnityEngineInternal
  10. {
  11.     public partial struct MathfInternal
  12.     {
  13.         public static volatile float FloatMinNormal = 1.17549435E-38f;
  14.         public static volatile float FloatMinDenormal = Single.Epsilon;
  15.  
  16.         public static bool IsFlushToZeroEnabled = (FloatMinDenormal == 0);
  17.     }
  18. }
  19.  
  20. namespace UnityEngine
  21. {
  22.     // A collection of common math functions.
  23.     public partial struct Mathf
  24.     {
  25.         // Returns the sine of angle /f/ in radians.
  26.         public static float Sin(float f) { return (float)Math.Sin(f); }
  27.  
  28.         // Returns the cosine of angle /f/ in radians.
  29.         public static float Cos(float f) { return (float)Math.Cos(f); }
  30.  
  31.         // Returns the tangent of angle /f/ in radians.
  32.         public static float Tan(float f) { return (float)Math.Tan(f); }
  33.  
  34.         // Returns the arc-sine of /f/ - the angle in radians whose sine is /f/.
  35.         public static float Asin(float f) { return (float)Math.Asin(f); }
  36.  
  37.         // Returns the arc-cosine of /f/ - the angle in radians whose cosine is /f/.
  38.         public static float Acos(float f) { return (float)Math.Acos(f); }
  39.  
  40.         // Returns the arc-tangent of /f/ - the angle in radians whose tangent is /f/.
  41.         public static float Atan(float f) { return (float)Math.Atan(f); }
  42.  
  43.         // Returns the angle in radians whose ::ref::Tan is @@y/x@@.
  44.         public static float Atan2(float y, float x) { return (float)Math.Atan2(y, x); }
  45.  
  46.         // Returns square root of /f/.
  47.         public static float Sqrt(float f) { return (float)Math.Sqrt(f); }
  48.  
  49.         // Returns the absolute value of /f/.
  50.         public static float Abs(float f) { return (float)Math.Abs(f); }
  51.  
  52.         // Returns the absolute value of /value/.
  53.         public static int Abs(int value) { return Math.Abs(value); }
  54.  
  55.         /// *listonly*
  56.         public static float Min(float a, float b) { return a < b ? a : b; }
  57.         // Returns the smallest of two or more values.
  58.         public static float Min(params float[] values)
  59.         {
  60.             int len = values.Length;
  61.             if (len == 0)
  62.                 return 0;
  63.             float m = values[0];
  64.             for (int i = 1; i < len; i++)
  65.             {
  66.                 if (values[i] < m)
  67.                     m = values[i];
  68.             }
  69.             return m;
  70.         }
  71.  
  72.         /// *listonly*
  73.         public static int Min(int a, int b) { return a < b ? a : b; }
  74.         // Returns the smallest of two or more values.
  75.         public static int Min(params int[] values)
  76.         {
  77.             int len = values.Length;
  78.             if (len == 0)
  79.                 return 0;
  80.             int m = values[0];
  81.             for (int i = 1; i < len; i++)
  82.             {
  83.                 if (values[i] < m)
  84.                     m = values[i];
  85.             }
  86.             return m;
  87.         }
  88.  
  89.         /// *listonly*
  90.         public static float Max(float a, float b) { return a > b ? a : b; }
  91.         // Returns largest of two or more values.
  92.         public static float Max(params float[] values)
  93.         {
  94.             int len = values.Length;
  95.             if (len == 0)
  96.                 return 0;
  97.             float m = values[0];
  98.             for (int i = 1; i < len; i++)
  99.             {
  100.                 if (values[i] > m)
  101.                     m = values[i];
  102.             }
  103.             return m;
  104.         }
  105.  
  106.         /// *listonly*
  107.         public static int Max(int a, int b) { return a > b ? a : b; }
  108.         // Returns the largest of two or more values.
  109.         public static int Max(params int[] values)
  110.         {
  111.             int len = values.Length;
  112.             if (len == 0)
  113.                 return 0;
  114.             int m = values[0];
  115.             for (int i = 1; i < len; i++)
  116.             {
  117.                 if (values[i] > m)
  118.                     m = values[i];
  119.             }
  120.             return m;
  121.         }
  122.  
  123.         // Returns /f/ raised to power /p/.
  124.         public static float Pow(float f, float p) { return (float)Math.Pow(f, p); }
  125.  
  126.         // Returns e raised to the specified power.
  127.         public static float Exp(float power) { return (float)Math.Exp(power); }
  128.  
  129.         // Returns the logarithm of a specified number in a specified base.
  130.         public static float Log(float f, float p) { return (float)Math.Log(f, p); }
  131.  
  132.         // Returns the natural (base e) logarithm of a specified number.
  133.         public static float Log(float f) { return (float)Math.Log(f); }
  134.  
  135.         // Returns the base 10 logarithm of a specified number.
  136.         public static float Log10(float f) { return (float)Math.Log10(f); }
  137.  
  138.         // Returns the smallest integer greater to or equal to /f/.
  139.         public static float Ceil(float f) { return (float)Math.Ceiling(f); }
  140.  
  141.         // Returns the largest integer smaller to or equal to /f/.
  142.         public static float Floor(float f) { return (float)Math.Floor(f); }
  143.  
  144.         // Returns /f/ rounded to the nearest integer.
  145.         public static float Round(float f) { return (float)Math.Round(f); }
  146.  
  147.         // Returns the smallest integer greater to or equal to /f/.
  148.         public static int CeilToInt(float f) { return (int)Math.Ceiling(f); }
  149.  
  150.         // Returns the largest integer smaller to or equal to /f/.
  151.         public static int FloorToInt(float f) { return (int)Math.Floor(f); }
  152.  
  153.         // Returns /f/ rounded to the nearest integer.
  154.         public static int RoundToInt(float f) { return (int)Math.Round(f); }
  155.  
  156.         // Returns the sign of /f/.
  157.         public static float Sign(float f) { return f >= 0F ? 1F : -1F; }
  158.  
  159.         // The infamous ''3.14159265358979...'' value (RO).
  160.         public const float PI = (float)Math.PI;
  161.  
  162.         // A representation of positive infinity (RO).
  163.         public const float Infinity = Single.PositiveInfinity;
  164.  
  165.         // A representation of negative infinity (RO).
  166.         public const float NegativeInfinity = Single.NegativeInfinity;
  167.  
  168.         // Degrees-to-radians conversion constant (RO).
  169.         public const float Deg2Rad = PI * 2F / 360F;
  170.  
  171.         // Radians-to-degrees conversion constant (RO).
  172.         public const float Rad2Deg = 1F / Deg2Rad;
  173.  
  174.         // A tiny floating point value (RO).
  175.         public static readonly float Epsilon =
  176.             UnityEngineInternal.MathfInternal.IsFlushToZeroEnabled ? UnityEngineInternal.MathfInternal.FloatMinNormal
  177.             : UnityEngineInternal.MathfInternal.FloatMinDenormal;
  178.  
  179.         // Clamps a value between a minimum float and maximum float value.
  180.         public static float Clamp(float value, float min, float max)
  181.         {
  182.             if (value < min)
  183.                 value = min;
  184.             else if (value > max)
  185.                 value = max;
  186.             return value;
  187.         }
  188.  
  189.         // Clamps value between min and max and returns value.
  190.         // Set the position of the transform to be that of the time
  191.         // but never less than 1 or more than 3
  192.         //
  193.         public static int Clamp(int value, int min, int max)
  194.         {
  195.             if (value < min)
  196.                 value = min;
  197.             else if (value > max)
  198.                 value = max;
  199.             return value;
  200.         }
  201.  
  202.         // Clamps value between 0 and 1 and returns value
  203.         public static float Clamp01(float value)
  204.         {
  205.             if (value < 0F)
  206.                 return 0F;
  207.             else if (value > 1F)
  208.                 return 1F;
  209.             else
  210.                 return value;
  211.         }
  212.  
  213.         // Interpolates between /a/ and /b/ by /t/. /t/ is clamped between 0 and 1.
  214.         public static float Lerp(float a, float b, float t)
  215.         {
  216.             return a + (b - a) * Clamp01(t);
  217.         }
  218.  
  219.         // Interpolates between /a/ and /b/ by /t/ without clamping the interpolant.
  220.         public static float LerpUnclamped(float a, float b, float t)
  221.         {
  222.             return a + (b - a) * t;
  223.         }
  224.  
  225.         // Same as ::ref::Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.
  226.         public static float LerpAngle(float a, float b, float t)
  227.         {
  228.             float delta = Repeat((b - a), 360);
  229.             if (delta > 180)
  230.                 delta -= 360;
  231.             return a + delta * Clamp01(t);
  232.         }
  233.  
  234.         // Moves a value /current/ towards /target/.
  235.         static public float MoveTowards(float current, float target, float maxDelta)
  236.         {
  237.             if (Mathf.Abs(target - current) <= maxDelta)
  238.                 return target;
  239.             return current + Mathf.Sign(target - current) * maxDelta;
  240.         }
  241.  
  242.         // Same as ::ref::MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.
  243.         static public float MoveTowardsAngle(float current, float target, float maxDelta)
  244.         {
  245.             float deltaAngle = DeltaAngle(current, target);
  246.             if (-maxDelta < deltaAngle && deltaAngle < maxDelta)
  247.                 return target;
  248.             target = current + deltaAngle;
  249.             return MoveTowards(current, target, maxDelta);
  250.         }
  251.  
  252.         // Interpolates between /min/ and /max/ with smoothing at the limits.
  253.         public static float SmoothStep(float from, float to, float t)
  254.         {
  255.             t = Mathf.Clamp01(t);
  256.             t = -2.0F * t * t * t + 3.0F * t * t;
  257.             return to * t + from * (1F - t);
  258.         }
  259.  
  260.         //*undocumented
  261.         public static float Gamma(float value, float absmax, float gamma)
  262.         {
  263.             bool negative = false;
  264.             if (value < 0F)
  265.                 negative = true;
  266.             float absval = Abs(value);
  267.             if (absval > absmax)
  268.                 return negative ? -absval : absval;
  269.  
  270.             float result = Pow(absval / absmax, gamma) * absmax;
  271.             return negative ? -result : result;
  272.         }
  273.  
  274.         // Compares two floating point values if they are similar.
  275.         public static bool Approximately(float a, float b)
  276.         {
  277.             // If a or b is zero, compare that the other is less or equal to epsilon.
  278.             // If neither a or b are 0, then find an epsilon that is good for
  279.             // comparing numbers at the maximum magnitude of a and b.
  280.             // Floating points have about 7 significant digits, so
  281.             // 1.000001f can be represented while 1.0000001f is rounded to zero,
  282.             // thus we could use an epsilon of 0.000001f for comparing values close to 1.
  283.             // We multiply this epsilon by the biggest magnitude of a and b.
  284.             return Abs(b - a) < Max(0.000001f * Max(Abs(a), Abs(b)), Epsilon * 8);
  285.         }
  286.  
  287.         [uei.ExcludeFromDocs]
  288.         public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed)
  289.         {
  290.             float deltaTime = Time.deltaTime;
  291.             return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
  292.         }
  293.  
  294.         [uei.ExcludeFromDocs]
  295.         public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime)
  296.         {
  297.             float deltaTime = Time.deltaTime;
  298.             float maxSpeed = Mathf.Infinity;
  299.             return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
  300.         }
  301.  
  302.         // Gradually changes a value towards a desired goal over time.
  303.         public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, [uei.DefaultValue("Mathf.Infinity")]  float maxSpeed, [uei.DefaultValue("Time.deltaTime")]  float deltaTime)
  304.         {
  305.             // Based on Game Programming Gems 4 Chapter 1.10
  306.             smoothTime = Mathf.Max(0.0001F, smoothTime);
  307.             float omega = 2F / smoothTime;
  308.  
  309.             float x = omega * deltaTime;
  310.             float exp = 1F / (1F + x + 0.48F * x * x + 0.235F * x * x * x);
  311.             float change = current - target;
  312.             float originalTo = target;
  313.  
  314.             // Clamp maximum speed
  315.             float maxChange = maxSpeed * smoothTime;
  316.             change = Mathf.Clamp(change, -maxChange, maxChange);
  317.             target = current - change;
  318.  
  319.             float temp = (currentVelocity + omega * change) * deltaTime;
  320.             currentVelocity = (currentVelocity - omega * temp) * exp;
  321.             float output = target + (change + temp) * exp;
  322.  
  323.             // Prevent overshooting
  324.             if (originalTo - current > 0.0F == output > originalTo)
  325.             {
  326.                 output = originalTo;
  327.                 currentVelocity = (output - originalTo) / deltaTime;
  328.             }
  329.  
  330.             return output;
  331.         }
  332.  
  333.         [uei.ExcludeFromDocs]
  334.         public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed)
  335.         {
  336.             float deltaTime = Time.deltaTime;
  337.             return SmoothDampAngle(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
  338.         }
  339.  
  340.         [uei.ExcludeFromDocs]
  341.         public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime)
  342.         {
  343.             float deltaTime = Time.deltaTime;
  344.             float maxSpeed = Mathf.Infinity;
  345.             return SmoothDampAngle(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
  346.         }
  347.  
  348.         // Gradually changes an angle given in degrees towards a desired goal angle over time.
  349.         public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, [uei.DefaultValue("Mathf.Infinity")]  float maxSpeed, [uei.DefaultValue("Time.deltaTime")]  float deltaTime)
  350.         {
  351.             target = current + DeltaAngle(current, target);
  352.             return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
  353.         }
  354.  
  355.         // Loops the value t, so that it is never larger than length and never smaller than 0.
  356.         public static float Repeat(float t, float length)
  357.         {
  358.             return Clamp(t - Mathf.Floor(t / length) * length, 0.0f, length);
  359.         }
  360.  
  361.         // PingPongs the value t, so that it is never larger than length and never smaller than 0.
  362.         public static float PingPong(float t, float length)
  363.         {
  364.             t = Repeat(t, length * 2F);
  365.             return length - Mathf.Abs(t - length);
  366.         }
  367.  
  368.         // Calculates the ::ref::Lerp parameter between of two values.
  369.         public static float InverseLerp(float a, float b, float value)
  370.         {
  371.             if (a != b)
  372.                 return Clamp01((value - a) / (b - a));
  373.             else
  374.                 return 0.0f;
  375.         }
  376.  
  377.         // Calculates the shortest difference between two given angles.
  378.         public static float DeltaAngle(float current, float target)
  379.         {
  380.             float delta = Mathf.Repeat((target - current), 360.0F);
  381.             if (delta > 180.0F)
  382.                 delta -= 360.0F;
  383.             return delta;
  384.         }
  385.  
  386.         // Infinite Line Intersection (line1 is p1-p2 and line2 is p3-p4)
  387.         internal static bool LineIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
  388.         {
  389.             float bx = p2.x - p1.x;
  390.             float by = p2.y - p1.y;
  391.             float dx = p4.x - p3.x;
  392.             float dy = p4.y - p3.y;
  393.             float bDotDPerp = bx * dy - by * dx;
  394.             if (bDotDPerp == 0)
  395.             {
  396.                 return false;
  397.             }
  398.             float cx = p3.x - p1.x;
  399.             float cy = p3.y - p1.y;
  400.             float t = (cx * dy - cy * dx) / bDotDPerp;
  401.  
  402.             result = new Vector2(p1.x + t * bx, p1.y + t * by);
  403.             return true;
  404.         }
  405.  
  406.         // Line Segment Intersection (line1 is p1-p2 and line2 is p3-p4)
  407.         internal static bool LineSegmentIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
  408.         {
  409.             float bx = p2.x - p1.x;
  410.             float by = p2.y - p1.y;
  411.             float dx = p4.x - p3.x;
  412.             float dy = p4.y - p3.y;
  413.             float bDotDPerp = bx * dy - by * dx;
  414.             if (bDotDPerp == 0)
  415.             {
  416.                 return false;
  417.             }
  418.             float cx = p3.x - p1.x;
  419.             float cy = p3.y - p1.y;
  420.             float t = (cx * dy - cy * dx) / bDotDPerp;
  421.             if (t < 0 || t > 1)
  422.             {
  423.                 return false;
  424.             }
  425.             float u = (cx * by - cy * bx) / bDotDPerp;
  426.             if (u < 0 || u > 1)
  427.             {
  428.                 return false;
  429.             }
  430.             result = new Vector2(p1.x + t * bx, p1.y + t * by);
  431.             return true;
  432.         }
  433.  
  434.         static internal long RandomToLong(System.Random r)
  435.         {
  436.             var buffer = new byte[8];
  437.             r.NextBytes(buffer);
  438.             return (long)(System.BitConverter.ToUInt64(buffer, 0) & System.Int64.MaxValue);
  439.         }
  440.     }
  441. }
Advertisement
Add Comment
Please, Sign In to add comment