mirror of
https://github.com/4sval/FModel.git
synced 2026-03-21 17:24:26 -05:00
saving this before refactoring
This commit is contained in:
parent
ad7dc46a0a
commit
8438591839
|
|
@ -11,6 +11,4 @@ public class BoneIndice
|
|||
public int ParentTrackIndex = -1; // bone index of the first tracked parent bone
|
||||
public bool HasTrack => TrackIndex > -1;
|
||||
public bool HasParentTrack => ParentTrackIndex > -1;
|
||||
|
||||
public override string ToString() => $"{ParentBoneIndex} -> {BoneIndex}{(HasTrack ? $" ({ParentTrackIndex} -> {TrackIndex})" : "")}";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ public class Model : IDisposable
|
|||
public bool HasSkeleton => Skeleton != null;
|
||||
public readonly Skeleton Skeleton;
|
||||
|
||||
public bool HasSockets => Sockets.Length > 0;
|
||||
public readonly Socket[] Sockets;
|
||||
public bool HasSockets => Sockets.Count > 0;
|
||||
public readonly List<Socket> Sockets;
|
||||
|
||||
public bool HasMorphTargets => Morphs.Length > 0;
|
||||
public readonly Morph[] Morphs;
|
||||
|
|
@ -115,7 +115,7 @@ public class Model : IDisposable
|
|||
Type = export.ExportType;
|
||||
UvCount = 1;
|
||||
Box = new FBox(new FVector(-2f), new FVector(2f));
|
||||
Sockets = Array.Empty<Socket>();
|
||||
Sockets = new List<Socket>();
|
||||
Morphs = Array.Empty<Morph>();
|
||||
Transforms = new List<Transform>();
|
||||
}
|
||||
|
|
@ -125,11 +125,10 @@ public class Model : IDisposable
|
|||
{
|
||||
Box = staticMesh.BoundingBox * Constants.SCALE_DOWN_RATIO;
|
||||
|
||||
Sockets = new Socket[export.Sockets.Length];
|
||||
for (int i = 0; i < Sockets.Length; i++)
|
||||
for (int i = 0; i < export.Sockets.Length; i++)
|
||||
{
|
||||
if (export.Sockets[i].Load<UStaticMeshSocket>() is not { } socket) continue;
|
||||
Sockets[i] = new Socket(socket);
|
||||
Sockets.Add(new Socket(socket));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,11 +146,10 @@ public class Model : IDisposable
|
|||
sockets.AddRange(skeleton.Sockets);
|
||||
}
|
||||
|
||||
Sockets = new Socket[sockets.Count];
|
||||
for (int i = 0; i < Sockets.Length; i++)
|
||||
for (int i = 0; i < sockets.Count; i++)
|
||||
{
|
||||
if (sockets[i].Load<USkeletalMeshSocket>() is not { } socket) continue;
|
||||
Sockets[i] = new Socket(socket);
|
||||
Sockets.Add(new Socket(socket));
|
||||
}
|
||||
|
||||
Morphs = new Morph[export.MorphTargets.Length];
|
||||
|
|
@ -453,10 +451,11 @@ public class Model : IDisposable
|
|||
_matrixVbo.Dispose();
|
||||
_vao.Dispose();
|
||||
Skeleton?.Dispose();
|
||||
for (int socket = 0; socket < Sockets.Length; socket++)
|
||||
for (int socket = 0; socket < Sockets.Count; socket++)
|
||||
{
|
||||
Sockets[socket]?.Dispose();
|
||||
}
|
||||
Sockets.Clear();
|
||||
if (HasMorphTargets) _morphVbo.Dispose();
|
||||
for (var morph = 0; morph < Morphs.Length; morph++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CUE4Parse.UE4.Assets.Exports.SkeletalMesh;
|
||||
using CUE4Parse.UE4.Assets.Exports.StaticMesh;
|
||||
|
|
@ -21,6 +21,13 @@ public class Socket : IDisposable
|
|||
AttachedModels = new List<FGuid>();
|
||||
}
|
||||
|
||||
public Socket(string name, FName boneName, Transform transform) : this()
|
||||
{
|
||||
Name = name;
|
||||
BoneName = boneName;
|
||||
Transform = transform;
|
||||
}
|
||||
|
||||
public Socket(UStaticMeshSocket socket) : this()
|
||||
{
|
||||
Name = socket.SocketName.Text;
|
||||
|
|
|
|||
|
|
@ -93,16 +93,60 @@ public class Renderer : IDisposable
|
|||
|
||||
public void Animate(UObject anim)
|
||||
{
|
||||
if (!Options.TryGetModel(out var model) || !model.HasSkeleton)
|
||||
if (!Options.TryGetModel(out var model))
|
||||
return;
|
||||
|
||||
Animate(anim, model);
|
||||
}
|
||||
private void Animate(UObject anim, Model model)
|
||||
{
|
||||
if (!model.HasSkeleton) return;
|
||||
switch (anim)
|
||||
{
|
||||
case UAnimSequence animSequence when animSequence.Skeleton.TryLoad(out USkeleton skeleton):
|
||||
model.Skeleton.SetAnimation(skeleton.ConvertAnims(animSequence), AnimateWithRotationOnly);
|
||||
break;
|
||||
case UAnimMontage animMontage when animMontage.Skeleton.TryLoad(out USkeleton skeleton):
|
||||
// for (int i = 0; i < skeleton.Sockets.Length; i++)
|
||||
// {
|
||||
// if (skeleton.Sockets[i].Load<USkeletalMeshSocket>() is not { } socket) continue;
|
||||
// model.Sockets.Add(new Socket(socket));
|
||||
// }
|
||||
|
||||
model.Skeleton.SetAnimation(skeleton.ConvertAnims(animMontage), AnimateWithRotationOnly);
|
||||
foreach (var notifyEvent in animMontage.Notifies)
|
||||
{
|
||||
if (!notifyEvent.NotifyStateClass.TryLoad(out UObject notifyClass) ||
|
||||
!notifyClass.TryGetValue(out FPackageIndex meshProp, "SkeletalMeshProp", "StaticMeshProp", "Mesh") ||
|
||||
!meshProp.TryLoad(out UObject export)) continue;
|
||||
|
||||
FGuid guid = export switch
|
||||
{
|
||||
UStaticMesh st => LoadStaticMesh(st, false),
|
||||
USkeletalMesh sk => LoadSkeletalMesh(sk, false),
|
||||
_ => throw new ArgumentException()
|
||||
};
|
||||
|
||||
if (!Options.TryGetModel(guid, out var addedModel))
|
||||
continue;
|
||||
|
||||
if (notifyClass.TryGetValue(out UObject skeletalMeshPropAnimation, "SkeletalMeshPropAnimation"))
|
||||
Animate(skeletalMeshPropAnimation, addedModel);
|
||||
if (notifyClass.TryGetValue(out FName socketName, "SocketName"))
|
||||
{
|
||||
var t = Transform.Identity;
|
||||
if (notifyClass.TryGetValue(out FVector location, "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("hello", socketName, t);
|
||||
model.Sockets.Add(s);
|
||||
s.AttachedModels.Add(guid);
|
||||
addedModel.AttachModel(model, s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UAnimComposite animComposite when animComposite.Skeleton.TryLoad(out USkeleton skeleton):
|
||||
model.Skeleton.SetAnimation(skeleton.ConvertAnims(animComposite), AnimateWithRotationOnly);
|
||||
|
|
@ -168,32 +212,40 @@ public class Renderer : IDisposable
|
|||
Picking.Render(viewMatrix, projMatrix, Options.Models);
|
||||
}
|
||||
|
||||
private void LoadStaticMesh(UStaticMesh original)
|
||||
private FGuid LoadStaticMesh(UStaticMesh original, bool select = true)
|
||||
{
|
||||
var guid = original.LightingGuid;
|
||||
if (Options.TryGetModel(guid, out var model))
|
||||
{
|
||||
model.AddInstance(Transform.Identity);
|
||||
Application.Current.Dispatcher.Invoke(() => model.SetupInstances());
|
||||
return;
|
||||
return guid;
|
||||
}
|
||||
|
||||
if (!original.TryConvert(out var mesh))
|
||||
return;
|
||||
return guid;
|
||||
|
||||
Options.Models[guid] = new Model(original, mesh);
|
||||
Options.SelectModel(guid);
|
||||
SetupCamera(Options.Models[guid].Box);
|
||||
if (select)
|
||||
{
|
||||
Options.SelectModel(guid);
|
||||
SetupCamera(Options.Models[guid].Box);
|
||||
}
|
||||
return guid;
|
||||
}
|
||||
|
||||
private void LoadSkeletalMesh(USkeletalMesh original)
|
||||
private FGuid LoadSkeletalMesh(USkeletalMesh original, bool select = true)
|
||||
{
|
||||
var guid = new FGuid((uint) original.GetFullName().GetHashCode());
|
||||
if (Options.Models.ContainsKey(guid) || !original.TryConvert(out var mesh)) return;
|
||||
if (Options.Models.ContainsKey(guid) || !original.TryConvert(out var mesh)) return guid;
|
||||
|
||||
Options.Models[guid] = new Model(original, mesh);
|
||||
Options.SelectModel(guid);
|
||||
SetupCamera(Options.Models[guid].Box);
|
||||
if (select)
|
||||
{
|
||||
Options.SelectModel(guid);
|
||||
SetupCamera(Options.Models[guid].Box);
|
||||
}
|
||||
return guid;
|
||||
}
|
||||
|
||||
private void LoadMaterialInstance(UMaterialInstance original)
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
|
|||
foreach (var model in s.Renderer.Options.Models.Values)
|
||||
{
|
||||
if (!model.HasSockets || model.IsSelected) continue;
|
||||
if (ImGui.TreeNode($"{model.Name} [{model.Sockets.Length}]"))
|
||||
if (ImGui.TreeNode($"{model.Name} [{model.Sockets.Count}]"))
|
||||
{
|
||||
var i = 0;
|
||||
foreach (var socket in model.Sockets)
|
||||
|
|
@ -460,7 +460,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
|
|||
{
|
||||
Layout("Two Sided");ImGui.Text($" : {model.TwoSided}");
|
||||
}
|
||||
Layout("Sockets");ImGui.Text($" : x{model.Sockets.Length}");
|
||||
Layout("Sockets");ImGui.Text($" : x{model.Sockets.Count}");
|
||||
|
||||
ImGui.EndTable();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user