diff --git a/CUE4Parse b/CUE4Parse
index 0e178d32..c527901e 160000
--- a/CUE4Parse
+++ b/CUE4Parse
@@ -1 +1 @@
-Subproject commit 0e178d32bef3b571cabca5f041dae102d209f2d3
+Subproject commit c527901e384fda7cd75cd630cf2bd535d155574f
diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index 5641d311..30c828e3 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -5,9 +5,9 @@
net6.0-windows
true
FModel.ico
- 4.4.1.1
- 4.4.1.1
- 4.4.1.1
+ 4.4.2.0
+ 4.4.2.0
+ 4.4.2.0
false
true
win-x64
diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs
index ef2bc7f9..eababa1b 100644
--- a/FModel/MainWindow.xaml.cs
+++ b/FModel/MainWindow.xaml.cs
@@ -78,10 +78,10 @@ public partial class MainWindow
#if DEBUG
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
- // "Phoenix/Content/RiggedObjects/Characters/Creatures/Elves/OneOff/HouseElf_F_T3/SK_HouseElf_F_T3_Master.uasset"));
+ // "ShooterGame/Content/Characters/Guide/S0/1P/Models/FP_Guide_S0_Skelmesh.uasset"));
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
- // "Phoenix/Content/Animation/Creatures/Elves/ELF_Rct_Mandrake_Loop_anm.uasset"));
+ // "/Game/Equippables/Guns/SniperRifles/Boltsniper/S0/1P/Anims/FP_Core_Boltsniper_S0_Fire.uasset"));
#endif
}
diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs
index 4a401e7f..530cff30 100644
--- a/FModel/Views/Snooper/Renderer.cs
+++ b/FModel/Views/Snooper/Renderer.cs
@@ -1,9 +1,11 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Threading;
using System.Windows;
using CUE4Parse_Conversion.Animations;
+using CUE4Parse_Conversion.Animations.PSA;
using CUE4Parse_Conversion.Meshes;
using CUE4Parse.UE4.Assets.Exports;
using CUE4Parse.UE4.Assets.Exports.Animation;
@@ -109,7 +111,7 @@ public class Renderer : IDisposable
float maxElapsedTime;
switch (anim)
{
- case UAnimSequence animSequence when animSequence.Skeleton.TryLoad(out USkeleton skeleton):
+ case UAnimSequence animSequence when /*!animSequence.IsValidAdditive() && */animSequence.Skeleton.TryLoad(out USkeleton skeleton):
{
var animSet = skeleton.ConvertAnims(animSequence);
var animation = new Animation(animSequence, animSet, guid);
@@ -118,6 +120,50 @@ public class Renderer : IDisposable
Options.AddAnimation(animation);
break;
}
+ /*case UAnimSequence additiveAnimSequence when additiveAnimSequence.IsValidAdditive() && additiveAnimSequence.Skeleton.TryLoad(out USkeleton additiveSkeleton):
+ {
+ var reference = additiveAnimSequence.RefPoseSeq?.Load();
+ var referenceSkeleton = reference.Skeleton.Load();
+
+ var additiveAnimSet = additiveSkeleton.ConvertAnims(additiveAnimSequence);
+ var referenceAnimSet = referenceSkeleton.ConvertAnims(reference);
+
+ var additivePoses = FAnimationRuntime.LoadAsPoses(additiveAnimSet, additiveSkeleton);
+ var referencePoses = FAnimationRuntime.LoadAsPoses(referenceAnimSet, referenceSkeleton, additiveAnimSet.Sequences[0].NumFrames, additiveAnimSequence.RefFrameIndex);
+
+ var animSeq = additiveAnimSet.Sequences[0];
+ animSeq.OriginalSequence = referenceAnimSet.Sequences[0].OriginalSequence;
+ animSeq.Tracks = new List(additivePoses[0].Bones.Length);
+ for (int i = 0; i < additivePoses[0].Bones.Length; i++)
+ {
+ animSeq.Tracks.Add(new CAnimTrack(additivePoses.Length));
+ }
+
+ //loop trough each Pose/Frame and add the output to the empty tracks
+ for (var index = 0; index < additivePoses.Length; index++)
+ {
+ var addPose = additivePoses[index];
+ var refPose = referencePoses[index];
+ switch (additiveAnimSequence.AdditiveAnimType)
+ {
+ case EAdditiveAnimationType.AAT_LocalSpaceBase:
+ FAnimationRuntime.AccumulateLocalSpaceAdditivePoseInternal(refPose, addPose, 1);
+ break;
+ case EAdditiveAnimationType.AAT_RotationOffsetMeshSpace:
+ FAnimationRuntime.AccumulateMeshSpaceRotationAdditiveToLocalPoseInternal(refPose, addPose, 1);
+ break;
+ }
+
+ refPose.Processed = true;
+ refPose.AddToTracks(animSeq.Tracks);
+ }
+
+ var animation = new Animation(additiveAnimSequence, additiveAnimSet, guid);
+ maxElapsedTime = animation.TotalElapsedTime;
+ model.Skeleton.Animate(additiveAnimSet, AnimateWithRotationOnly);
+ Options.AddAnimation(animation);
+ break;
+ }*/
case UAnimMontage animMontage when animMontage.Skeleton.TryLoad(out USkeleton skeleton):
{
var animSet = skeleton.ConvertAnims(animMontage);
diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs
index 1158abe3..99c3db51 100644
--- a/FModel/Views/Snooper/SnimGui.cs
+++ b/FModel/Views/Snooper/SnimGui.cs
@@ -287,7 +287,7 @@ public class SnimGui
1. UI / UX
- Press Shift while moving a window to dock it
- - Ctrl Click in a box to input a new value
+ - Double Click in a box to input a new value
- Mouse Click + Drag in a box to modify the value without having to type
- Press H to hide the window and append the next mesh you extract
@@ -307,7 +307,7 @@ public class SnimGui
- Teleport to quickly move the camera to the position of the model
- Delete
- Deselect
- - Copy Name to Clipboard
+ - Copy Path to Clipboard
4. World
- Save All to save all loaded models at once
@@ -317,11 +317,19 @@ public class SnimGui
5.1. Right Click Section
- Show / Hide the section
- Swap to change the material used by this section
- - Copy Name to Clipboard
+ - Copy Path to Clipboard
5.2. Transform
- Move / Rotate / Scale the model in the world
5.3. Morph Targets
- Modify the vertices position by a given amount to change the shape of the model
+
+6. Timeline
+ - Press Space to play/pause
+ - Control the time with your mouse
+ 6.1 Right Click Section
+ - Animate another loaded model
+ - Save
+ - Copy Path to Clipboard
");
ImGui.Separator();