using UnityEngine; using System.Linq.Expressions; using System; namespace UC { public class Math { static public float ofMap(float value, float inputMin, float inputMax, float outputMin, float outputMax, bool clamp = false) { #if true if (Mathf.Abs(inputMin - inputMax) < Mathf.Epsilon) { return outputMin; } else { float outVal = ((value - inputMin) / (inputMax - inputMin) * (outputMax - outputMin) + outputMin); if (clamp) { if (outputMax < outputMin) { if (outVal < outputMax) outVal = outputMax; else if (outVal > outputMin) outVal = outputMin; } else { if (outVal > outputMax) outVal = outputMax; else if (outVal < outputMin) outVal = outputMin; } } return outVal; } #else // unity version return Mathf.Lerp(outputMin, outputMax, Mathf.InverseLerp(inputMin, inputMax, value)); #endif } static public float ofMap(float value, Vector2 inputMinMax, Vector2 outputMinMax, bool clamp = false) { return ofMap(value, inputMinMax.x, inputMinMax.y, outputMinMax.x, outputMinMax.y, clamp); } //////////////////////////////////////////////////////////////////////////////// public static T2 Convert(T1 x) { ParameterExpression pX = Expression.Parameter(typeof(T1), "x"); UnaryExpression body = Expression.Convert(pX, typeof(T2)); return Expression.Lambda>(body, pX).Compile()(x); } public static T Floor(T x) { return Convert(Convert(x)); } public static T Negate(T x) { ParameterExpression pX = Expression.Parameter(typeof(T), "x"); UnaryExpression body = Expression.Negate(pX); return Expression.Lambda>(body, pX).Compile()(x); } //////////////////////////////////////////////////////////////////////////////// public delegate BinaryExpression GeneralOpDel(Expression left, Expression right); public static R GeneralOp(T x, T y, GeneralOpDel expr) { ParameterExpression pX = Expression.Parameter(typeof(T), "x"); ParameterExpression pY = Expression.Parameter(typeof(T), "y"); BinaryExpression body = expr(pX, pY); return Expression.Lambda>(body, pX, pY).Compile()(x, y); } public static T GeneralOp(T x, T y, GeneralOpDel expr) { return GeneralOp(x, y, expr); } public static T Add(T x, T y) { return GeneralOp(x, y, Expression.Add); } public static T Subtract(T x, T y) { return GeneralOp(x, y, Expression.Subtract); } public static T Multiply(T x, T y) { return GeneralOp(x, y, Expression.Multiply); } public static T Divide(T x, T y) { return GeneralOp(x, y, Expression.Divide); } //////////////////////////////////////////////////////////////////////////////// public static bool LessThan(T x, T y) { return GeneralOp(x, y, Expression.LessThan); } public static bool LessThanOrEqual(T x, T y) { return GeneralOp(x, y, Expression.LessThanOrEqual); } public static bool GreaterThan(T x, T y) { return GeneralOp(x, y, Expression.GreaterThan); } public static bool GreaterThanOrEqual(T x, T y) { return GeneralOp(x, y, Expression.GreaterThanOrEqual); } //////////////////////////////////////////////////////////////////////////////// public static T Modulo(T x, T y, bool cut_cornors = false) { T result = GeneralOp(x, y, Expression.Modulo); //T result = Subtract(x, Multiply(y, Floor(Divide(x, y)))); if (cut_cornors) { T half_y = Divide(y, Convert(2)); if (LessThan(result, Negate(half_y))) result = Add(result, y); else if (GreaterThanOrEqual(result, half_y)) result = Subtract(result, y); } return result; } public static float Nearest360(float angle, float comparisonTarget) { return angle + Mathf.Round((comparisonTarget - angle) / 360) * 360; } } }