CubismPhysicsMath.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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="normalizedMinimum">Value of normalized minimum.</param>
  121. /// <param name="normalizedMaximum">Value of normalized maximum.</param>
  122. /// <param name="normalizedDefault">Value of normalized default.</param>
  123. /// <param name="isInverted">True if input is inverted; otherwise.</param>
  124. /// <returns></returns>
  125. public static float Normalize(CubismParameter parameter,
  126. float normalizedMinimum,
  127. float normalizedMaximum,
  128. float normalizedDefault,
  129. bool isInverted = false)
  130. {
  131. var result = 0.0f;
  132. var maxValue = Mathf.Max(parameter.MaximumValue, parameter.MinimumValue);
  133. if (maxValue < parameter.Value)
  134. {
  135. parameter.Value = maxValue;
  136. }
  137. var minValue = Mathf.Min(parameter.MaximumValue, parameter.MinimumValue);
  138. if (minValue > parameter.Value)
  139. {
  140. parameter.Value = minValue;
  141. }
  142. var minNormValue = Mathf.Min(normalizedMinimum, normalizedMaximum);
  143. var maxNormValue = Mathf.Max(normalizedMinimum, normalizedMaximum);
  144. var middleNormValue = normalizedDefault;
  145. var middleValue = GetDefaultValue(minValue, maxValue);
  146. var paramValue = parameter.Value - middleValue;
  147. switch ((int)Mathf.Sign(paramValue))
  148. {
  149. case 1:
  150. {
  151. var nLength = maxNormValue - middleNormValue;
  152. var pLength = maxValue - middleValue;
  153. if (pLength != 0.0f)
  154. {
  155. result = paramValue * (nLength / pLength);
  156. result += middleNormValue;
  157. }
  158. break;
  159. }
  160. case -1:
  161. {
  162. var nLength = minNormValue - middleNormValue;
  163. var pLength = minValue - middleValue;
  164. if (pLength != 0.0f)
  165. {
  166. result = paramValue * (nLength / pLength);
  167. result += middleNormValue;
  168. }
  169. break;
  170. }
  171. case 0:
  172. {
  173. result = middleNormValue;
  174. break;
  175. }
  176. }
  177. return (isInverted) ? result : (result * -1.0f);
  178. }
  179. }
  180. }