Skip to content

Commit fe6af7a

Browse files
committed
Use AnimationSet to group animations with appeals
1 parent d1f8572 commit fe6af7a

6 files changed

Lines changed: 115 additions & 19 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using JetBrains.Annotations;
2+
using OpenMLTD.MillionDance.Entities.Internal;
3+
4+
namespace OpenMLTD.MillionDance.Entities.Extensions {
5+
internal static class AnimationSetExtensions {
6+
7+
public static void Deconstruct<T>([NotNull] this AnimationSet<T> animationSet, [CanBeNull] out T @default, [CanBeNull] out T another, [CanBeNull] out T special) {
8+
@default = animationSet.Default;
9+
another = animationSet.Another;
10+
special = animationSet.Special;
11+
}
12+
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using JetBrains.Annotations;
2+
3+
namespace OpenMLTD.MillionDance.Entities.Internal {
4+
internal static class AnimationSet {
5+
6+
[NotNull]
7+
public static AnimationSet<T> Create<T>([CanBeNull] T @default, [CanBeNull] T another, [CanBeNull] T special) {
8+
return new AnimationSet<T>(@default, another, special);
9+
}
10+
11+
}
12+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System.Diagnostics;
2+
using JetBrains.Annotations;
3+
4+
namespace OpenMLTD.MillionDance.Entities.Internal {
5+
/// <summary>
6+
/// A set of animations
7+
/// </summary>
8+
/// <typeparam name="T">The type containing animation data</typeparam>
9+
internal sealed class AnimationSet<T> {
10+
11+
public AnimationSet([CanBeNull] T @default, [CanBeNull] T another, [CanBeNull] T special) {
12+
Default = @default;
13+
Special = special;
14+
Another = another;
15+
}
16+
17+
/// <summary>
18+
/// Default animations
19+
/// </summary>
20+
[CanBeNull]
21+
public T Default {
22+
[DebuggerStepThrough]
23+
get;
24+
}
25+
26+
/// <summary>
27+
/// Animations for another appeal (apa)
28+
/// </summary>
29+
[CanBeNull]
30+
public T Another {
31+
[DebuggerStepThrough]
32+
get;
33+
}
34+
35+
/// <summary>
36+
/// Animations for special appeal (apg)
37+
/// </summary>
38+
[CanBeNull]
39+
public T Special {
40+
[DebuggerStepThrough]
41+
get;
42+
}
43+
44+
}
45+
}

src/MillionDance/FMain.Working.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ ConversionConfig PrepareConversionConfig(InputParams ip) {
225225

226226
if (p.GenerateCameraMotion) {
227227
Log("Loading camera motion...");
228-
camera = ResourceLoader.LoadCamera(p.InputCamera);
228+
(camera, _, _) = ResourceLoader.LoadCamera(p.InputCamera);
229229
if (camera == null) {
230230
Log("Failed to load camera data.");
231231
break;

src/MillionDance/MillionDance.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,12 @@
7777
<Compile Include="Core\VmdCreator.FacialExpressions.cs" />
7878
<Compile Include="Core\VmdCreator.FacialExpressionTable.cs" />
7979
<Compile Include="Core\VmdCreator.Light.cs" />
80+
<Compile Include="Entities\Extensions\AnimationSetExtensions.cs" />
8081
<Compile Include="Entities\Extensions\KeyTypeExtension.cs" />
8182
<Compile Include="Entities\Extensions\PropertyTypeExtension.cs" />
8283
<Compile Include="Entities\Extensions\ScenarioObjectExtensions.cs" />
84+
<Compile Include="Entities\Internal\AnimationSet.cs" />
85+
<Compile Include="Entities\Internal\AnimationSet`1.cs" />
8386
<Compile Include="Entities\Internal\CameraAnimation.cs" />
8487
<Compile Include="Entities\Internal\CameraFrame.cs" />
8588
<Compile Include="Entities\Mltd\CompiledBodyAnimationSource.cs" />

src/MillionDance/ResourceLoader.cs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
using Imas.Data.Serialized.Sway;
1010
using JetBrains.Annotations;
1111
using OpenMLTD.MillionDance.Core;
12+
using OpenMLTD.MillionDance.Entities.Extensions;
13+
using OpenMLTD.MillionDance.Entities.Internal;
1214
using OpenMLTD.MillionDance.Entities.Mltd;
1315

1416
namespace OpenMLTD.MillionDance {
@@ -127,15 +129,21 @@ public static AvatarWrapper LoadHeadAvatar([NotNull] string filePath) {
127129
return result;
128130
}
129131

130-
[CanBeNull]
131-
public static CharacterImasMotionAsset LoadCamera([NotNull] string filePath) {
132-
CharacterImasMotionAsset cam = null;
132+
[NotNull]
133+
public static AnimationSet<CharacterImasMotionAsset> LoadCamera([NotNull] string filePath) {
134+
CharacterImasMotionAsset cam = null, apa = null, apg = null;
133135

134-
const string camEnds = "_cam.imo";
136+
const string defCamEnds = "_cam.imo";
137+
const string apaCamEnds = "_apa.imo";
138+
const string apgCamEnds = "_apg.imo";
139+
const string apaPortraitCamEnds = "_tate_apa.imo";
140+
const string apgPortraitCamEnds = "_tate_apg.imo";
135141

136142
var manager = new AssetsManager();
137143
manager.LoadFiles(filePath);
138144

145+
var ser = new ScriptableObjectSerializer();
146+
139147
foreach (var assetFile in manager.assetsFileList) {
140148
foreach (var obj in assetFile.Objects) {
141149
if (obj.type != ClassIDType.MonoBehaviour) {
@@ -148,22 +156,25 @@ public static CharacterImasMotionAsset LoadCamera([NotNull] string filePath) {
148156
throw new ArgumentException("An object serialized as MonoBehaviour is actually not a MonoBehaviour.");
149157
}
150158

151-
if (!behaviour.m_Name.EndsWith(camEnds)) {
152-
continue;
159+
if (behaviour.m_Name.EndsWith(defCamEnds)) {
160+
cam = ser.Deserialize<CharacterImasMotionAsset>(behaviour);
161+
} else if (behaviour.m_Name.EndsWith(apaCamEnds) && !behaviour.m_Name.EndsWith(apaPortraitCamEnds)) {
162+
apa = ser.Deserialize<CharacterImasMotionAsset>(behaviour);
163+
} else if (behaviour.m_Name.EndsWith(apgCamEnds) && !behaviour.m_Name.EndsWith(apgPortraitCamEnds)) {
164+
apg = ser.Deserialize<CharacterImasMotionAsset>(behaviour);
153165
}
154166

155-
var ser = new ScriptableObjectSerializer();
156-
157-
cam = ser.Deserialize<CharacterImasMotionAsset>(behaviour);
158-
159-
break;
167+
if (cam != null && apa != null && apg != null) {
168+
break;
169+
}
160170
}
161171
}
162172

163-
return cam;
173+
return AnimationSet.Create(cam, apa, apg);
164174
}
165175

166-
public static (IBodyAnimationSource, IBodyAnimationSource, IBodyAnimationSource) LoadDance([NotNull] string filePath, int songPosition) {
176+
[NotNull]
177+
public static AnimationSet<IBodyAnimationSource> LoadDance([NotNull] string filePath, int songPosition) {
167178
IBodyAnimationSource danSource = null, apaSource = null, apgSource = null;
168179
var danceAnimationLoaded = false;
169180

@@ -211,7 +222,7 @@ public static (IBodyAnimationSource, IBodyAnimationSource, IBodyAnimationSource)
211222
}
212223
}
213224

214-
return (danSource, apaSource, apgSource);
225+
return AnimationSet.Create(danSource, apaSource, apgSource);
215226
}
216227

217228
public static (ScenarioObject, ScenarioObject, ScenarioObject) LoadScenario([NotNull] string filePath) {
@@ -255,7 +266,8 @@ public static (ScenarioObject, ScenarioObject, ScenarioObject) LoadScenario([Not
255266
return (main, landscape, portrait);
256267
}
257268

258-
private static (CharacterImasMotionAsset, CharacterImasMotionAsset, CharacterImasMotionAsset) LoadDanceLegacy([NotNull] string filePath, int songPosition) {
269+
[NotNull]
270+
private static AnimationSet<CharacterImasMotionAsset> LoadDanceLegacy([NotNull] string filePath, int songPosition) {
259271
CharacterImasMotionAsset dan = null, apa = null, apg = null;
260272

261273
var danComp = $"{songPosition:00}_dan.imo";
@@ -294,10 +306,11 @@ private static (CharacterImasMotionAsset, CharacterImasMotionAsset, CharacterIma
294306
}
295307
}
296308

297-
return (dan, apa, apg);
309+
return AnimationSet.Create(dan, apa, apg);
298310
}
299311

300-
private static (AnimationClip, AnimationClip, AnimationClip) LoadDanceCompiled([NotNull] string filePath, int songPosition) {
312+
[NotNull]
313+
private static AnimationSet<AnimationClip> LoadDanceCompiled([NotNull] string filePath, int songPosition) {
301314
AnimationClip dan = null, apa = null, apg = null;
302315

303316
var danComp = $"{songPosition:00}_dan";
@@ -333,13 +346,22 @@ private static (AnimationClip, AnimationClip, AnimationClip) LoadDanceCompiled([
333346
}
334347
}
335348

336-
return (dan, apa, apg);
349+
return AnimationSet.Create(dan, apa, apg);
337350
}
338351

339352
public static (SwayController Body, SwayController Head) LoadSwayControllers([NotNull] string bodyFilePath, [NotNull] string headFilePath) {
340353
var body = LoadSwayController(bodyFilePath);
354+
355+
if (body == null) {
356+
throw new ArgumentNullException(nameof(body), "Body sway is null.");
357+
}
358+
341359
var head = LoadSwayController(headFilePath);
342360

361+
if (head == null) {
362+
throw new ArgumentNullException(nameof(head), "Head sway is null.");
363+
}
364+
343365
SwayController.FixSwayReferences(body, head);
344366

345367
return (Body: body, Head: head);

0 commit comments

Comments
 (0)