Advertisement
Krythic

VoidwalkerMath

Jul 31st, 2020
1,289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 44.66 KB | None | 0 0
  1. using SharpDX;
  2. using System;
  3. using VoidwalkerEngine.Framework.Logic;
  4.  
  5. namespace VoidwalkerEngine.Framework.Maths
  6. {
  7.     public static class VoidwalkerMath
  8.     {
  9.         /// <summary>
  10.         /// Represents the mathematical constant e.
  11.         /// </summary>
  12.         public const float E = 2.718282f;
  13.         /// <summary>
  14.         /// Represents the log base two of e.
  15.         /// </summary>
  16.         public const float Log2E = 1.442695f;
  17.         /// <summary>
  18.         /// First Person Rotational Bounds Limits
  19.         /// </summary>
  20.         public const float PiOver2RadiusClamp = 1.560796F;
  21.         /// <summary>
  22.         /// Represents the log base ten of e.
  23.         /// </summary>
  24.         public const float Log10E = 0.4342945f;
  25.         /// <summary>
  26.         /// Represents the value of pi.
  27.         /// </summary>
  28.         public const float Pi = 3.141593f;
  29.         /// <summary>
  30.         /// Represents the value of pi times two.
  31.         /// </summary>
  32.         public const float TwoPi = 6.28318530718f;
  33.         /// <summary>
  34.         /// Represents the value of pi times two.
  35.         /// </summary>
  36.         public const float FourPi = 12.5663706144f;
  37.         /// <summary>
  38.         /// Represents the value of pi divided by two.
  39.         /// </summary>
  40.         public const float PiOver2 = 1.570796f;
  41.         /// <summary>
  42.         /// Represents the value of pi divided by four.
  43.         /// </summary>
  44.         public const float PiOver4 = 0.7853982f;
  45.         /// <summary>
  46.         ///
  47.         /// </summary>
  48.         public const float PiDividedBy180 = 0.01745329F;
  49.         /// <summary>
  50.         /// My lucky number 31.
  51.         /// </summary>
  52.         public const int Lucky31 = 31;
  53.         /// <summary>
  54.         /// 0.5f
  55.         /// </summary>
  56.         public const float ModifierHalf = 0.5f;
  57.         /// <summary>
  58.         /// 1.0f
  59.         /// </summary>
  60.         public const float ModifierEqual = 1.0f;
  61.         /// <summary>
  62.         /// 1.5f
  63.         /// </summary>
  64.         public const float ModifierSesqui = 1.5f;
  65.         /// <summary>
  66.         /// 2.0f
  67.         /// </summary>
  68.         public const float ModifierDouble = 2.0f;
  69.  
  70.         /// <summary>
  71.         ///
  72.         /// </summary>
  73.         /// <param name="fieldOfView"></param>
  74.         /// <param name="farZ"></param>
  75.         /// <param name="nearZ"></param>
  76.         /// <param name="viewportWidth"></param>
  77.         /// <param name="viewportHeight"></param>
  78.         /// <returns></returns>
  79.         public static Matrix CreateInfiniteProjectionMatrix(float fieldOfView, float nearZ, float farZ, float viewportWidth, float viewportHeight)
  80.         {
  81.             float e = 1 / (float)Math.Tan(fieldOfView / 2);
  82.             float a = viewportHeight / viewportWidth;
  83.             float alg1 = -((farZ + nearZ) / (farZ - nearZ));
  84.             float alg2 = -((2 * farZ * nearZ) / (farZ - nearZ));
  85.             Matrix result = new Matrix(
  86.                 e, 0.0f, 0.0f, 0.0f,
  87.                 0.0f, e / a, 0.0f, 0.0f,
  88.                 0.0f, 0.0f, alg1, alg2,
  89.                 0.0f, 0.0f, -1.0f, 0.0f);
  90.             return result;
  91.         }
  92.  
  93.         //Matrix InfiniteReverseZProjection(float fovY_radians, float aspectWbyH, float zNear)
  94.         //{
  95.         //    float f = 1.0f / (float)System.Math.Tan(fovY_radians / 2.0f);
  96.         //    Matrix Result = new Matrix(
  97.         //        f / aspectWbyH, 0.0f, 0.0f, 0.0f,
  98.         //                  0.0f, f, 0.0f, 0.0f,
  99.         //                  0.0f, 0.0f, 0.0f, -1.0f,
  100.         //                  0.0f, 0.0f, zNear, 0.0f);
  101.  
  102.         //    return Result;
  103.         //}
  104.  
  105.         public static int ToNearest(int value, int power, bool allowZero = true)
  106.         {
  107.             int result = power * (int)Math.Round(value / (double)power);
  108.             if (!allowZero)
  109.             {
  110.                 if (result <= 1)
  111.                 {
  112.                     return power;
  113.                 }
  114.             }
  115.             return result;
  116.         }
  117.  
  118.         /// <summary>
  119.         /// Inverts a given Integer.
  120.         /// </summary>
  121.         /// <param name="value"></param>
  122.         /// <returns></returns>
  123.         public static int Invert(int value)
  124.         {
  125.             return -value;
  126.         }
  127.  
  128.         /// <summary>
  129.         /// Increases or decreases a given number by a multiplier. If the
  130.         /// multiplier is greater than 0, the number will be increased. If
  131.         /// the number is less than 0, the given number will be decreased
  132.         /// by the multiplier.
  133.         /// </summary>
  134.         /// <param name="value"></param>
  135.         /// <param name="multiplier"></param>
  136.         /// <returns></returns>
  137.         public static int ApplyMultiplier(int value, int multiplier)
  138.         {
  139.             return (int)(value * ToMultiplier(multiplier));
  140.         }
  141.  
  142.         /// <summary>
  143.         /// Converts an integer to a multiplier. If the value of 20
  144.         /// is used, the output will be 1.20, if -40 is used, the output
  145.         /// will be 0.60
  146.         /// </summary>
  147.         /// <param name="percent"></param>
  148.         /// <returns></returns>
  149.         public static double ToMultiplier(int percent)
  150.         {
  151.             return ((100 + percent) / 100D);
  152.         }
  153.  
  154.         /// <summary>
  155.         ///
  156.         /// </summary>
  157.         /// <param name="value"></param>
  158.         /// <param name="percent"></param>
  159.         /// <returns></returns>
  160.         public static double PercentOf(int value, int percent)
  161.         {
  162.             return ((Clamp(percent, 0, 100) / 100d) * value);
  163.         }
  164.  
  165.         /// <summary>
  166.         /// Clamps the specified Number to between 0-360, and wraps
  167.         /// back around if required.
  168.         /// </summary>
  169.         /// <param name="degrees"></param>
  170.         /// <returns></returns>
  171.         public static int ClampDegrees(int degrees)
  172.         {
  173.             return (degrees % 360) + (degrees < 0 ? 360 : 0);
  174.         }
  175.  
  176.         public static double InversePow(double value, double power)
  177.         {
  178.             return Math.Pow(value, 1.0 / power);
  179.         }
  180.  
  181.         /// <summary>
  182.         ///
  183.         /// </summary>
  184.         /// <param name="f"></param>
  185.         /// <returns></returns>
  186.         public static float Sin(float f)
  187.         {
  188.             return (float)Math.Sin(f);
  189.         }
  190.         /// <summary>
  191.         ///
  192.         /// </summary>
  193.         /// <param name="f"></param>
  194.         /// <returns></returns>
  195.         public static float Cos(float f)
  196.         {
  197.             return (float)Math.Cos(f);
  198.         }
  199.         /// <summary>
  200.         ///
  201.         /// </summary>
  202.         /// <param name="f"></param>
  203.         /// <returns></returns>
  204.         public static float Tan(float f)
  205.         {
  206.             return (float)Math.Tan(f);
  207.         }
  208.         /// <summary>
  209.         ///
  210.         /// </summary>
  211.         /// <param name="f"></param>
  212.         /// <returns></returns>
  213.         public static float Asin(float f)
  214.         {
  215.             return (float)Math.Asin(f);
  216.         }
  217.         /// <summary>
  218.         ///
  219.         /// </summary>
  220.         /// <param name="f"></param>
  221.         /// <returns></returns>
  222.         public static float Acos(float f)
  223.         {
  224.             return (float)Math.Acos(f);
  225.         }
  226.         /// <summary>
  227.         ///
  228.         /// </summary>
  229.         /// <param name="f"></param>
  230.         /// <returns></returns>
  231.         public static float Atan(float f)
  232.         {
  233.             return (float)Math.Atan(f);
  234.         }
  235.         /// <summary>
  236.         ///
  237.         /// </summary>
  238.         /// <param name="y"></param>
  239.         /// <param name="x"></param>
  240.         /// <returns></returns>
  241.         public static float Atan2(float y, float x)
  242.         {
  243.             return (float)Math.Atan2(y, x);
  244.         }
  245.         /// <summary>
  246.         ///
  247.         /// </summary>
  248.         /// <param name="f"></param>
  249.         /// <returns></returns>
  250.         public static float Sqrt(float f)
  251.         {
  252.             return (float)Math.Sqrt(f);
  253.         }
  254.         /// <summary>
  255.         ///
  256.         /// </summary>
  257.         /// <param name="x"></param>
  258.         /// <param name="y"></param>
  259.         /// <returns></returns>
  260.         public static float Pow(float x, float y)
  261.         {
  262.             return (float)Math.Pow(x, y);
  263.         }
  264.         /// <summary>
  265.         ///
  266.         /// </summary>
  267.         /// <param name="x"></param>
  268.         /// <param name="y"></param>
  269.         /// <returns></returns>
  270.         public static float Pow(double x, double y)
  271.         {
  272.             return (float)Math.Pow(x, y);
  273.         }
  274.         /// <summary>
  275.         ///
  276.         /// </summary>
  277.         /// <param name="f"></param>
  278.         /// <returns></returns>
  279.         public static float Abs(float f)
  280.         {
  281.             return Math.Abs(f);
  282.         }
  283.         /// <summary>
  284.         ///
  285.         /// </summary>
  286.         /// <param name="value"></param>
  287.         /// <returns></returns>
  288.         public static int Abs(int value)
  289.         {
  290.             return Math.Abs(value);
  291.         }
  292.         /// <summary>
  293.         ///
  294.         /// </summary>
  295.         /// <param name="value"></param>
  296.         /// <param name="percent"></param>
  297.         /// <returns></returns>
  298.         public static int MultiplyByPercent(int value, double percent)
  299.         {
  300.             return ((int)(value * percent));
  301.         }
  302.  
  303.         public static string GetSign(int value)
  304.         {
  305.             if (value == 0)
  306.             {
  307.                 return "";
  308.             }
  309.             if (value > 0)
  310.             {
  311.                 return "+";
  312.             }
  313.             else
  314.             {
  315.                 return "-";
  316.             }
  317.         }
  318.  
  319.         /// <summary>
  320.         /// Clamps the specified value.
  321.         /// </summary>
  322.         /// <param name="value">The value.</param>
  323.         /// <param name="min">The minimum.</param>
  324.         /// <param name="max">The maximum.</param>
  325.         /// <returns></returns>
  326.         public static int Clamp(int value, int min, int max)
  327.         {
  328.             return (value < min) ? min : (value > max) ? max : value;
  329.         }
  330.  
  331.         /// <summary>
  332.         ///
  333.         /// </summary>
  334.         /// <param name="value"></param>
  335.         /// <param name="range"></param>
  336.         /// <returns></returns>
  337.         public static int Clamp(int value, Range range)
  338.         {
  339.             return Clamp(value, range.Minimum, range.Maximum);
  340.         }
  341.  
  342.         /// <summary>
  343.         ///
  344.         /// </summary>
  345.         /// <param name="array"></param>
  346.         /// <param name="min"></param>
  347.         /// <param name="max"></param>
  348.         public static void Clamp(int[] array, int min, int max)
  349.         {
  350.             for (int i = 0; i < array.Length; i++)
  351.             {
  352.                 array[i] = Clamp(array[i], min, max);
  353.             }
  354.         }
  355.  
  356.         /// <summary>
  357.         ///
  358.         /// </summary>
  359.         /// <param name="array"></param>
  360.         /// <param name="range"></param>
  361.         public static void Clamp(int[] array, Range range)
  362.         {
  363.             Clamp(array, range.Minimum, range.Maximum);
  364.         }
  365.  
  366.         /// <summary>
  367.         /// Clamps the specified value.
  368.         /// </summary>
  369.         /// <param name="value">The value.</param>
  370.         /// <param name="min">The minimum.</param>
  371.         /// <param name="max">The maximum.</param>
  372.         /// <returns></returns>
  373.         public static float Clamp(float value, float min, float max)
  374.         {
  375.             return (value < min) ? min : (value > max) ? max : value;
  376.         }
  377.  
  378.         /// <summary>
  379.         ///
  380.         /// </summary>
  381.         /// <param name="array"></param>
  382.         /// <param name="min"></param>
  383.         /// <param name="max"></param>
  384.         public static void Clamp(float[] array, float min, float max)
  385.         {
  386.             for (int i = 0; i < array.Length; i++)
  387.             {
  388.                 array[i] = Clamp(array[i], min, max);
  389.             }
  390.         }
  391.  
  392.         /// <summary>
  393.         /// Clamps the specified value.
  394.         /// </summary>
  395.         /// <param name="value">The value.</param>
  396.         /// <param name="min">The minimum.</param>
  397.         /// <param name="max">The maximum.</param>
  398.         /// <returns></returns>
  399.         public static double Clamp(double value, double min, double max)
  400.         {
  401.             return (value < min) ? min : (value > max) ? max : value;
  402.         }
  403.  
  404.         /// <summary>
  405.         ///
  406.         /// </summary>
  407.         /// <param name="array"></param>
  408.         /// <param name="min"></param>
  409.         /// <param name="max"></param>
  410.         public static void Clamp(double[] array, double min, double max)
  411.         {
  412.             for (int i = 0; i < array.Length; i++)
  413.             {
  414.                 array[i] = Clamp(array[i], min, max);
  415.             }
  416.         }
  417.  
  418.         /// <summary>
  419.         /// Clamps the specified value.
  420.         /// </summary>
  421.         /// <param name="value">The value.</param>
  422.         /// <param name="min">The minimum.</param>
  423.         /// <param name="max">The maximum.</param>
  424.         /// <returns></returns>
  425.         public static long Clamp(long value, long min, long max)
  426.         {
  427.             return (value < min) ? min : (value > max) ? max : value;
  428.         }
  429.  
  430.         /// <summary>
  431.         ///
  432.         /// </summary>
  433.         /// <param name="array"></param>
  434.         /// <param name="min"></param>
  435.         /// <param name="max"></param>
  436.         public static void Clamp(long[] array, long min, long max)
  437.         {
  438.             for (int i = 0; i < array.Length; i++)
  439.             {
  440.                 array[i] = Clamp(array[i], min, max);
  441.             }
  442.         }
  443.  
  444.         /// <summary>
  445.         /// Clamps the specified value.
  446.         /// </summary>
  447.         /// <param name="value">The value.</param>
  448.         /// <param name="min">The minimum.</param>
  449.         /// <param name="max">The maximum.</param>
  450.         /// <returns></returns>
  451.         public static byte Clamp(byte value, byte min, byte max)
  452.         {
  453.             return (value < min) ? min : (value > max) ? max : value;
  454.         }
  455.  
  456.         /// <summary>
  457.         ///
  458.         /// </summary>
  459.         /// <param name="array"></param>
  460.         /// <param name="min"></param>
  461.         /// <param name="max"></param>
  462.         public static void Clamp(byte[] array, byte min, byte max)
  463.         {
  464.             for (int i = 0; i < array.Length; i++)
  465.             {
  466.                 array[i] = Clamp(array[i], min, max);
  467.             }
  468.         }
  469.  
  470.         /// <summary>
  471.         /// Clamps the specfied number to number desired maximum.
  472.         /// </summary>
  473.         /// <param name="value">The value.</param>
  474.         /// <param name="max">The maximum.</param>
  475.         /// <returns></returns>
  476.         public static int ClampMaximum(int value, int max)
  477.         {
  478.             return value > max ? max : value;
  479.         }
  480.  
  481.         /// <summary>
  482.         ///
  483.         /// </summary>
  484.         /// <param name="array"></param>
  485.         /// <param name="max"></param>
  486.         public static void Max(int[] array, int max)
  487.         {
  488.             for (int i = 0; i < array.Length; i++)
  489.             {
  490.                 array[i] = ClampMaximum(array[i], max);
  491.             }
  492.         }
  493.  
  494.         /// <summary>
  495.         /// Clamps the specfied number to number desired maximum.
  496.         /// </summary>
  497.         /// <param name="value">The value.</param>
  498.         /// <param name="max">The maximum.</param>
  499.         /// <returns></returns>
  500.         public static double Max(double value, double max)
  501.         {
  502.             return value > max ? max : value;
  503.         }
  504.  
  505.         /// <summary>
  506.         ///
  507.         /// </summary>
  508.         /// <param name="array"></param>
  509.         /// <param name="max"></param>
  510.         public static void Max(double[] array, double max)
  511.         {
  512.             for (int i = 0; i < array.Length; i++)
  513.             {
  514.                 array[i] = Max(array[i], max);
  515.             }
  516.         }
  517.  
  518.         /// <summary>
  519.         /// Clamps the specfied number to number desired maximum.
  520.         /// </summary>
  521.         /// <param name="value">The value.</param>
  522.         /// <param name="max">The maximum.</param>
  523.         /// <returns></returns>
  524.         public static byte Max(byte value, byte max)
  525.         {
  526.             return value > max ? max : value;
  527.         }
  528.  
  529.         /// <summary>
  530.         ///
  531.         /// </summary>
  532.         /// <param name="array"></param>
  533.         /// <param name="max"></param>
  534.         public static void Max(byte[] array, byte max)
  535.         {
  536.             for (int i = 0; i < array.Length; i++)
  537.             {
  538.                 array[i] = Max(array[i], max);
  539.             }
  540.         }
  541.  
  542.         /// <summary>
  543.         /// Clamps the specfied number to number desired maximum.
  544.         /// </summary>
  545.         /// <param name="value">The value.</param>
  546.         /// <param name="max">The maximum.</param>
  547.         /// <returns></returns>
  548.         public static float Max(float value, float max)
  549.         {
  550.             return value > max ? max : value;
  551.         }
  552.  
  553.         /// <summary>
  554.         ///
  555.         /// </summary>
  556.         /// <param name="array"></param>
  557.         /// <param name="max"></param>
  558.         public static void Max(float[] array, float max)
  559.         {
  560.             for (int i = 0; i < array.Length; i++)
  561.             {
  562.                 array[i] = Max(array[i], max);
  563.             }
  564.         }
  565.  
  566.         /// <summary>
  567.         /// Clamps the specfied number to number desired minimum.
  568.         /// </summary>
  569.         /// <param name="value">The value.</param>
  570.         /// <param name="min">The minimum.</param>
  571.         /// <returns></returns>
  572.         public static int ClampMinimum(int value, int min)
  573.         {
  574.             return value < min ? min : value;
  575.         }
  576.  
  577.         /// <summary>
  578.         ///
  579.         /// </summary>
  580.         /// <param name="array"></param>
  581.         /// <param name="min"></param>
  582.         public static void Min(int[] array, int min)
  583.         {
  584.             for (int i = 0; i < array.Length; i++)
  585.             {
  586.                 array[i] = ClampMinimum(array[i], min);
  587.             }
  588.         }
  589.  
  590.         /// <summary>
  591.         /// Clamps the specfied number to number desired minimum.
  592.         /// </summary>
  593.         /// <param name="value">The value.</param>
  594.         /// <param name="min">The minimum.</param>
  595.         /// <returns></returns>
  596.         public static double Min(double value, double min)
  597.         {
  598.             return value < min ? min : value;
  599.         }
  600.  
  601.         /// <summary>
  602.         ///
  603.         /// </summary>
  604.         /// <param name="array"></param>
  605.         /// <param name="min"></param>
  606.         public static void Min(double[] array, double min)
  607.         {
  608.             for (int i = 0; i < array.Length; i++)
  609.             {
  610.                 array[i] = Min(array[i], min);
  611.             }
  612.         }
  613.  
  614.         /// <summary>
  615.         /// Clamps the specified number to number desired minimum.
  616.         /// </summary>
  617.         /// <param name="value">The value.</param>
  618.         /// <param name="min">The minimum.</param>
  619.         /// <returns></returns>
  620.         public static byte Min(byte value, byte min)
  621.         {
  622.             return value < min ? min : value;
  623.         }
  624.  
  625.         /// <summary>
  626.         ///
  627.         /// </summary>
  628.         /// <param name="array"></param>
  629.         /// <param name="min"></param>
  630.         public static void Min(byte[] array, byte min)
  631.         {
  632.             for (int i = 0; i < array.Length; i++)
  633.             {
  634.                 array[i] = Min(array[i], min);
  635.             }
  636.         }
  637.  
  638.         /// <summary>
  639.         /// Clamps the specified number to number desired minimum.
  640.         /// </summary>
  641.         /// <param name="value">The value.</param>
  642.         /// <param name="min">The minimum.</param>
  643.         /// <returns></returns>
  644.         public static float Min(float value, float min)
  645.         {
  646.             return value < min ? min : value;
  647.         }
  648.  
  649.         /// <summary>
  650.         ///
  651.         /// </summary>
  652.         /// <param name="array"></param>
  653.         /// <param name="min"></param>
  654.         public static void Min(float[] array, float min)
  655.         {
  656.             for (int i = 0; i < array.Length; i++)
  657.             {
  658.                 array[i] = Min(array[i], min);
  659.             }
  660.         }
  661.  
  662.  
  663.         /// <summary>
  664.         /// Parses number positive or negative integer from number string using number highly optimized routine.
  665.         /// </summary>
  666.         /// <param name="data"></param>
  667.         /// <returns></returns>
  668.         public static int ParseInt32Fast(string data)
  669.         {
  670.             return data[0] == 45 ? ParseNegativeInt32Fast(data) : ParsePositiveInt32Fast(data);
  671.         }
  672.  
  673.         /// <summary>
  674.         /// Parses number positive integer from number string using number highly optimized routine.
  675.         /// </summary>
  676.         /// <param name="data"></param>
  677.         /// <returns></returns>
  678.         public static int ParsePositiveInt32Fast(string data)
  679.         {
  680.             int result = 0;
  681.             for (int i = 0; i < data.Length; i++)
  682.             {
  683.                 result = ((10 * result) + (data[i] - 48));
  684.             }
  685.             return result;
  686.         }
  687.  
  688.         public static bool IsNumeric(string data, bool canBeNegative = true, bool canHaveDecimalPlace = false)
  689.         {
  690.             int negativeSignCount = 0;
  691.             for (int i = 0; i < data.Length; i++)
  692.             {
  693.                 if (data[i] == '-')
  694.                 {
  695.                     if (!canBeNegative)
  696.                     {
  697.                         return false;
  698.                     }
  699.                     negativeSignCount++;
  700.                     if (negativeSignCount > 1)
  701.                     {
  702.                         return false;
  703.                     }
  704.                     continue;
  705.                 }
  706.                 if (!char.IsDigit(data[i]))
  707.                 {
  708.                     return false;
  709.                 }
  710.             }
  711.             return true;
  712.         }
  713.  
  714.         /// <summary>
  715.         /// Creates an Oriented Bounding Box
  716.         /// </summary>
  717.         /// <param name="min"></param>
  718.         /// <param name="max"></param>
  719.         /// <param name="transform"></param>
  720.         /// <returns></returns>
  721.         public static BoundingBox CreateOrientedBoundingBox(Vector3 min, Vector3 max, Matrix transform)
  722.         {
  723.             Vector3[] corners = new Vector3[]
  724.             {
  725.                 Vector3.TransformCoordinate(new Vector3(min.X, max.Y, max.Z), transform),
  726.                 Vector3.TransformCoordinate(new Vector3(max.X, max.Y, max.Z), transform),
  727.                 Vector3.TransformCoordinate(new Vector3(max.X, min.Y, max.Z), transform),
  728.                 Vector3.TransformCoordinate(new Vector3(min.X, min.Y, max.Z), transform),
  729.                 Vector3.TransformCoordinate(new Vector3(min.X, max.Y, min.Z), transform),
  730.                 Vector3.TransformCoordinate(new Vector3(max.X, max.Y, min.Z), transform),
  731.                 Vector3.TransformCoordinate(new Vector3(max.X, min.Y, min.Z), transform),
  732.                 Vector3.TransformCoordinate(new Vector3(min.X, min.Y, min.Z), transform)
  733.             };
  734.             return BoundingBox.FromPoints(corners);
  735.         }
  736.  
  737.         /// <summary>
  738.         /// Creates a Billboard Matrix that is aligned on all axes.
  739.         /// </summary>
  740.         /// <param name="geometryLocation"></param>
  741.         /// <param name="cameraLocation"></param>
  742.         /// <param name="up"></param>
  743.         /// <param name="forward"></param>
  744.         /// <param name="applyTranslation"></param>
  745.         /// <returns></returns>
  746.         public static Matrix CreateBillboard(Vector3 geometryLocation, Vector3 cameraLocation, Vector3 up, Vector3 forward)
  747.         {
  748.             Vector3 difference = geometryLocation - cameraLocation;
  749.             float lengthSquared = difference.LengthSquared();
  750.             difference = MathUtil.IsZero(lengthSquared) ? -forward : difference * (float)(1.0 / Math.Sqrt(lengthSquared));
  751.             Vector3.Cross(ref up, ref difference, out Vector3 crossProduct);
  752.             crossProduct.Normalize();
  753.             Vector3.Cross(ref difference, ref crossProduct, out Vector3 final);
  754.             Matrix result = new Matrix
  755.             {
  756.                 M11 = crossProduct.X,
  757.                 M12 = crossProduct.Y,
  758.                 M13 = crossProduct.Z,
  759.                 M21 = final.X,
  760.                 M22 = final.Y,
  761.                 M23 = final.Z,
  762.                 M31 = difference.X,
  763.                 M32 = difference.Y,
  764.                 M33 = difference.Z,
  765.                 M41 = geometryLocation.X,
  766.                 M42 = geometryLocation.Y,
  767.                 M43 = geometryLocation.Z,
  768.                 M44 = 1.0f
  769.             };
  770.             return result;
  771.         }
  772.  
  773.         /// <summary>
  774.         /// Creates a Billboard matrix that is aligned on the X and Z axis.
  775.         /// </summary>
  776.         /// <param name="geometryLocation"></param>
  777.         /// <param name="cameraLocation"></param>
  778.         /// <param name="up"></param>
  779.         /// <param name="forward"></param>
  780.         /// <param name="applyTranslation"></param>
  781.         /// <returns></returns>
  782.         public static Matrix CreateBillboardXZAxis(Vector3 geometryLocation, Vector3 cameraLocation, Vector3 up, Vector3 forward)
  783.         {
  784.             Vector3 difference = new Vector3(geometryLocation.X, 0, geometryLocation.Z) - new Vector3(cameraLocation.X, 0, cameraLocation.Z);
  785.             float lengthSquared = difference.LengthSquared();
  786.             difference = MathUtil.IsZero(lengthSquared) ? -forward : difference * (float)(1.0 / Math.Sqrt(lengthSquared));
  787.             Vector3.Cross(ref up, ref difference, out Vector3 crossProduct);
  788.             crossProduct.Normalize();
  789.             Vector3.Cross(ref difference, ref crossProduct, out Vector3 final);
  790.             Matrix result = new Matrix
  791.             {
  792.                 M11 = crossProduct.X,
  793.                 M12 = crossProduct.Y,
  794.                 M13 = crossProduct.Z,
  795.                 M21 = final.X,
  796.                 M22 = final.Y,
  797.                 M23 = final.Z,
  798.                 M31 = difference.X,
  799.                 M32 = difference.Y,
  800.                 M33 = difference.Z,
  801.                 M41 = geometryLocation.X,
  802.                 M42 = geometryLocation.Y,
  803.                 M43 = geometryLocation.Z,
  804.                 M44 = 1.0f
  805.             };
  806.             return result;
  807.         }
  808.  
  809.         /// <summary>
  810.         /// Parses number negative integer from number string using number highly optimized routine.
  811.         /// </summary>
  812.         /// <param name="data"></param>
  813.         /// <returns></returns>
  814.         public static int ParseNegativeInt32Fast(string data)
  815.         {
  816.             int result = 0;
  817.             for (int i = 1; i < data.Length; i++)
  818.             {
  819.                 result = ((10 * result) + (data[i] - 48));
  820.             }
  821.             return -result;
  822.         }
  823.  
  824.         /// <summary>
  825.         /// Parses number floating point number from number string. This
  826.         /// function uses an invariant culture, meaning the float
  827.         /// can be either negative or positive.
  828.         /// </summary>
  829.         /// <param name="input">The input.</param>
  830.         /// <returns></returns>
  831.         public static float ParseFloatFast(string input)
  832.         {
  833.             float result = 0;
  834.             int index = 0;
  835.             float exp = 0.1f;
  836.             int length = input.Length;
  837.             char character = input[0];
  838.             float sign = 1;
  839.             if (character == 45)
  840.             {
  841.                 sign = -1;
  842.                 ++index;
  843.             }
  844.             while (true)
  845.             {
  846.                 if (index >= length)
  847.                 {
  848.                     return sign * result;
  849.                 }
  850.                 character = input[index++];
  851.                 if (character < 48 || character > 57)
  852.                 {
  853.                     break;
  854.                 }
  855.                 result = ((result * 10) + (character - 48));
  856.             }
  857.             while (index < length)
  858.             {
  859.                 character = input[index++];
  860.                 result += (character - 48) * exp;
  861.                 exp *= 0.1f;
  862.             }
  863.             return sign * result;
  864.         }
  865.  
  866.         public static double ParseDoubleFast(string input)
  867.         {
  868.             double result = 0;
  869.             int index = 0;
  870.             double exp = 0.1f;
  871.             int length = input.Length;
  872.             char character = input[0];
  873.             double sign = 1;
  874.             if (character == 45)
  875.             {
  876.                 sign = -1;
  877.                 ++index;
  878.             }
  879.             while (true)
  880.             {
  881.                 if (index >= length)
  882.                 {
  883.                     return sign * result;
  884.                 }
  885.                 character = input[index++];
  886.                 if (character < 48 || character > 57)
  887.                 {
  888.                     break;
  889.                 }
  890.                 result = ((result * 10) + (character - 48));
  891.             }
  892.             while (index < length)
  893.             {
  894.                 character = input[index++];
  895.                 result += (character - 48) * exp;
  896.                 exp *= 0.1f;
  897.             }
  898.             return sign * result;
  899.         }
  900.         /// <summary>
  901.         /// CubeRoot(number,power)
  902.         /// </summary>
  903.         /// <param name="number"></param>
  904.         /// <param name="power"></param>
  905.         /// <returns></returns>
  906.         public static double CubeRoot(double number, int power)
  907.         {
  908.             double[] x = new double[2];
  909.             x[0] = number;
  910.             x[1] = number / power;
  911.             while (Math.Abs(x[0] - x[1]) > 0.001D)
  912.             {
  913.                 x[1] = x[0];
  914.                 x[0] = (1 / (double)power) * ((((double)power - 1) * x[1]) + (number / Math.Pow(x[1], (double)power - 1)));
  915.             }
  916.             return x[0];
  917.         }
  918.  
  919.         /// <summary>
  920.         /// Converts degrees to radians.
  921.         /// </summary>
  922.         /// <param name="degrees">The angle in degrees.</param>
  923.         public static float ToRadians(float degrees)
  924.         {
  925.             return degrees / 360.0f * TwoPi;
  926.         }
  927.  
  928.         /// <summary>
  929.         /// Creates a rotation matrix using degrees.
  930.         /// </summary>
  931.         /// <param name="xDegrees"></param>
  932.         /// <param name="yDegrees"></param>
  933.         /// <param name="zDegrees"></param>
  934.         /// <returns></returns>
  935.         public static Matrix CreateRotationMatrix(float xDegrees, float yDegrees, float zDegrees)
  936.         {
  937.             return
  938.                 Matrix.RotationX(ToRadians(xDegrees)) *
  939.                 Matrix.RotationY(ToRadians(yDegrees)) *
  940.                 Matrix.RotationZ(ToRadians(zDegrees));
  941.         }
  942.  
  943.         /// <summary>
  944.         /// Converts a Vector3 of Degrees to a Vector3 of Radians
  945.         /// </summary>
  946.         /// <param name="degrees"></param>
  947.         /// <returns></returns>
  948.         public static Vector3 ToRadians(Vector3 degrees)
  949.         {
  950.             return ToRadians(degrees.X,degrees.Y,degrees.Z);
  951.         }
  952.  
  953.         /// <summary>
  954.         ///
  955.         /// </summary>
  956.         /// <param name="degreesX"></param>
  957.         /// <param name="degreesY"></param>
  958.         /// <param name="degreesZ"></param>
  959.         /// <returns></returns>
  960.         public static Vector3 ToRadians(float degreesX, float degreesY, float degreesZ)
  961.         {
  962.             return
  963.                 new Vector3(
  964.                     ToRadians(degreesX),
  965.                     ToRadians(degreesY),
  966.                     ToRadians(degreesZ));
  967.         }
  968.  
  969.         /// <summary>
  970.         ///
  971.         /// </summary>
  972.         /// <param name="degrees"></param>
  973.         public static void ToRadians(float[] degrees)
  974.         {
  975.             for(int i = 0; i < degrees.Length; i++)
  976.             {
  977.                 degrees[i] = ToRadians(degrees[i]);
  978.             }
  979.         }
  980.  
  981.         /// <summary>
  982.         ///
  983.         /// </summary>
  984.         /// <param name="degrees"></param>
  985.         /// <returns></returns>
  986.         public static Matrix CreateRotationMatrix(Vector3 degrees)
  987.         {
  988.             return CreateRotationMatrix(degrees.X, degrees.Y, degrees.Z);
  989.         }
  990.  
  991.         /// <summary>
  992.         /// Converts radians to degrees.
  993.         /// </summary>
  994.         /// <param name="radians">The angle in radians.</param>
  995.         public static float ToDegrees(float radians)
  996.         {
  997.             return radians * 57.29578f;
  998.         }
  999.  
  1000.         /// <summary>
  1001.         ///
  1002.         /// </summary>
  1003.         /// <param name="radians"></param>
  1004.         /// <returns></returns>
  1005.         public static double ToDegrees(double radians)
  1006.         {
  1007.             return radians * 57.29578;
  1008.         }
  1009.  
  1010.         /// <summary>
  1011.         /// Gets the nearest bigger power of two.
  1012.         /// </summary>
  1013.         /// <param name="v">The v.</param>
  1014.         /// <returns></returns>
  1015.         public static int GetNearestBiggerPowerOfTwo(int v)
  1016.         {
  1017.             --v;
  1018.             v |= v >> 1;
  1019.             v |= v >> 2;
  1020.             v |= v >> 4;
  1021.             v |= v >> 8;
  1022.             v |= v >> 16;
  1023.             ++v;
  1024.             return v;
  1025.         }
  1026.  
  1027.         /// <summary>
  1028.         /// Gets the nearest bigger power of two.
  1029.         /// </summary>
  1030.         /// <param name="v">The v.</param>
  1031.         /// <returns></returns>
  1032.         public static uint GetNearestBiggerPowerOfTwo(uint v)
  1033.         {
  1034.             --v;
  1035.             v |= v >> 1;
  1036.             v |= v >> 2;
  1037.             v |= v >> 4;
  1038.             v |= v >> 8;
  1039.             v |= v >> 16;
  1040.             ++v;
  1041.             return v;
  1042.         }
  1043.  
  1044.         /// <summary>
  1045.         /// Returns nearest bigger power of two
  1046.         /// </summary>
  1047.         /// <param name="f"></param>
  1048.         /// <returns></returns>
  1049.         public static int GetNearestBiggerPowerOfTwo(float f)
  1050.         {
  1051.             int x = 1;
  1052.             while (x < f)
  1053.             {
  1054.                 x <<= 1;
  1055.             }
  1056.             return x;
  1057.         }
  1058.  
  1059.         /// <summary>
  1060.         /// Gets the nearest bigger power of two.
  1061.         /// </summary>
  1062.         /// <param name="f">The f.</param>
  1063.         /// <returns></returns>
  1064.         public static int GetNearestBiggerPowerOfTwo(double f)
  1065.         {
  1066.             int x = 1;
  1067.             while (x < f)
  1068.             {
  1069.                 x <<= 1;
  1070.             }
  1071.             return x;
  1072.         }
  1073.  
  1074.         /// <summary>
  1075.         /// Returns true if value is power of two
  1076.         /// </summary>
  1077.         /// <param name="x"></param>
  1078.         /// <returns></returns>
  1079.         public static bool IsPowerOfTwo(int x)
  1080.         {
  1081.             return ((x > 0) && ((x & (x - 1)) == 0));
  1082.         }
  1083.  
  1084.         /// <summary>
  1085.         /// Determines whether the specified value is odd.
  1086.         /// </summary>
  1087.         /// <param name="value">The value.</param>
  1088.         /// <returns></returns>
  1089.         public static bool IsOdd(int value)
  1090.         {
  1091.             return value % 2 != 0;
  1092.         }
  1093.  
  1094.         /// <summary>
  1095.         /// Determines whether the specified value is even.
  1096.         /// </summary>
  1097.         /// <param name="value">The value.</param>
  1098.         /// <returns></returns>
  1099.         public static bool IsEven(int value)
  1100.         {
  1101.             return value % 2 == 0;
  1102.         }
  1103.  
  1104.         /// <summary>
  1105.         /// Barycentrics the specified value1.
  1106.         /// </summary>
  1107.         /// <param name="value1">The value1.</param>
  1108.         /// <param name="value2">The value2.</param>
  1109.         /// <param name="value3">The value3.</param>
  1110.         /// <param name="amount1">The amount1.</param>
  1111.         /// <param name="amount2">The amount2.</param>
  1112.         /// <returns></returns>
  1113.         public static float Barycentric(float value1, float value2, float value3, float amount1, float amount2)
  1114.         {
  1115.             return value1 + (value2 - value1) * amount1 + (value3 - value1) * amount2;
  1116.         }
  1117.  
  1118.         /// <summary>
  1119.         /// Catmulls the rom.
  1120.         /// </summary>
  1121.         /// <param name="value1">The value1.</param>
  1122.         /// <param name="value2">The value2.</param>
  1123.         /// <param name="value3">The value3.</param>
  1124.         /// <param name="value4">The value4.</param>
  1125.         /// <param name="amount">The amount.</param>
  1126.         /// <returns></returns>
  1127.         public static float CatmullRom(float value1, float value2, float value3, float value4, float amount)
  1128.         {
  1129.             double amountSquared = amount * amount;
  1130.             double amountCubed = amountSquared * amount;
  1131.             return (float)(0.5 * (2.0 * value2 +
  1132.                 (value3 - value1) * amount +
  1133.                 (2.0 * value1 - 5.0 * value2 + 4.0 * value3 - value4) * amountSquared +
  1134.                 (3.0 * value2 - value1 - 3.0 * value3 + value4) * amountCubed));
  1135.         }
  1136.  
  1137.         /// <summary>
  1138.         /// Distances the specified left.
  1139.         /// </summary>
  1140.         /// <param name="left">The left.</param>
  1141.         /// <param name="right">The right.</param>
  1142.         /// <returns></returns>
  1143.         public static float Distance(float left, float right)
  1144.         {
  1145.             return Math.Abs(left - right);
  1146.         }
  1147.  
  1148.         /// <summary>
  1149.         /// Distances the specified left.
  1150.         /// </summary>
  1151.         /// <param name="left">The left.</param>
  1152.         /// <param name="right">The right.</param>
  1153.         /// <returns></returns>
  1154.         public static int Distance(int left, int right)
  1155.         {
  1156.             return Math.Abs(left - right);
  1157.         }
  1158.  
  1159.         /// <summary>
  1160.         ///
  1161.         /// </summary>
  1162.         /// <param name="left"></param>
  1163.         /// <param name="right"></param>
  1164.         /// <returns></returns>
  1165.         public static float Distance(Vector3 left, Vector3 right)
  1166.         {
  1167.             return Math.Abs((left - right).Length());
  1168.         }
  1169.  
  1170.         /// <summary>
  1171.         /// Hermites the specified value1.
  1172.         /// </summary>
  1173.         /// <param name="value1">The value1.</param>
  1174.         /// <param name="tangent1">The tangent1.</param>
  1175.         /// <param name="value2">The value2.</param>
  1176.         /// <param name="tangent2">The tangent2.</param>
  1177.         /// <param name="amount">The amount.</param>
  1178.         /// <returns></returns>
  1179.         public static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount)
  1180.         {
  1181.             float v1 = value1, v2 = value2, t1 = tangent1, t2 = tangent2, s = amount, result;
  1182.             float sCubed = s * s * s;
  1183.             float sSquared = s * s;
  1184.             switch (amount)
  1185.             {
  1186.                 case 0f:
  1187.                     result = value1;
  1188.                     break;
  1189.                 case 1f:
  1190.                     result = value2;
  1191.                     break;
  1192.                 default:
  1193.                     result = (2 * v1 - 2 * v2 + t2 + t1) * sCubed +
  1194.                              (3 * v2 - 3 * v1 - 2 * t1 - t2) * sSquared +
  1195.                              t1 * s +
  1196.                              v1;
  1197.                     break;
  1198.             }
  1199.             return result;
  1200.         }
  1201.  
  1202.         /// <summary>
  1203.         /// Linearly interpolates between two values.
  1204.         /// </summary>
  1205.         /// <param name="value1">Source value.</param>
  1206.         /// <param name="value2">Destination value.</param>
  1207.         /// <param name="amount">Value between 0 and 1 indicating the weight of value2.</param>
  1208.         /// <returns>Interpolated value.</returns>
  1209.         public static float Lerp(float value1, float value2, float amount)
  1210.         {
  1211.             return value1 + (value2 - value1) * amount;
  1212.         }
  1213.  
  1214.         /// <summary>
  1215.         /// Smoothes the step.
  1216.         /// </summary>
  1217.         /// <param name="value1">The value1.</param>
  1218.         /// <param name="value2">The value2.</param>
  1219.         /// <param name="amount">The amount.</param>
  1220.         /// <returns></returns>
  1221.         public static float SmoothStep(float value1, float value2, float amount)
  1222.         {
  1223.             return Hermite(value1, 0f, value2, 0f, Clamp(amount, 0f, 1f));
  1224.         }
  1225.  
  1226.         /// <summary>
  1227.         /// https://en.wikipedia.org/wiki/Pythagorean_theorem
  1228.         /// </summary>
  1229.         /// <param name="a"></param>
  1230.         /// <param name="b"></param>
  1231.         /// <returns></returns>
  1232.         public static float Pythagorean(float a, float b)
  1233.         {
  1234.             return (float)Math.Sqrt((a * a) + (b * b));
  1235.         }
  1236.  
  1237.         /// <summary>
  1238.         ///
  1239.         /// (Hypotenuse² = (Perpendicular² + Base²))
  1240.         ///
  1241.         /// https://en.wikipedia.org/wiki/Pythagorean_theorem
  1242.         /// </summary>
  1243.         /// <param name="a"></param>
  1244.         /// <param name="b"></param>
  1245.         /// <returns></returns>
  1246.         public static int Pythagorean(int a, int b)
  1247.         {
  1248.             return (int)Math.Sqrt((a * a) + (b * b));
  1249.         }
  1250.  
  1251.         /// <summary>
  1252.         ///
  1253.         /// (Hypotenuse² = (Perpendicular² + Base²))
  1254.         ///
  1255.         /// https://en.wikipedia.org/wiki/Pythagorean_theorem
  1256.         /// </summary>
  1257.         /// <param name="a"></param>
  1258.         /// <param name="b"></param>
  1259.         /// <returns></returns>
  1260.         public static double Pythagorean(double a, double b)
  1261.         {
  1262.             return Math.Sqrt((a * a) + (b * b));
  1263.         }
  1264.  
  1265.         /// <summary>
  1266.         /// Finds the center of a specified Rectangle.
  1267.         /// </summary>
  1268.         /// <param name="x"></param>
  1269.         /// <param name="y"></param>
  1270.         /// <param name="width"></param>
  1271.         /// <param name="height"></param>
  1272.         /// <returns></returns>
  1273.         public static Point FindCenter(int x, int y, int width, int height)
  1274.         {
  1275.             return new Point(x + (width / 2), y + (height / 2));
  1276.         }
  1277.  
  1278.         /// <summary>
  1279.         ///
  1280.         /// </summary>
  1281.         /// <param name="x"></param>
  1282.         /// <param name="y"></param>
  1283.         /// <param name="width"></param>
  1284.         /// <param name="height"></param>
  1285.         /// <param name="resultX"></param>
  1286.         /// <param name="resultY"></param>
  1287.         public static void FindCenter(int x, int y, int width, int height, out int resultX, out int resultY)
  1288.         {
  1289.             Point p = FindCenter(x, y, width, height);
  1290.             resultX = p.X;
  1291.             resultY = p.Y;
  1292.         }
  1293.  
  1294.         /// <summary>
  1295.         ///
  1296.         /// </summary>
  1297.         /// <param name="location"></param>
  1298.         /// <param name="quaternion"></param>
  1299.         /// <param name="scale"></param>
  1300.         /// <returns></returns>
  1301.         public static Matrix CreateEntityMatrix(Vector3 location, Quaternion quaternion, Vector3 scale)
  1302.         {
  1303.             return
  1304.                 Matrix.Scaling(scale) *
  1305.                 Matrix.RotationQuaternion(quaternion) *
  1306.                 Matrix.Translation(location);
  1307.         }
  1308.  
  1309.         /// <summary>
  1310.         /// Converts a given bool to either 1 or 0.
  1311.         /// </summary>
  1312.         /// <param name="value"></param>
  1313.         /// <returns></returns>
  1314.         public static int BoolToInt(bool value)
  1315.         {
  1316.             return value ? 1 : 0;
  1317.         }
  1318.  
  1319.         /// <summary>
  1320.         /// Converts a given integer to a boolean value.
  1321.         /// if the value is zero or negative, this returns false.
  1322.         /// If the value is 1 or more, this returns true;
  1323.         /// </summary>
  1324.         /// <param name="integer"></param>
  1325.         /// <returns></returns>
  1326.         public static bool IntToBool(int integer)
  1327.         {
  1328.             return integer > 0;
  1329.         }
  1330.  
  1331.  
  1332.  
  1333.         /// <summary>
  1334.         /// Calculates a Cardinal Direction from a given degree of
  1335.         /// rotation. If no direction can be calculated, this function
  1336.         /// returns CardinalDirectionType.None.
  1337.         /// </summary>
  1338.         /// <param name="degrees"></param>
  1339.         /// <returns></returns>
  1340.         public static CardinalDirection GetCardinalDirection(float degrees)
  1341.         {
  1342.             float rot = degrees % 360;
  1343.             if (rot < 0f)
  1344.             {
  1345.                 rot += 360.0f;
  1346.             }
  1347.             if (0f <= rot && rot < 22.5)
  1348.             {
  1349.                 return CardinalDirection.North;
  1350.             }
  1351.             if (22.5f <= rot && rot < 67.5f)
  1352.             {
  1353.                 return CardinalDirection.NorthEast;
  1354.             }
  1355.             if (67.5f <= rot && rot < 112.5f)
  1356.             {
  1357.                 return CardinalDirection.East;
  1358.             }
  1359.             if (112.5f <= rot && rot < 157.5f)
  1360.             {
  1361.                 return CardinalDirection.SouthEast;
  1362.             }
  1363.             if (157.5f <= rot && rot < 202.5f)
  1364.             {
  1365.                 return CardinalDirection.South;
  1366.             }
  1367.             if (202.5f <= rot && rot < 247.5f)
  1368.             {
  1369.                 return CardinalDirection.SouthWest;
  1370.             }
  1371.             if (247.5f <= rot && rot < 292.5f)
  1372.             {
  1373.                 return CardinalDirection.West;
  1374.             }
  1375.             if (292.5f <= rot && rot < 337.5f)
  1376.             {
  1377.                 return CardinalDirection.NorthWest;
  1378.             }
  1379.             if (337.5f <= rot && rot < 360.0f)
  1380.             {
  1381.                 return CardinalDirection.North;
  1382.             }
  1383.             return CardinalDirection.None;
  1384.         }
  1385.     }
  1386. }
  1387.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement