/
CubismPhysicsMath.cs
225 lines (180 loc) · 6.52 KB
/
CubismPhysicsMath.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/**
* 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);
}
}
}