Skip to content

Commit 36e2665

Browse files
Merge pull request #61 from Live2D/develop
Cubism 4 SDK for Unity R5 beta3
2 parents 829c156 + eee4752 commit 36e2665

12 files changed

Lines changed: 226 additions & 50 deletions

File tree

Assets/Live2D/Cubism/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77

8+
## [4-r.5-beta.3] - 2022-06-16
9+
10+
### Changed
11+
12+
* Change the version of the development project to `2019.4.39f1`.
13+
14+
### Fixed
15+
16+
* Fix physics system behaviour when exists Physics Fps Setting in .physics3.json.
17+
18+
819
## [4-r.5-beta.2] - 2022-06-02
920

1021
### Fixed
@@ -184,6 +195,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
184195
* Fix issue where Priority value was not reset after playing motion with CubismMotionController.
185196

186197

198+
[4-r.5-beta.3]: https://github.com/Live2D/CubismUnityComponents/compare/4-r.5-beta.2...4-r.5-beta.3
187199
[4-r.5-beta.2]: https://github.com/Live2D/CubismUnityComponents/compare/4-r.5-beta.1...4-r.5-beta.2
188200
[4-r.5-beta.1]: https://github.com/Live2D/CubismUnityComponents/compare/4-r.4.2...4-r.5-beta.1
189201
[4-r.4.2]: https://github.com/Live2D/CubismUnityComponents/compare/4-r.4.1...4-r.4.2

Assets/Live2D/Cubism/Framework/Json/CubismPhysics3Json.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public CubismPhysicsRig ToRig()
5151
instance.Wind.x = Meta.EffectiveForces.Wind.X;
5252
instance.Wind.y = Meta.EffectiveForces.Wind.Y;
5353

54+
instance.Fps = Meta.Fps;
5455

5556
instance.SubRigs = new CubismPhysicsSubRig[Meta.PhysicsSettingCount];
5657

@@ -463,6 +464,13 @@ public struct SerializableMeta
463464
/// </summary>
464465
[SerializeField]
465466
public SerializableEffectiveForces EffectiveForces;
467+
468+
/// <summary>
469+
/// [Optional] Fps of physics operations.
470+
/// If the value is not set to Json, it will change according to the application's operating FPS.
471+
/// </summary>
472+
[SerializeField]
473+
public float Fps;
466474
}
467475

468476

Assets/Live2D/Cubism/Framework/Physics/CubismPhysics.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,8 @@ public static class CubismPhysics
5050
/// Threshold of moving.
5151
/// </summary>
5252
public const float MovementThreshold = 0.001f;
53+
54+
/// Constant of maximum allowed delta time
55+
public const float MaxDeltaTime = 5.0f;
5356
}
5457
}

Assets/Live2D/Cubism/Framework/Physics/CubismPhysicsInput.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ public struct CubismPhysicsInput
2525
/// <param name="targetTranslation">Result of translation.</param>
2626
/// <param name="targetAngle">Result of rotation.</param>
2727
/// <param name="parameter">Parameter.</param>
28+
/// <param name="parameterValue">Parameter value.</param>
2829
/// <param name="normalization">Normalized components.</param>
2930
/// <param name="weight">Weight.</param>
3031
public delegate void NormalizedParameterValueGetter(
3132
ref Vector2 targetTranslation,
3233
ref float targetAngle,
3334
CubismParameter parameter,
35+
ref float parameterValue,
3436
CubismPhysicsNormalization normalization,
3537
float weight
3638
);
@@ -41,18 +43,21 @@ float weight
4143
/// <param name="targetTranslation">Result of translation.</param>
4244
/// <param name="targetAngle">Result of rotation.</param>
4345
/// <param name="parameter">Parameter.</param>
46+
/// <param name="parameterValue">Parameter value.</param>
4447
/// <param name="normalization">Normalized components.</param>
4548
/// <param name="weight">Weight.</param>
4649
private void GetInputTranslationXFromNormalizedParameterValue(
4750
ref Vector2 targetTranslation,
4851
ref float targetAngle,
4952
CubismParameter parameter,
53+
ref float parameterValue,
5054
CubismPhysicsNormalization normalization,
5155
float weight
5256
)
5357
{
5458
targetTranslation.x += CubismPhysicsMath.Normalize(
5559
parameter,
60+
ref parameterValue,
5661
normalization.Position.Minimum,
5762
normalization.Position.Maximum,
5863
normalization.Position.Default,
@@ -66,18 +71,21 @@ float weight
6671
/// <param name="targetTranslation">Result of translation.</param>
6772
/// <param name="targetAngle">Result of rotation.</param>
6873
/// <param name="parameter">Parameter.</param>
74+
/// <param name="parameterValue">Parameter value.</param>
6975
/// <param name="normalization">Normalized components.</param>
7076
/// <param name="weight">Weight.</param>
7177
private void GetInputTranslationYFromNormalizedParameterValue(
7278
ref Vector2 targetTranslation,
7379
ref float targetAngle,
7480
CubismParameter parameter,
81+
ref float parameterValue,
7582
CubismPhysicsNormalization normalization,
7683
float weight
7784
)
7885
{
7986
targetTranslation.y += CubismPhysicsMath.Normalize(
8087
parameter,
88+
ref parameterValue,
8189
normalization.Position.Minimum,
8290
normalization.Position.Maximum,
8391
normalization.Position.Default,
@@ -91,18 +99,21 @@ float weight
9199
/// <param name="targetTranslation">Result of translation.</param>
92100
/// <param name="targetAngle">Result of rotation.</param>
93101
/// <param name="parameter">Parameter.</param>
102+
/// <param name="parameterValue">Parameter value.</param>
94103
/// <param name="normalization">Normalized components.</param>
95104
/// <param name="weight">Weight.</param>
96105
private void GetInputAngleFromNormalizedParameterValue(
97106
ref Vector2 targetTranslation,
98107
ref float targetAngle,
99108
CubismParameter parameter,
109+
ref float parameterValue,
100110
CubismPhysicsNormalization normalization,
101111
float weight
102112
)
103113
{
104114
targetAngle += CubismPhysicsMath.Normalize(
105115
parameter,
116+
ref parameterValue,
106117
normalization.Angle.Minimum,
107118
normalization.Angle.Maximum,
108119
normalization.Angle.Default,

Assets/Live2D/Cubism/Framework/Physics/CubismPhysicsMath.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,14 @@ private static float GetDefaultValue(float min, float max)
147147
/// Normalize parameter value.
148148
/// </summary>
149149
/// <param name="parameter">Target parameter.</param>
150+
/// <param name="parameterValue">Target parameter Value.</param>
150151
/// <param name="normalizedMinimum">Value of normalized minimum.</param>
151152
/// <param name="normalizedMaximum">Value of normalized maximum.</param>
152153
/// <param name="normalizedDefault">Value of normalized default.</param>
153154
/// <param name="isInverted">True if input is inverted; otherwise.</param>
154155
/// <returns></returns>
155156
public static float Normalize(CubismParameter parameter,
157+
ref float parameterValue,
156158
float normalizedMinimum,
157159
float normalizedMaximum,
158160
float normalizedDefault,
@@ -162,23 +164,23 @@ public static float Normalize(CubismParameter parameter,
162164

163165
var maxValue = Mathf.Max(parameter.MaximumValue, parameter.MinimumValue);
164166

165-
if (maxValue < parameter.Value)
167+
if (maxValue < parameterValue)
166168
{
167-
parameter.Value = maxValue;
169+
parameterValue = maxValue;
168170
}
169171

170172
var minValue = Mathf.Min(parameter.MaximumValue, parameter.MinimumValue);
171-
if (minValue > parameter.Value)
173+
if (minValue > parameterValue)
172174
{
173-
parameter.Value = minValue;
175+
parameterValue = minValue;
174176
}
175177

176178
var minNormValue = Mathf.Min(normalizedMinimum, normalizedMaximum);
177179
var maxNormValue = Mathf.Max(normalizedMinimum, normalizedMaximum);
178180
var middleNormValue = normalizedDefault;
179181

180182
var middleValue = GetDefaultValue(minValue, maxValue);
181-
var paramValue = parameter.Value - middleValue;
183+
var paramValue = parameterValue - middleValue;
182184

183185
switch ((int)Mathf.Sign(paramValue))
184186
{

Assets/Live2D/Cubism/Framework/Physics/CubismPhysicsOutput.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@ public struct CubismPhysicsOutput
2323
/// Delegation of function of getting output value.
2424
/// </summary>
2525
/// <param name="translation">Translation.</param>
26-
/// <param name="parameter">Parameter.</param>
2726
/// <param name="particles">Particles.</param>
2827
/// <param name="particleIndex">Index of particle.</param>
2928
/// <param name="gravity">Gravity.</param>
3029
/// <returns>Output value.</returns>
3130
public delegate float ValueGetter(
3231
Vector2 translation,
33-
CubismParameter parameter,
3432
CubismPhysicsParticle[] particles,
3533
int particleIndex,
3634
Vector2 gravity
@@ -42,19 +40,16 @@ Vector2 gravity
4240
/// <returns>Output scale.</returns>
4341
public delegate float ScaleGetter();
4442

45-
4643
/// <summary>
4744
/// Gets output for translation X-axis.
4845
/// </summary>
4946
/// <param name="translation">Translation.</param>
50-
/// <param name="parameter">Parameter.</param>
5147
/// <param name="particles">Particles.</param>
5248
/// <param name="particleIndex">Index of particle.</param>
5349
/// <param name="gravity">Gravity.</param>
5450
/// <returns>Output value.</returns>
5551
private float GetOutputTranslationX(
5652
Vector2 translation,
57-
CubismParameter parameter,
5853
CubismPhysicsParticle[] particles,
5954
int particleIndex,
6055
Vector2 gravity
@@ -74,14 +69,12 @@ Vector2 gravity
7469
/// Gets output for translation Y-axis.
7570
/// </summary>
7671
/// <param name="translation">Translation.</param>
77-
/// <param name="parameter">Parameter.</param>
7872
/// <param name="particles">Particles.</param>
7973
/// <param name="particleIndex">Index of particle.</param>
8074
/// <param name="gravity">Gravity.</param>
8175
/// <returns>Output value.</returns>
8276
private float GetOutputTranslationY(
8377
Vector2 translation,
84-
CubismParameter parameter,
8578
CubismPhysicsParticle[] particles,
8679
int particleIndex,
8780
Vector2 gravity
@@ -101,14 +94,12 @@ Vector2 gravity
10194
/// Gets output for angle.
10295
/// </summary>
10396
/// <param name="translation">Translation.</param>
104-
/// <param name="parameter">Parameter.</param>
10597
/// <param name="particles">Particles.</param>
10698
/// <param name="particleIndex">Index of particle.</param>
10799
/// <param name="gravity">Gravity.</param>
108100
/// <returns>Output value.</returns>
109101
private float GetOutputAngle(
110102
Vector2 translation,
111-
CubismParameter parameter,
112103
CubismPhysicsParticle[] particles,
113104
int particleIndex,
114105
Vector2 gravity
@@ -148,7 +139,6 @@ Vector2 gravity
148139
return outputValue;
149140
}
150141

151-
152142
/// <summary>
153143
/// Gets output scale for translation X-axis.
154144
/// </summary>

Assets/Live2D/Cubism/Framework/Physics/CubismPhysicsRig.cs

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88

99
using System;
10+
using Live2D.Cubism.Core;
1011
using UnityEngine;
1112

1213

@@ -32,18 +33,37 @@ public class CubismPhysicsRig
3233
[SerializeField]
3334
public Vector2 Wind = CubismPhysics.Wind;
3435

36+
[SerializeField]
37+
public float Fps = 0.0f;
38+
39+
40+
private float _currentRemainTime; // Time not processed by physics.
41+
42+
public float[] ParametersCache
43+
{
44+
get { return _parametersCache; }
45+
set { _parametersCache = value; }
46+
}
47+
48+
[NonSerialized]
49+
private float[] _parametersCache; // Cache parameters used by Evaluate.
3550

3651
/// <summary>
3752
/// Reference of controller to refer from children rig.
3853
/// </summary>
3954
public CubismPhysicsController Controller { get; set; }
4055

41-
4256
/// <summary>
4357
/// Initializes rigs.
4458
/// </summary>
4559
public void Initialize()
4660
{
61+
_currentRemainTime = 0.0f;
62+
63+
Controller.gameObject.FindCubismModel();
64+
65+
_parametersCache = new float[Controller.Parameters.Length];
66+
4767
for (var i = 0; i < SubRigs.Length; ++i)
4868
{
4969
SubRigs[i].Initialize();
@@ -52,13 +72,86 @@ public void Initialize()
5272

5373
/// <summary>
5474
/// Evaluate rigs.
75+
///
76+
/// Pendulum interpolation weights
77+
///
78+
/// The result of the pendulum calculation is saved and
79+
/// the output to the parameters is interpolated with the saved previous result of the pendulum calculation.
80+
///
81+
/// The figure shows the interpolation between [1] and [2].
82+
///
83+
/// The weight of the interpolation are determined by the current time seen between
84+
/// the latest pendulum calculation timing and the next timing.
85+
///
86+
/// Figure shows the weight of position (3) as seen between [2] and [4].
87+
///
88+
/// As an interpretation, the pendulum calculation and weights are misaligned.
89+
///
90+
/// If there is no FPS information in physics3.json, it is always set in the previous pendulum state.
91+
///
92+
/// The purpose of this specification is to avoid the quivering appearance caused by deviations from the interpolation range.
93+
///
94+
/// ------------ time -------------->
95+
///
96+
///         |+++++|------| <- weight
97+
/// ==[1]====#=====[2]---(3)----(4)
98+
/// ^ output contents
99+
///
100+
/// 1: _previousRigOutput
101+
/// 2: _currentRigOutput
102+
/// 3: _currentRemainTime (now rendering)
103+
/// 4: next particles timing
55104
/// </summary>
56105
/// <param name="deltaTime"></param>
57106
public void Evaluate(float deltaTime)
58107
{
108+
if (0.0f >= deltaTime)
109+
{
110+
return;
111+
}
112+
113+
_currentRemainTime += deltaTime;
114+
if (_currentRemainTime > CubismPhysics.MaxDeltaTime)
115+
{
116+
_currentRemainTime = 0.0f;
117+
}
118+
119+
var physicsDeltaTime = 0.0f;
120+
121+
if (Fps > 0.0f)
122+
{
123+
physicsDeltaTime = 1.0f / Fps;
124+
}
125+
else
126+
{
127+
physicsDeltaTime = deltaTime;
128+
}
129+
130+
if (_parametersCache.Length < Controller.Parameters.Length)
131+
{
132+
_parametersCache = new float[Controller.Parameters.Length];
133+
}
134+
135+
while (_currentRemainTime >= physicsDeltaTime)
136+
{
137+
// copy parameter model to cache
138+
for (var i = 0; i < Controller.Parameters.Length; i++)
139+
{
140+
_parametersCache[i] = Controller.Parameters[i].Value;
141+
}
142+
143+
for (var i = 0; i < SubRigs.Length; ++i)
144+
{
145+
SubRigs[i].Evaluate(physicsDeltaTime);
146+
}
147+
148+
_currentRemainTime -= physicsDeltaTime;
149+
}
150+
151+
float alpha = _currentRemainTime / physicsDeltaTime;
59152
for (var i = 0; i < SubRigs.Length; ++i)
60153
{
61-
SubRigs[i].Evaluate(deltaTime);
154+
SubRigs[i].Interpolate(alpha);
62155
}
63156
}
64157
}

0 commit comments

Comments
 (0)