diff --git a/FModel/Views/Snooper/Models/Model.cs b/FModel/Views/Snooper/Models/Model.cs index 5df5b811..63d6ad2a 100644 --- a/FModel/Views/Snooper/Models/Model.cs +++ b/FModel/Views/Snooper/Models/Model.cs @@ -248,6 +248,7 @@ public class Model : IDisposable public void AddInstance(Transform transform) { + SelectedInstance = TransformsCount; TransformsCount++; Transforms.Add(transform); } @@ -262,27 +263,30 @@ public class Model : IDisposable boneMatrix = Skeleton.GetBoneMatrix(boneIndices); var socketRelation = boneMatrix * worldMatrix; - foreach (var attached in socket.AttachedModels) + foreach (var info in socket.AttachedModels) { - if (!options.TryGetModel(attached, out var attachedModel)) + if (!options.TryGetModel(info.Guid, out var attachedModel)) continue; - attachedModel.Transforms[attachedModel.SelectedInstance].Relation = socket.Transform.LocalMatrix * socketRelation; + attachedModel.Transforms[info.Instance].Relation = socket.Transform.LocalMatrix * socketRelation; attachedModel.UpdateMatrices(options); } } } private Matrix4x4 UpdateMatrices() { - var matrix = Transforms[SelectedInstance].Matrix; - if (matrix == _previousMatrix) return matrix; + for (int instance = 0; instance < TransformsCount; instance++) + { + var matrix = Transforms[instance].Matrix; + if (matrix == _previousMatrix) return matrix; - _matrixVbo.Bind(); - _matrixVbo.Update(SelectedInstance, matrix); - _matrixVbo.Unbind(); + _matrixVbo.Bind(); + _matrixVbo.Update(instance, matrix); + _matrixVbo.Unbind(); - _previousMatrix = matrix; - return matrix; + _previousMatrix = matrix; + } + return _previousMatrix; } public void UpdateMorph(int index) @@ -294,7 +298,7 @@ public class Model : IDisposable public void AttachModel(Model attachedTo, Socket socket) { - socket.AttachedModels.Add(Guid); + socket.AttachedModels.Add(new SocketAttachementInfo { Guid = Guid, Instance = SelectedInstance }); _attachedTo = $"'{socket.Name}' from '{attachedTo.Name}'{(!socket.BoneName.IsNone ? $" at '{socket.BoneName}'" : "")}"; attachedTo._attachedFor.Add($"'{Name}'"); @@ -306,7 +310,7 @@ public class Model : IDisposable public void DetachModel(Model attachedTo, Socket socket) { - socket.AttachedModels.Remove(Guid); + socket.AttachedModels.Remove(new SocketAttachementInfo { Guid = Guid, Instance = SelectedInstance }); SafeDetachModel(attachedTo); } diff --git a/FModel/Views/Snooper/Models/Socket.cs b/FModel/Views/Snooper/Models/Socket.cs index 94d6a7d5..e0ede3e5 100644 --- a/FModel/Views/Snooper/Models/Socket.cs +++ b/FModel/Views/Snooper/Models/Socket.cs @@ -7,18 +7,24 @@ using CUE4Parse.UE4.Objects.UObject; namespace FModel.Views.Snooper.Models; +public struct SocketAttachementInfo +{ + public FGuid Guid; + public int Instance; +} + public class Socket : IDisposable { public readonly string Name; public readonly FName BoneName; public readonly Transform Transform; - public readonly List AttachedModels; + public readonly List AttachedModels; private Socket() { Transform = Transform.Identity; - AttachedModels = new List(); + AttachedModels = new List(); } public Socket(string name, FName boneName, Transform transform) : this() diff --git a/FModel/Views/Snooper/Options.cs b/FModel/Views/Snooper/Options.cs index e0d41b0d..3083eda2 100644 --- a/FModel/Views/Snooper/Options.cs +++ b/FModel/Views/Snooper/Options.cs @@ -107,12 +107,12 @@ public class Options { foreach (var socket in model.Sockets) { - foreach (var guid in socket.AttachedModels) + foreach (var info in socket.AttachedModels) { - if (!TryGetModel(guid, out var attachedModel)) continue; + if (!TryGetModel(info.Guid, out var attachedModel)) continue; attachedModel.SafeDetachModel(model); - RemoveModel(guid); + RemoveModel(info.Guid); } socket.Dispose(); } diff --git a/FModel/Views/Snooper/Renderer.cs b/FModel/Views/Snooper/Renderer.cs index c9cee5ec..2bc9f87a 100644 --- a/FModel/Views/Snooper/Renderer.cs +++ b/FModel/Views/Snooper/Renderer.cs @@ -249,7 +249,7 @@ public class Renderer : IDisposable if (Options.TryGetModel(guid, out var model)) { model.AddInstance(Transform.Identity); - Application.Current.Dispatcher.Invoke(() => model.SetupInstances()); + if (select) Application.Current.Dispatcher.Invoke(() => model.SetupInstances()); return guid; } diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index 1d052628..5ba99601 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -420,7 +420,7 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio var i = 0; foreach (var socket in model.Sockets) { - var isAttached = socket.AttachedModels.Contains(selectedModel.Guid); + var isAttached = socket.AttachedModels.Contains(new SocketAttachementInfo { Guid = selectedModel.Guid, Instance = selectedModel.SelectedInstance }); ImGui.PushID(i); ImGui.BeginDisabled(selectedModel.IsAttached && !isAttached); switch (isAttached)