CubismPhysicsMath.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * Copyright(c) Live2D Inc. All rights reserved.
  3. *
  4. * Use of this source code is governed by the Live2D Open Software license
  5. * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
  6. */
  7. using Live2D.Cubism.Core;
  8. using UnityEngine;
  9. namespace Live2D.Cubism.Framework.Physics
  10. {
  11. /// <summary>
  12. /// Math utilities for physics.
  13. /// </summary>
  14. internal static class CubismPhysicsMath
  15. {
  16. /// <summary>
  17. /// Gets radian from degrees.
  18. /// </summary>
  19. /// <param name="degrees">Degrees.</param>
  20. /// <returns>Radian.</returns>
  21. public static float DegreesToRadian(float degrees)
  22. {
  23. return (degrees / 180.0f) * Mathf.PI;
  24. }
  25. /// <summary>
  26. /// Gets degrees from radian.
  27. /// </summary>
  28. /// <param name="radian">Radian.</param>
  29. /// <returns>Degrees.</returns>
  30. public static float RadianToDegrees(float radian)
  31. {
  32. return (radian * 180.0f) / Mathf.PI;
  33. }
  34. /// <summary>
  35. /// Gets angle from both vector direction.
  36. /// </summary>
  37. /// <param name="from">From vector.</param>
  38. /// <param name="to">To vector.</param>
  39. /// <returns>Angle of radian.</returns>
  40. public static float DirectionToRadian(Vector2 from, Vector2 to)
  41. {
  42. var q1 = Mathf.Atan2(to.y, to.x);
  43. var q2 = Mathf.Atan2(from.y, from.x);
  44. return GetAngleDiff(q1, q2);
  45. }
  46. /// <summary>
  47. /// Gets difference of angle.
  48. /// </summary>
  49. /// <param name="q1"></param>
  50. /// <param name="q2"></param>
  51. /// <returns></returns>
  52. public static float GetAngleDiff(float q1, float q2)
  53. {
  54. var ret = q1 - q2;
  55. while (ret < -Mathf.PI)
  56. {
  57. ret += (Mathf.PI * 2.0f);
  58. }
  59. while (ret > Mathf.PI)
  60. {
  61. ret -= (Mathf.PI * 2.0f);
  62. }
  63. return ret;
  64. }
  65. /// <summary>
  66. /// Gets angle from both vector direction.
  67. /// </summary>
  68. /// <param name="from">From vector.</param>
  69. /// <param name="to">To vector.</param>
  70. /// <returns>Angle of degrees.</returns>
  71. public static float DirectionToDegrees(Vector2 from, Vector2 to)
  72. {
  73. var radian = DirectionToRadian(from, to);
  74. var degree = (float)RadianToDegrees(radian);
  75. if ((to.x - from.x) > 0.0f)
  76. {
  77. degree = -degree;
  78. }
  79. return degree;
  80. }
  81. /// <summary>
  82. /// Gets vector direction from angle.
  83. /// </summary>
  84. /// <param name="totalAngle">Radian.</param>
  85. /// <returns>Direction of vector.</returns>
  86. public static Vector2 RadianToDirection(float totalAngle)
  87. {
  88. var ret = Vector2.zero;
  89. ret.x = Mathf.Sin(totalAngle);
  90. ret.y = (float)Mathf.Cos(totalAngle);
  91. return ret;
  92. }
  93. /// <summary>
  94. /// Gets range of value.
  95. /// </summary>
  96. /// <param name="min">Minimum value.</param>
  97. /// <param name="max">Maximum value.</param>
  98. /// <returns></returns>
  99. private static float GetRangeValue(float min, float max)
  100. {
  101. var maxValue = Mathf.Max(min, max);
  102. var minValue = Mathf.Min(min, max);
  103. return Mathf.Abs(maxValue - minValue);
  104. }
  105. /// <summary>
  106. /// Gets middle value.
  107. /// </summary>
  108. /// <param name="min">Minimum value.</param>
  109. /// <param name="max">Maximum value.</param>
  110. /// <returns></returns>
  111. private static float GetDefaultValue(float min, float max)
  112. {
  113. var minValue = Mathf.Min(min, max);
  114. return minValue + (GetRangeValue(min, max) / 2.0f);
  115. }
  116. /// <summary>
  117. /// Normalize parameter value.
  118. /// </summary>
  119. /// <param name="parameter">Target parameter.</param>
  120. /// <param name="parameterValue">Target parameter Value.</param>
  121. /// <param name="normalizedMinimum">Value of normalized minimum.</param>
  122. /// <param name="normalizedMaximum">Value of normalized maximum.</param>
  123. /// <param name="normalizedDefault">Value of normalized default.</param>
  124. /// <param name="isInverted">True if input is inverted; otherwise.</param>
  125. /// <returns></returns>
  126. public static float Normalize(CubismParameter parameter,
  127. ref float parameterValue,
  128. float normalizedMinimum,
  129. float normalizedMaximum,
  130. float normalizedDefault,
  131. bool isInverted = false)
  132. {
  133. var result = 0.0f;
  134. var maxValue = Mathf.Max(parameter.MaximumValue, parameter.MinimumValue);
  135. if (maxValue < parameterValue)
  136. {
  137. parameterValue = maxValue;
  138. }
  139. var minValue = Mathf.Min(parameter.MaximumValue, parameter.MinimumValue);
  140. if (minValue > parameterValue)
  141. {
  142. parameterValue = minValue;
  143. }
  144. var minNormValue = Mathf.Min(normalizedMinimum, normalizedMaximum);
  145. var maxNormValue = Mathf.Max(normalizedMinimum, normalizedMaximum);
  146. var middleNormValue = normalizedDefault;
  147. var middleValue = GetDefaultValue(minValue, maxValue);
  148. var paramValue = parameterValue - middleValue;
  149. switch ((int)Mathf.Sign(paramValue))
  150. {
  151. case 1:
  152. {
  153. var nLength = maxNormValue - middleNormValue;
  154. var pLength = maxValue - middleValue;
  155. if (pLength != 0.0f)
  156. {
  157. result = paramValue * (nLength / pLength);
  158. result += middleNormValue;
  159. }
  160. break;
  161. }
  162. case -1:
  163. {
  164. var nLength = minNormValue - middleNormValue;
  165. var pLength = minValue - middleValue;
  166. if (pLength != 0.0f)
  167. {
  168. result = paramValue * (nLength / pLength);
  169. result += middleNormValue;
  170. }
  171. break;
  172. }
  173. case 0:
  174. {
  175. result = middleNormValue;
  176. break;
  177. }
  178. }
  179. return (isInverted) ? result : (result * -1.0f);
  180. }
  181. }
  182. }