mirror of
https://github.com/4sval/FModel.git
synced 2026-03-21 17:24:26 -05:00
Merge pull request #550 from 4sval/on-hold
Some checks failed
FModel QA Builder / build (push) Has been cancelled
Some checks failed
FModel QA Builder / build (push) Has been cancelled
On hold
This commit is contained in:
commit
34116d62b2
|
|
@ -1 +1 @@
|
|||
Subproject commit 9a63be6718300901eebe6af9c65908c2c69c67b0
|
||||
Subproject commit c36748f206d19eea45a6f2ea4cc82e56617d87c9
|
||||
|
|
@ -1,13 +1,19 @@
|
|||
using RestSharp;
|
||||
using RestSharp.Interceptors;
|
||||
|
||||
namespace FModel.ViewModels.ApiEndpoints;
|
||||
|
||||
public abstract class AbstractApiProvider
|
||||
{
|
||||
protected readonly RestClient _client;
|
||||
protected readonly Interceptor _interceptor;
|
||||
|
||||
protected AbstractApiProvider(RestClient client)
|
||||
{
|
||||
_client = client;
|
||||
_interceptor = new CompatibilityInterceptor
|
||||
{
|
||||
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class DynamicApiEndpoint : AbstractApiProvider
|
|||
{
|
||||
var request = new FRestRequest(url)
|
||||
{
|
||||
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
|
||||
Interceptors = [_interceptor]
|
||||
};
|
||||
var response = await _client.ExecuteAsync(request, token).ConfigureAwait(false);
|
||||
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public class FortniteCentralApiEndpoint : AbstractApiProvider
|
|||
{
|
||||
var request = new FRestRequest("https://fortnitecentral.genxgames.gg/api/v1/hotfixes")
|
||||
{
|
||||
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
|
||||
Interceptors = [_interceptor]
|
||||
};
|
||||
request.AddParameter("lang", language);
|
||||
var response = await _client.ExecuteAsync<Dictionary<string, Dictionary<string, string>>>(request, token).ConfigureAwait(false);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class BackupManagerViewModel : ViewModel
|
|||
var backupFolder = Path.Combine(UserSettings.Default.OutputDirectory, "Backups");
|
||||
var fileName = $"{_gameName}_{DateTime.Now:MM'_'dd'_'yyyy}.fbkp";
|
||||
var fullPath = Path.Combine(backupFolder, fileName);
|
||||
var func = new Func<GameFile, bool>(x => !x.Path.EndsWith(".uexp") && !x.Path.EndsWith(".ubulk") && !x.Path.EndsWith(".uptnl"));
|
||||
var func = new Func<GameFile, bool>(x => !x.IsUePackagePayload);
|
||||
|
||||
using var fileStream = new FileStream(fullPath, FileMode.Create);
|
||||
using var compressedStream = LZ4Stream.Encode(fileStream, LZ4Level.L00_FAST);
|
||||
|
|
@ -80,7 +80,7 @@ public class BackupManagerViewModel : ViewModel
|
|||
if (!func(asset)) continue;
|
||||
writer.Write(asset.Size);
|
||||
writer.Write(asset.IsEncrypted);
|
||||
writer.Write($"/{asset.Path.ToLower()}");
|
||||
writer.Write(asset.Path);
|
||||
}
|
||||
|
||||
SaveCheck(fullPath, fileName, "created", "create");
|
||||
|
|
@ -121,6 +121,7 @@ public enum EBackupVersion : byte
|
|||
{
|
||||
BeforeVersionWasAdded = 0,
|
||||
Initial,
|
||||
PerfectPath, // no more leading slash and ToLower
|
||||
|
||||
LatestPlusOne,
|
||||
Latest = LatestPlusOne - 1
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ public class LoadCommand : ViewModelCommand<LoadingModesViewModel>
|
|||
{
|
||||
case ELoadingMode.AllButNew:
|
||||
{
|
||||
var paths = new HashSet<string>();
|
||||
var paths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var magic = archive.Read<uint>();
|
||||
if (magic != BackupManagerViewModel.FBKP_MAGIC)
|
||||
{
|
||||
|
|
@ -192,7 +192,7 @@ public class LoadCommand : ViewModelCommand<LoadingModesViewModel>
|
|||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
archive.Position += 29;
|
||||
paths.Add(archive.ReadString().ToLower()[1..]);
|
||||
paths.Add(archive.ReadString()[1..]);
|
||||
archive.Position += 4;
|
||||
}
|
||||
}
|
||||
|
|
@ -205,7 +205,10 @@ public class LoadCommand : ViewModelCommand<LoadingModesViewModel>
|
|||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
archive.Position += sizeof(long) + sizeof(byte);
|
||||
paths.Add(archive.ReadString().ToLower()[1..]);
|
||||
var fullPath = archive.ReadString();
|
||||
if (version < EBackupVersion.PerfectPath) fullPath = fullPath[1..];
|
||||
|
||||
paths.Add(fullPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +236,7 @@ public class LoadCommand : ViewModelCommand<LoadingModesViewModel>
|
|||
var uncompressedSize = archive.Read<long>();
|
||||
var isEncrypted = archive.ReadFlag();
|
||||
archive.Position += 4;
|
||||
var fullPath = archive.ReadString().ToLower()[1..];
|
||||
var fullPath = archive.ReadString()[1..];
|
||||
archive.Position += 4;
|
||||
|
||||
AddEntry(fullPath, uncompressedSize, isEncrypted, entries);
|
||||
|
|
@ -249,7 +252,8 @@ public class LoadCommand : ViewModelCommand<LoadingModesViewModel>
|
|||
|
||||
var uncompressedSize = archive.Read<long>();
|
||||
var isEncrypted = archive.ReadFlag();
|
||||
var fullPath = archive.ReadString().ToLower()[1..];
|
||||
var fullPath = archive.ReadString();
|
||||
if (version < EBackupVersion.PerfectPath) fullPath = fullPath[1..];
|
||||
|
||||
AddEntry(fullPath, uncompressedSize, isEncrypted, entries);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ public class Animation : IDisposable
|
|||
_export = export;
|
||||
Path = _export.GetPathName();
|
||||
Name = _export.Name;
|
||||
Sequences = Array.Empty<Sequence>();
|
||||
Sequences = [];
|
||||
Framing = new Dictionary<int, float>();
|
||||
AttachedModels = new List<FGuid>();
|
||||
AttachedModels = [];
|
||||
}
|
||||
|
||||
public Animation(UObject export, CAnimSet animSet) : this(export)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public class TimeTracker : IDisposable
|
|||
public bool IsActive;
|
||||
public float ElapsedTime;
|
||||
public float MaxElapsedTime;
|
||||
public int TimeMultiplier;
|
||||
public float TimeMultiplier;
|
||||
|
||||
public TimeTracker()
|
||||
{
|
||||
|
|
@ -51,7 +51,7 @@ public class TimeTracker : IDisposable
|
|||
if (doMet)
|
||||
{
|
||||
MaxElapsedTime = 0.01f;
|
||||
TimeMultiplier = 1;
|
||||
TimeMultiplier = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ public class SkeletalModel : UModel
|
|||
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Line);
|
||||
foreach (var collision in Collisions)
|
||||
{
|
||||
var boneMatrix = Matrix4x4.Identity;
|
||||
|
|
@ -162,7 +162,7 @@ public class SkeletalModel : UModel
|
|||
|
||||
collision.Render(shader, boneMatrix);
|
||||
}
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,12 +148,12 @@ public class StaticModel : UModel
|
|||
base.RenderCollision(shader);
|
||||
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Line);
|
||||
foreach (var collision in Collisions)
|
||||
{
|
||||
collision.Render(shader, Matrix4x4.Identity);
|
||||
}
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ public abstract class UModel : IRenderableModel
|
|||
}
|
||||
|
||||
Vao.Bind();
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, ShowWireframe ? PolygonMode.Line : PolygonMode.Fill);
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, ShowWireframe ? PolygonMode.Line : PolygonMode.Fill);
|
||||
foreach (var section in Sections)
|
||||
{
|
||||
if (!section.Show) continue;
|
||||
|
|
@ -275,7 +275,7 @@ public abstract class UModel : IRenderableModel
|
|||
|
||||
GL.DrawElementsInstanced(PrimitiveType.Triangles, section.FacesCount, DrawElementsType.UnsignedInt, section.FirstFaceIndexPtr, TransformsCount);
|
||||
}
|
||||
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
|
||||
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Fill);
|
||||
Vao.Unbind();
|
||||
|
||||
if (IsSelected)
|
||||
|
|
|
|||
|
|
@ -122,111 +122,90 @@ public class Renderer : IDisposable
|
|||
public void Animate(Lazy<UObject> anim) => Animate(anim.Value, Options.SelectedModel);
|
||||
private void Animate(UObject anim, FGuid guid)
|
||||
{
|
||||
if (!Options.TryGetModel(guid, out var m) || m is not SkeletalModel model)
|
||||
if (anim is not UAnimSequenceBase animBase || !animBase.Skeleton.TryLoad(out USkeleton skeleton) ||
|
||||
!Options.TryGetModel(guid, out var m) || m is not SkeletalModel model)
|
||||
return;
|
||||
|
||||
float maxElapsedTime;
|
||||
switch (anim)
|
||||
var animSet = animBase switch
|
||||
{
|
||||
case UAnimSequence animSequence when animSequence.Skeleton.TryLoad(out USkeleton skeleton):
|
||||
{
|
||||
var animSet = skeleton.ConvertAnims(animSequence);
|
||||
var animation = new Animation(animSequence, animSet, guid);
|
||||
maxElapsedTime = animation.TotalElapsedTime;
|
||||
model.Skeleton.Animate(animSet);
|
||||
Options.AddAnimation(animation);
|
||||
break;
|
||||
}
|
||||
case UAnimMontage animMontage when animMontage.Skeleton.TryLoad(out USkeleton skeleton):
|
||||
{
|
||||
var animSet = skeleton.ConvertAnims(animMontage);
|
||||
var animation = new Animation(animMontage, animSet, guid);
|
||||
maxElapsedTime = animation.TotalElapsedTime;
|
||||
model.Skeleton.Animate(animSet);
|
||||
Options.AddAnimation(animation);
|
||||
UAnimSequence animSequence => skeleton.ConvertAnims(animSequence),
|
||||
UAnimMontage animMontage => skeleton.ConvertAnims(animMontage),
|
||||
UAnimComposite animComposite => skeleton.ConvertAnims(animComposite),
|
||||
_ => throw new ArgumentException("Unknown animation type")
|
||||
};
|
||||
|
||||
foreach (var notifyEvent in animMontage.Notifies)
|
||||
var animation = new Animation(anim, animSet, guid);
|
||||
model.Skeleton.Animate(animSet);
|
||||
Options.AddAnimation(animation);
|
||||
|
||||
foreach (var notifyEvent in animBase.Notifies)
|
||||
{
|
||||
if (!notifyEvent.NotifyStateClass.TryLoad(out UObject notifyClass) ||
|
||||
!notifyClass.TryGetValue(out UObject export, "SkeletalMeshProp", "StaticMeshProp", "Mesh", "SkeletalMeshTemplate"))
|
||||
continue;
|
||||
|
||||
var t = Transform.Identity;
|
||||
if (notifyClass.TryGetValue(out FTransform offset, "Offset"))
|
||||
{
|
||||
t.Rotation = offset.Rotation;
|
||||
t.Position = offset.Translation * Constants.SCALE_DOWN_RATIO;
|
||||
t.Scale = offset.Scale3D;
|
||||
}
|
||||
|
||||
UModel addedModel = null;
|
||||
switch (export)
|
||||
{
|
||||
case UStaticMesh st:
|
||||
{
|
||||
if (!notifyEvent.NotifyStateClass.TryLoad(out UObject notifyClass) ||
|
||||
!notifyClass.TryGetValue(out FPackageIndex meshProp, "SkeletalMeshProp", "StaticMeshProp", "Mesh") ||
|
||||
!meshProp.TryLoad(out UObject export)) continue;
|
||||
|
||||
var t = Transform.Identity;
|
||||
if (notifyClass.TryGetValue(out FTransform offset, "Offset"))
|
||||
guid = st.LightingGuid;
|
||||
if (Options.TryGetModel(guid, out addedModel))
|
||||
{
|
||||
t.Rotation = offset.Rotation;
|
||||
t.Position = offset.Translation * Constants.SCALE_DOWN_RATIO;
|
||||
t.Scale = offset.Scale3D;
|
||||
addedModel.AddInstance(t);
|
||||
}
|
||||
|
||||
UModel addedModel = null;
|
||||
switch (export)
|
||||
else if (st.TryConvert(out var mesh))
|
||||
{
|
||||
case UStaticMesh st:
|
||||
{
|
||||
guid = st.LightingGuid;
|
||||
if (Options.TryGetModel(guid, out addedModel))
|
||||
{
|
||||
addedModel.AddInstance(t);
|
||||
}
|
||||
else if (st.TryConvert(out var mesh))
|
||||
{
|
||||
addedModel = new StaticModel(st, mesh, t);
|
||||
Options.Models[guid] = addedModel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case USkeletalMesh sk:
|
||||
{
|
||||
guid = Guid.NewGuid();
|
||||
if (!Options.Models.ContainsKey(guid) && sk.TryConvert(out var mesh))
|
||||
{
|
||||
addedModel = new SkeletalModel(sk, mesh, t);
|
||||
Options.Models[guid] = addedModel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addedModel == null)
|
||||
throw new ArgumentException("Unknown model type");
|
||||
|
||||
addedModel.IsProp = true;
|
||||
if (notifyClass.TryGetValue(out UObject skeletalMeshPropAnimation, "SkeletalMeshPropAnimation", "Animation"))
|
||||
Animate(skeletalMeshPropAnimation, guid);
|
||||
if (notifyClass.TryGetValue(out FName socketName, "SocketName"))
|
||||
{
|
||||
t = Transform.Identity;
|
||||
if (notifyClass.TryGetValue(out FVector location, "LocationOffset", "Location"))
|
||||
t.Position = location * Constants.SCALE_DOWN_RATIO;
|
||||
if (notifyClass.TryGetValue(out FRotator rotation, "RotationOffset", "Rotation"))
|
||||
t.Rotation = rotation.Quaternion();
|
||||
if (notifyClass.TryGetValue(out FVector scale, "Scale"))
|
||||
t.Scale = scale;
|
||||
|
||||
var s = new Socket($"ANIM_{addedModel.Name}", socketName, t, true);
|
||||
model.Sockets.Add(s);
|
||||
addedModel.Attachments.Attach(model, addedModel.GetTransform(), s,
|
||||
new SocketAttachementInfo { Guid = guid, Instance = addedModel.SelectedInstance });
|
||||
addedModel = new StaticModel(st, mesh, t);
|
||||
Options.Models[guid] = addedModel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case USkeletalMesh sk:
|
||||
{
|
||||
guid = Guid.NewGuid();
|
||||
if (!Options.Models.ContainsKey(guid) && sk.TryConvert(out var mesh))
|
||||
{
|
||||
addedModel = new SkeletalModel(sk, mesh, t);
|
||||
Options.Models[guid] = addedModel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UAnimComposite animComposite when animComposite.Skeleton.TryLoad(out USkeleton skeleton):
|
||||
|
||||
if (addedModel == null)
|
||||
throw new ArgumentException("Unknown model type");
|
||||
|
||||
addedModel.IsProp = true;
|
||||
if (notifyClass.TryGetValue(out UObject skeletalMeshPropAnimation, "SkeletalMeshPropAnimation", "Animation", "AnimToPlay"))
|
||||
Animate(skeletalMeshPropAnimation, guid);
|
||||
if (notifyClass.TryGetValue(out FName socketName, "SocketName"))
|
||||
{
|
||||
var animSet = skeleton.ConvertAnims(animComposite);
|
||||
var animation = new Animation(animComposite, animSet, guid);
|
||||
maxElapsedTime = animation.TotalElapsedTime;
|
||||
model.Skeleton.Animate(animSet);
|
||||
Options.AddAnimation(animation);
|
||||
break;
|
||||
t = Transform.Identity;
|
||||
if (notifyClass.TryGetValue(out FVector location, "LocationOffset", "Location"))
|
||||
t.Position = location * Constants.SCALE_DOWN_RATIO;
|
||||
if (notifyClass.TryGetValue(out FRotator rotation, "RotationOffset", "Rotation"))
|
||||
t.Rotation = rotation.Quaternion();
|
||||
if (notifyClass.TryGetValue(out FVector scale, "Scale"))
|
||||
t.Scale = scale;
|
||||
|
||||
var s = new Socket($"ANIM_{addedModel.Name}", socketName, t, true);
|
||||
model.Sockets.Add(s);
|
||||
addedModel.Attachments.Attach(model, addedModel.GetTransform(), s,
|
||||
new SocketAttachementInfo { Guid = guid, Instance = addedModel.SelectedInstance });
|
||||
}
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
Options.Tracker.IsPaused = false;
|
||||
Options.Tracker.SafeSetMaxElapsedTime(maxElapsedTime);
|
||||
Options.Tracker.SafeSetMaxElapsedTime(animation.TotalElapsedTime);
|
||||
}
|
||||
|
||||
public void Setup()
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ public class SnimGui
|
|||
Layout("Animate With Rotation Only");ImGui.PushID(1);
|
||||
ImGui.Checkbox("", ref s.Renderer.AnimateWithRotationOnly);
|
||||
ImGui.PopID();Layout("Time Multiplier");ImGui.PushID(2);
|
||||
ImGui.DragInt("", ref s.Renderer.Options.Tracker.TimeMultiplier, 0.1f, 1, 8, "x%i", ImGuiSliderFlags.NoInput);
|
||||
ImGui.DragFloat("", ref s.Renderer.Options.Tracker.TimeMultiplier, 0.01f, 0.25f, 8f, "x%.2f", ImGuiSliderFlags.NoInput);
|
||||
ImGui.PopID();Layout("Vertex Colors");ImGui.PushID(3);
|
||||
var c = (int) s.Renderer.Color;
|
||||
ImGui.Combo("vertex_colors", ref c,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user