| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 | /** * Copyright(c) Live2D Inc. All rights reserved. * * Use of this source code is governed by the Live2D Open Software license * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. */using Live2D.Cubism.Core;using UnityEngine;namespace Live2D.Cubism.Framework.Physics{    /// <summary>    /// Math utilities for physics.    /// </summary>    internal static class CubismPhysicsMath    {        /// <summary>        /// Gets radian from degrees.        /// </summary>        /// <param name="degrees">Degrees.</param>        /// <returns>Radian.</returns>        public static float DegreesToRadian(float degrees)        {            return (degrees / 180.0f) * Mathf.PI;        }        /// <summary>        /// Gets degrees from radian.        /// </summary>        /// <param name="radian">Radian.</param>        /// <returns>Degrees.</returns>        public static float RadianToDegrees(float radian)        {            return (radian * 180.0f) / Mathf.PI;        }        /// <summary>        /// Gets angle from both vector direction.        /// </summary>        /// <param name="from">From vector.</param>        /// <param name="to">To vector.</param>        /// <returns>Angle of radian.</returns>        public static float DirectionToRadian(Vector2 from, Vector2 to)        {            var q1 = Mathf.Atan2(to.y, to.x);            var q2 = Mathf.Atan2(from.y, from.x);            return GetAngleDiff(q1, q2);        }        /// <summary>        /// Gets difference of angle.        /// </summary>        /// <param name="q1"></param>        /// <param name="q2"></param>        /// <returns></returns>        public static float GetAngleDiff(float q1, float q2)        {            var ret = q1 - q2;            while (ret < -Mathf.PI)            {                ret += (Mathf.PI * 2.0f);            }            while (ret > Mathf.PI)            {                ret -= (Mathf.PI * 2.0f);            }            return ret;        }        /// <summary>    /// Gets angle from both vector direction.    /// </summary>    /// <param name="from">From vector.</param>    /// <param name="to">To vector.</param>    /// <returns>Angle of degrees.</returns>    public static float DirectionToDegrees(Vector2 from, Vector2 to)        {            var radian = DirectionToRadian(from, to);            var degree = (float)RadianToDegrees(radian);            if ((to.x - from.x) > 0.0f)            {                degree = -degree;            }            return degree;        }        /// <summary>        /// Gets vector direction from angle.        /// </summary>        /// <param name="totalAngle">Radian.</param>        /// <returns>Direction of vector.</returns>        public static Vector2 RadianToDirection(float totalAngle)        {            var ret = Vector2.zero;            ret.x = Mathf.Sin(totalAngle);            ret.y = (float)Mathf.Cos(totalAngle);            return ret;        }        /// <summary>        /// Gets range of value.        /// </summary>        /// <param name="min">Minimum value.</param>        /// <param name="max">Maximum value.</param>        /// <returns></returns>        private static float GetRangeValue(float min, float max)        {            var maxValue = Mathf.Max(min, max);            var minValue = Mathf.Min(min, max);            return Mathf.Abs(maxValue - minValue);        }        /// <summary>        /// Gets middle value.        /// </summary>        /// <param name="min">Minimum value.</param>        /// <param name="max">Maximum value.</param>        /// <returns></returns>        private static float GetDefaultValue(float min, float max)        {            var minValue = Mathf.Min(min, max);            return minValue + (GetRangeValue(min, max) / 2.0f);        }        /// <summary>        /// Normalize parameter value.        /// </summary>        /// <param name="parameter">Target parameter.</param>        /// <param name="normalizedMinimum">Value of normalized minimum.</param>        /// <param name="normalizedMaximum">Value of normalized maximum.</param>        /// <param name="normalizedDefault">Value of normalized default.</param>        /// <param name="isInverted">True if input is inverted; otherwise.</param>        /// <returns></returns>        public static float Normalize(CubismParameter parameter,            float normalizedMinimum,            float normalizedMaximum,            float normalizedDefault,            bool isInverted = false)        {            var result = 0.0f;            var maxValue = Mathf.Max(parameter.MaximumValue, parameter.MinimumValue);            if (maxValue < parameter.Value)            {                parameter.Value = maxValue;            }            var minValue = Mathf.Min(parameter.MaximumValue, parameter.MinimumValue);            if (minValue > parameter.Value)            {                parameter.Value = minValue;            }            var minNormValue = Mathf.Min(normalizedMinimum, normalizedMaximum);            var maxNormValue = Mathf.Max(normalizedMinimum, normalizedMaximum);            var middleNormValue = normalizedDefault;            var middleValue = GetDefaultValue(minValue, maxValue);            var paramValue = parameter.Value - middleValue;            switch ((int)Mathf.Sign(paramValue))            {                case 1:                    {                        var nLength = maxNormValue - middleNormValue;                        var pLength = maxValue - middleValue;                        if (pLength != 0.0f)                        {                            result = paramValue * (nLength / pLength);                            result += middleNormValue;                        }                        break;                    }                case -1:                    {                        var nLength = minNormValue - middleNormValue;                        var pLength = minValue - middleValue;                        if (pLength != 0.0f)                        {                            result = paramValue * (nLength / pLength);                            result += middleNormValue;                        }                        break;                    }                case 0:                    {                        result = middleNormValue;                        break;                    }            }            return (isInverted) ? result : (result * -1.0f);        }    }}
 |