mirror of
https://github.com/4sval/FModel.git
synced 2026-09-07 00:56:29 -05:00
so there's 2 skeletons ok why not
This commit is contained in:
@@ -58,6 +58,6 @@ public class Animation : IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace FModel.Views.Snooper.Models.Animations;
|
||||
public class Skeleton : IDisposable
|
||||
{
|
||||
public readonly USkeleton UnrealSkeleton;
|
||||
public readonly FReferenceSkeleton ReferenceSkeleton;
|
||||
public readonly Dictionary<string, int> BonesIndexByName;
|
||||
public readonly Dictionary<int, Transform> BonesTransformByIndex;
|
||||
public readonly bool IsLoaded;
|
||||
@@ -23,15 +24,15 @@ public class Skeleton : IDisposable
|
||||
BonesTransformByIndex = new Dictionary<int, Transform>();
|
||||
}
|
||||
|
||||
public Skeleton(FPackageIndex package, Transform transform) : this()
|
||||
public Skeleton(FPackageIndex package, FReferenceSkeleton referenceSkeleton, Transform transform) : this()
|
||||
{
|
||||
UnrealSkeleton = package.Load<USkeleton>();
|
||||
if (UnrealSkeleton == null) return;
|
||||
|
||||
BonesIndexByName = UnrealSkeleton.ReferenceSkeleton.FinalNameToIndexMap;
|
||||
ReferenceSkeleton = referenceSkeleton ?? UnrealSkeleton.ReferenceSkeleton;
|
||||
BonesIndexByName = ReferenceSkeleton.FinalNameToIndexMap;
|
||||
BonesTransformByIndex = new Dictionary<int, Transform>();
|
||||
UpdateBoneMatrices(transform.Matrix);
|
||||
|
||||
IsLoaded = true;
|
||||
}
|
||||
|
||||
@@ -44,8 +45,8 @@ public class Skeleton : IDisposable
|
||||
{
|
||||
foreach (var boneIndex in BonesIndexByName.Values)
|
||||
{
|
||||
var bone = UnrealSkeleton.ReferenceSkeleton.FinalRefBonePose[boneIndex];
|
||||
var parentIndex = UnrealSkeleton.ReferenceSkeleton.FinalRefBoneInfo[boneIndex].ParentIndex;
|
||||
var bone = ReferenceSkeleton.FinalRefBonePose[boneIndex];
|
||||
var parentIndex = ReferenceSkeleton.FinalRefBoneInfo[boneIndex].ParentIndex;
|
||||
|
||||
if (!BonesTransformByIndex.TryGetValue(boneIndex, out var boneTransform))
|
||||
{
|
||||
@@ -76,6 +77,8 @@ public class Skeleton : IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
BonesIndexByName.Clear();
|
||||
BonesTransformByIndex.Clear();
|
||||
Anim?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ using CUE4Parse.UE4.Assets.Exports.SkeletalMesh;
|
||||
using CUE4Parse.UE4.Assets.Exports.StaticMesh;
|
||||
using CUE4Parse.UE4.Objects.Core.Math;
|
||||
using FModel.Extensions;
|
||||
using FModel.Services;
|
||||
using FModel.Settings;
|
||||
using FModel.Views.Snooper.Buffers;
|
||||
using FModel.Views.Snooper.Models.Animations;
|
||||
@@ -25,6 +24,7 @@ namespace FModel.Views.Snooper.Models;
|
||||
public class Model : IDisposable
|
||||
{
|
||||
private int _handle;
|
||||
private const int _LOD_INDEX = 0;
|
||||
|
||||
private BufferObject<uint> _ebo;
|
||||
private BufferObject<float> _vbo;
|
||||
@@ -40,7 +40,6 @@ public class Model : IDisposable
|
||||
public readonly string Name;
|
||||
public readonly string Type;
|
||||
public readonly bool HasVertexColors;
|
||||
public readonly bool HasMorphTargets;
|
||||
public readonly int UvCount;
|
||||
public readonly FBox Box;
|
||||
public uint[] Indices;
|
||||
@@ -55,6 +54,9 @@ public class Model : IDisposable
|
||||
public bool HasSockets => Sockets.Length > 0;
|
||||
public readonly Socket[] Sockets;
|
||||
|
||||
public bool HasMorphTargets => Morphs.Length > 0;
|
||||
public readonly Morph[] Morphs;
|
||||
|
||||
private string _attachedTo = string.Empty;
|
||||
private readonly List<string> _attachedFor = new ();
|
||||
public bool IsAttached => _attachedTo.Length > 0;
|
||||
@@ -66,8 +68,6 @@ public class Model : IDisposable
|
||||
public readonly List<Transform> Transforms;
|
||||
private Matrix4x4 _previousMatrix;
|
||||
|
||||
public readonly Morph[] Morphs;
|
||||
|
||||
public bool Show;
|
||||
public bool Wireframe;
|
||||
public bool IsSetup { get; private set; }
|
||||
@@ -87,7 +87,7 @@ public class Model : IDisposable
|
||||
}
|
||||
|
||||
public Model(UStaticMesh export, CStaticMesh staticMesh) : this(export, staticMesh, Transform.Identity) {}
|
||||
public Model(UStaticMesh export, CStaticMesh staticMesh, Transform transform) : this(export, export.Materials, null, staticMesh.LODs.Count, staticMesh.LODs[0], staticMesh.LODs[0].Verts, transform)
|
||||
public Model(UStaticMesh export, CStaticMesh staticMesh, Transform transform) : this(export, export.Materials, staticMesh.LODs, transform)
|
||||
{
|
||||
Box = staticMesh.BoundingBox * Constants.SCALE_DOWN_RATIO;
|
||||
|
||||
@@ -97,10 +97,16 @@ public class Model : IDisposable
|
||||
if (export.Sockets[i].Load<UStaticMeshSocket>() is not { } socket) continue;
|
||||
Sockets[i] = new Socket(socket, Transforms[0]);
|
||||
}
|
||||
|
||||
Morphs = Array.Empty<Morph>();
|
||||
}
|
||||
private Model(USkeletalMesh export, CSkeletalMesh skeletalMesh, Transform transform) : this(export, export.Materials, export.Skeleton, skeletalMesh.LODs.Count, skeletalMesh.LODs[0], skeletalMesh.LODs[0].Verts, transform)
|
||||
|
||||
public Model(USkeletalMesh export, CSkeletalMesh skeletalMesh) : this(export, skeletalMesh, Transform.Identity) {}
|
||||
private Model(USkeletalMesh export, CSkeletalMesh skeletalMesh, Transform transform) : this(export, export.Materials, skeletalMesh.LODs, transform)
|
||||
{
|
||||
var t = Transforms[0];
|
||||
Box = skeletalMesh.BoundingBox * Constants.SCALE_DOWN_RATIO;
|
||||
Skeleton = new Skeleton(export.Skeleton, export.ReferenceSkeleton, t);
|
||||
|
||||
var sockets = new List<FPackageIndex>();
|
||||
sockets.AddRange(export.Sockets);
|
||||
@@ -113,37 +119,29 @@ public class Model : IDisposable
|
||||
|
||||
if (!Skeleton.BonesIndexByName.TryGetValue(socket.BoneName.Text, out var boneIndex) ||
|
||||
!Skeleton.BonesTransformByIndex.TryGetValue(boneIndex, out var boneTransform))
|
||||
boneTransform = Transforms[0];
|
||||
boneTransform = t;
|
||||
|
||||
Sockets[i] = new Socket(socket, boneTransform);
|
||||
}
|
||||
}
|
||||
public Model(USkeletalMesh export, CSkeletalMesh skeletalMesh) : this(export, skeletalMesh, Transform.Identity)
|
||||
{
|
||||
var morphTargets = export.MorphTargets;
|
||||
if (morphTargets is not { Length: > 0 })
|
||||
return;
|
||||
|
||||
var length = morphTargets.Length;
|
||||
|
||||
HasMorphTargets = true;
|
||||
Morphs = new Morph[length];
|
||||
Morphs = new Morph[export.MorphTargets.Length];
|
||||
for (var i = 0; i < Morphs.Length; i++)
|
||||
{
|
||||
Morphs[i] = new Morph(Vertices, VertexSize, morphTargets[i].Load<UMorphTarget>());
|
||||
ApplicationService.ApplicationView.Status.UpdateStatusLabel($"{Morphs[i].Name} ... {i}/{length}");
|
||||
Morphs[i] = new Morph(Vertices, VertexSize, export.MorphTargets[i].Load<UMorphTarget>());
|
||||
}
|
||||
ApplicationService.ApplicationView.Status.UpdateStatusLabel("");
|
||||
}
|
||||
|
||||
private Model(UObject export, ResolvedObject[] materials, FPackageIndex skeleton, int numLods, CBaseMeshLod lod, CMeshVertex[] vertices, Transform transform = null) : this(export)
|
||||
private Model(UObject export, IReadOnlyList<ResolvedObject> materials, IReadOnlyList<CStaticMeshLod> lods, Transform transform = null)
|
||||
: this(export, materials, lods[_LOD_INDEX], lods[_LOD_INDEX].Verts, lods.Count, transform) {}
|
||||
private Model(UObject export, IReadOnlyList<ResolvedObject> materials, IReadOnlyList<CSkelMeshLod> lods, Transform transform = null)
|
||||
: this(export, materials, lods[_LOD_INDEX], lods[_LOD_INDEX].Verts, lods.Count, transform) {}
|
||||
private Model(UObject export, IReadOnlyList<ResolvedObject> materials, CBaseMeshLod lod, IReadOnlyList<CMeshVertex> vertices, int numLods, Transform transform = null) : this(export)
|
||||
{
|
||||
var t = transform ?? Transform.Identity;
|
||||
var hasCustomUvs = lod.ExtraUV.IsValueCreated;
|
||||
UvCount = hasCustomUvs ? Math.Max(lod.NumTexCoords, numLods) : lod.NumTexCoords;
|
||||
TwoSided = lod.IsTwoSided;
|
||||
|
||||
Materials = new Material[materials.Length];
|
||||
Materials = new Material[materials.Count];
|
||||
for (int m = 0; m < Materials.Length; m++)
|
||||
{
|
||||
if ((materials[m]?.TryLoad(out var material) ?? false) && material is UMaterialInterface unrealMaterial)
|
||||
@@ -156,9 +154,8 @@ public class Model : IDisposable
|
||||
VertexSize += 4; // + Color
|
||||
}
|
||||
|
||||
if (skeleton != null)
|
||||
if (vertices is CSkelMeshVertex[])
|
||||
{
|
||||
Skeleton = new Skeleton(skeleton, t);
|
||||
VertexSize += 8; // + BoneIds + BoneWeights
|
||||
}
|
||||
|
||||
@@ -169,7 +166,7 @@ public class Model : IDisposable
|
||||
}
|
||||
|
||||
Vertices = new float[lod.NumVerts * VertexSize];
|
||||
for (int i = 0; i < vertices.Length; i++)
|
||||
for (int i = 0; i < vertices.Count; i++)
|
||||
{
|
||||
var count = 0;
|
||||
var baseIndex = i * VertexSize;
|
||||
@@ -197,9 +194,8 @@ public class Model : IDisposable
|
||||
Vertices[baseIndex + count++] = color.A;
|
||||
}
|
||||
|
||||
if (HasSkeleton)
|
||||
if (vert is CSkelMeshVertex skelVert)
|
||||
{
|
||||
var skelVert = (CSkelMeshVertex) vert;
|
||||
var weightsHash = skelVert.UnpackWeights();
|
||||
Vertices[baseIndex + count++] = skelVert.Bone[0];
|
||||
Vertices[baseIndex + count++] = skelVert.Bone[1];
|
||||
@@ -220,6 +216,7 @@ public class Model : IDisposable
|
||||
if (section.IsValid) Sections[s].SetupMaterial(Materials[section.MaterialIndex]);
|
||||
}
|
||||
|
||||
var t = transform ?? Transform.Identity;
|
||||
_previousMatrix = t.Matrix;
|
||||
AddInstance(t);
|
||||
}
|
||||
@@ -425,13 +422,15 @@ public class Model : IDisposable
|
||||
_vbo.Dispose();
|
||||
_matrixVbo.Dispose();
|
||||
_vao.Dispose();
|
||||
if (HasMorphTargets)
|
||||
Skeleton?.Dispose();
|
||||
for (int socket = 0; socket < Sockets.Length; socket++)
|
||||
{
|
||||
_morphVbo.Dispose();
|
||||
for (var morph = 0; morph < Morphs.Length; morph++)
|
||||
{
|
||||
Morphs[morph].Dispose();
|
||||
}
|
||||
Sockets[socket]?.Dispose();
|
||||
}
|
||||
if (HasMorphTargets) _morphVbo.Dispose();
|
||||
for (var morph = 0; morph < Morphs.Length; morph++)
|
||||
{
|
||||
Morphs[morph]?.Dispose();
|
||||
}
|
||||
|
||||
GL.DeleteProgram(_handle);
|
||||
|
||||
@@ -48,6 +48,6 @@ public class Socket : IDisposable
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
AttachedModels.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user