Skip to content

Commit 223dd8f

Browse files
committed
multiple anims on same model
1 parent 946d38c commit 223dd8f

File tree

7 files changed

+74
-54
lines changed

7 files changed

+74
-54
lines changed

FModel/MainWindow.xaml.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ await Task.WhenAll(
8585
#if DEBUG
8686
await _threadWorkerView.Begin(cancellationToken =>
8787
_applicationView.CUE4Parse.Extract(cancellationToken,
88-
"Hk_project/Content/Character/Cat/Mesh/SKM_Cat.uasset"));
88+
"ShooterGame/Content/Characters/Guide/S0/3P/Models/TP_Guide_S0_Skelmesh.uasset"));
8989
await _threadWorkerView.Begin(cancellationToken =>
9090
_applicationView.CUE4Parse.Extract(cancellationToken,
91-
"Hk_project/Content/Animation/CAT/Idle/CAT_SitBalledStrechingToStand_Idle.uasset"));
91+
"ShooterGame/Content/Characters/Guide/S0/Ability_Q/3P/Anims/TP_Guide_S0_Q_WolfTotem_Cast_Outro_Montage.uasset"));
9292
#endif
9393
}
9494

@@ -142,7 +142,7 @@ private void OnTabItemChange(object sender, SelectionChangedEventArgs e)
142142

143143
private async void OnMappingsReload(object sender, ExecutedRoutedEventArgs e)
144144
{
145-
await _applicationView.CUE4Parse.InitMappings();
145+
await _applicationView.CUE4Parse.InitMappings(true);
146146
}
147147

148148
private void OnOpenAvalonFinder()

FModel/ViewModels/CUE4ParseViewModel.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ await _threadWorkerView.Begin(cancellationToken =>
351351
});
352352
}
353353

354-
public Task InitMappings()
354+
public Task InitMappings(bool force = false)
355355
{
356356
if (!UserSettings.IsEndpointValid(EEndpointType.Mapping, out var endpoint))
357357
{
@@ -377,7 +377,7 @@ public Task InitMappings()
377377
if (!mapping.IsValid) continue;
378378

379379
var mappingPath = Path.Combine(mappingsFolder, mapping.FileName);
380-
if (!File.Exists(mappingPath))
380+
if (force || !File.Exists(mappingPath))
381381
{
382382
_apiEndpointView.DownloadFile(mapping.Url, mappingPath);
383383
}
@@ -883,8 +883,12 @@ public void ExtractAndScroll(CancellationToken cancellationToken, string fullPat
883883
{
884884
var shouldDecompress = UserSettings.Default.CompressedAudioMode == ECompressedAudio.PlayDecompressed;
885885
export.Decode(shouldDecompress, out var audioFormat, out var data);
886-
if (data == null || string.IsNullOrEmpty(audioFormat) || export.Owner == null)
886+
var hasAf = !string.IsNullOrEmpty(audioFormat);
887+
if (data == null || !hasAf || export.Owner == null)
888+
{
889+
if (hasAf) FLogger.Append(ELog.Warning, () => FLogger.Text($"Unsupported audio format '{audioFormat}'", Constants.WHITE, true));
887890
return false;
891+
}
888892

889893
SaveAndPlaySound(Path.Combine(TabControl.SelectedTab.Directory, TabControl.SelectedTab.Header.SubstringBeforeLast('.')).Replace('\\', '/'), audioFormat, data);
890894
return false;

FModel/Views/Snooper/Animations/Animation.cs

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using CUE4Parse_Conversion.Animations.PSA;
55
using CUE4Parse.UE4.Assets.Exports;
66
using CUE4Parse.UE4.Objects.Core.Misc;
7-
using CUE4Parse.Utils;
87
using ImGuiNET;
98

109
namespace FModel.Views.Snooper.Animations;
@@ -20,15 +19,8 @@ public class Animation : IDisposable
2019
public readonly float StartTime; // Animation Start Time
2120
public readonly float EndTime; // Animation End Time
2221
public readonly float TotalElapsedTime; // Animation Max Time
23-
public readonly string TargetSkeleton;
22+
public readonly Dictionary<int, float> Framing;
2423

25-
public int CurrentSequence;
26-
public int FrameInSequence; // Current Sequence's Frame to Display
27-
public int NextFrameInSequence;
28-
public float LerpAmount;
29-
30-
public string Label =>
31-
$"Retarget: {TargetSkeleton}\nSequences: {CurrentSequence + 1}/{Sequences.Length}\nFrames: {FrameInSequence}/{Sequences[CurrentSequence].EndFrame}";
3224
public bool IsActive;
3325
public bool IsSelected;
3426

@@ -40,23 +32,22 @@ public Animation(UObject export)
4032
Path = _export.GetPathName();
4133
Name = _export.Name;
4234
Sequences = Array.Empty<Sequence>();
35+
Framing = new Dictionary<int, float>();
4336
AttachedModels = new List<FGuid>();
4437
}
4538

4639
public Animation(UObject export, CAnimSet animSet) : this(export)
4740
{
4841
_animSet = animSet;
49-
TargetSkeleton = _animSet.Skeleton.Name;
5042

5143
Sequences = new Sequence[_animSet.Sequences.Count];
5244
for (int i = 0; i < Sequences.Length; i++)
5345
{
5446
Sequences[i] = new Sequence(_animSet.Sequences[i]);
55-
5647
EndTime = Sequences[i].EndTime;
57-
TotalElapsedTime += _animSet.Sequences[i].NumFrames * Sequences[i].TimePerFrame;
5848
}
5949

50+
TotalElapsedTime = animSet.TotalAnimTime;
6051
if (Sequences.Length > 0)
6152
StartTime = Sequences[0].StartTime;
6253
}
@@ -70,30 +61,16 @@ public void TimeCalculation(float elapsedTime)
7061
{
7162
for (int i = 0; i < Sequences.Length; i++)
7263
{
73-
if (elapsedTime < Sequences[i].EndTime && elapsedTime >= Sequences[i].StartTime)
64+
var sequence = Sequences[i];
65+
if (elapsedTime < sequence.EndTime && elapsedTime >= sequence.StartTime)
7466
{
75-
CurrentSequence = i;
76-
break;
67+
Framing[i] = (elapsedTime - sequence.StartTime) / sequence.TimePerFrame;
7768
}
69+
else Framing.Remove(i);
7870
}
79-
if (elapsedTime >= TotalElapsedTime) Reset();
80-
81-
var lastEndTime = 0.0f;
82-
for (int s = 0; s < CurrentSequence; s++)
83-
lastEndTime = Sequences[s].EndTime;
8471

85-
var exactFrameAtThisTime = (elapsedTime - lastEndTime) / Sequences[CurrentSequence].TimePerFrame;
86-
FrameInSequence = Math.Min(exactFrameAtThisTime.FloorToInt(), Sequences[CurrentSequence].EndFrame);
87-
NextFrameInSequence = Math.Min(FrameInSequence + 1, Sequences[CurrentSequence].EndFrame);
88-
LerpAmount = Math.Clamp(exactFrameAtThisTime - FrameInSequence, 0, 1);
89-
}
90-
91-
private void Reset()
92-
{
93-
FrameInSequence = 0;
94-
NextFrameInSequence = 0;
95-
LerpAmount = 0.0f;
96-
CurrentSequence = 0;
72+
if (elapsedTime >= TotalElapsedTime)
73+
Framing.Clear();
9774
}
9875

9976
public void Dispose()
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace FModel.Views.Snooper.Animations;
1+
using System.Collections.Generic;
2+
3+
namespace FModel.Views.Snooper.Animations;
24

35
public class Bone
46
{
@@ -8,18 +10,21 @@ public class Bone
810
public string LoweredParentName;
911

1012
public int SkeletonIndex = -1;
11-
public bool IsAnimated;
13+
public readonly List<int> AnimatedBySequences;
1214

1315
public Bone(int i, int p, Transform t)
1416
{
1517
Index = i;
1618
ParentIndex = p;
1719
Rest = t;
20+
21+
AnimatedBySequences = new List<int>();
1822
}
1923

2024
public bool IsRoot => Index == 0 && ParentIndex == -1 && string.IsNullOrEmpty(LoweredParentName);
2125
public bool IsMapped => SkeletonIndex > -1;
26+
public bool IsAnimated => AnimatedBySequences.Count > 0;
2227
public bool IsNative => Index == SkeletonIndex;
2328

24-
public override string ToString() => $"Mesh Ref '{Index}' is Skel Ref '{SkeletonIndex}' ({IsAnimated})";
29+
public override string ToString() => $"Mesh Ref '{Index}' is Skel Ref '{SkeletonIndex}'";
2530
}

FModel/Views/Snooper/Animations/Skeleton.cs

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using CUE4Parse_Conversion.Animations.PSA;
55
using CUE4Parse.UE4.Assets.Exports.Animation;
66
using CUE4Parse.UE4.Objects.Core.Math;
7+
using CUE4Parse.Utils;
78
using FModel.Views.Snooper.Buffers;
89
using OpenTK.Graphics.OpenGL4;
910
using Serilog;
@@ -74,7 +75,6 @@ public void Animate(CAnimSet anim, bool rotationOnly)
7475
var skeletonBoneIndex = bone.SkeletonIndex;
7576
if (sequence.OriginalSequence.FindTrackForBoneIndex(skeletonBoneIndex) < 0)
7677
{
77-
bone.IsAnimated |= false;
7878
for (int frame = 0; frame < _animatedBonesTransform[s][bone.Index].Length; frame++)
7979
{
8080
_animatedBonesTransform[s][bone.Index][frame] = new Transform
@@ -86,7 +86,7 @@ public void Animate(CAnimSet anim, bool rotationOnly)
8686
}
8787
else
8888
{
89-
bone.IsAnimated |= true;
89+
bone.AnimatedBySequences.Add(s);
9090
for (int frame = 0; frame < _animatedBonesTransform[s][bone.Index].Length; frame++)
9191
{
9292
var boneOrientation = bone.Rest.Rotation;
@@ -173,7 +173,6 @@ private void MapSkeleton(CAnimSet anim)
173173
continue;
174174

175175
bone.SkeletonIndex = boneIndex;
176-
bone.IsAnimated = false;
177176
}
178177

179178
#if DEBUG
@@ -192,7 +191,7 @@ public void ResetAnimatedData(bool full = false)
192191
foreach (var bone in BonesByLoweredName.Values)
193192
{
194193
bone.SkeletonIndex = -1;
195-
bone.IsAnimated = false;
194+
bone.AnimatedBySequences.Clear();
196195
}
197196

198197
if (!full) return;
@@ -208,22 +207,59 @@ public void Setup()
208207
_ssbo.UpdateRange(BoneCount, Matrix4x4.Identity);
209208
}
210209

211-
public void UpdateAnimationMatrices(int currentSequence, int frameInSequence, int nextFrameInSequence, float lerp)
210+
public void UpdateAnimationMatrices(Animation animation)
212211
{
213212
if (!IsAnimated) return;
214213

215214
_ssbo.Bind();
216-
for (int boneIndex = 0; boneIndex < BoneCount; boneIndex++)
215+
216+
foreach (var bone in BonesByLoweredName.Values)
217217
{
218+
var (s, f) = GetBoneFrameData(bone, animation);
219+
var frameInSequence = Math.Min(f.FloorToInt(), animation.Sequences[s].EndFrame);
220+
var nextFrameInSequence = Math.Min(frameInSequence + 1, animation.Sequences[s].EndFrame);
221+
var lerpAmount = Math.Clamp(f - frameInSequence, 0, 1);
222+
223+
var boneIndex = bone.Index;
218224
var matrix = Matrix4x4.Lerp(
219-
_animatedBonesTransform[currentSequence][boneIndex][frameInSequence].Matrix,
220-
_animatedBonesTransform[currentSequence][boneIndex][nextFrameInSequence].Matrix,
221-
lerp);
225+
_animatedBonesTransform[s][boneIndex][frameInSequence].Matrix,
226+
_animatedBonesTransform[s][boneIndex][nextFrameInSequence].Matrix,
227+
lerpAmount);
222228
_ssbo.Update(boneIndex, _invertedBonesMatrix[boneIndex] * matrix);
223229
}
230+
224231
_ssbo.Unbind();
225232
}
226233

234+
private (int, float) GetBoneFrameData(Bone bone, Animation animation)
235+
{
236+
int s = -1;
237+
float f = 0.0f;
238+
239+
void Get(Bone b)
240+
{
241+
foreach (var i in b.AnimatedBySequences)
242+
{
243+
s = i;
244+
if (animation.Framing.TryGetValue(s, out f))
245+
break;
246+
}
247+
}
248+
249+
Get(bone);
250+
if (s == -1)
251+
{
252+
var parent = BonesByLoweredName[bone.LoweredParentName];
253+
while (!parent.IsAnimated)
254+
{
255+
parent = BonesByLoweredName[parent.LoweredParentName];
256+
}
257+
Get(parent);
258+
}
259+
260+
return (s, f);
261+
}
262+
227263
public Matrix4x4 GetBoneMatrix(Bone bone) => IsAnimated ? bone.Rest.Matrix * _ssbo.Get(bone.Index) : bone.Rest.Matrix;
228264

229265
public void Render()

FModel/Views/Snooper/Renderer.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,7 @@ public void Update(Snooper wnd, float deltaSeconds)
267267
animation.TimeCalculation(Options.Tracker.ElapsedTime);
268268
foreach (var guid in animation.AttachedModels.Where(guid => Options.Models[guid].HasSkeleton))
269269
{
270-
Options.Models[guid].Skeleton.UpdateAnimationMatrices(
271-
animation.CurrentSequence, animation.FrameInSequence,
272-
animation.NextFrameInSequence, animation.LerpAmount);
270+
Options.Models[guid].Skeleton.UpdateAnimationMatrices(animation);
273271
}
274272
}
275273

0 commit comments

Comments
 (0)