From bd21425fdfcf2fd3876dc3e1fe980ca1b0409cbf Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 27 Sep 2023 18:31:41 +0200 Subject: [PATCH] Fix issue with unnecessary redrawing during GPose when using redraw-requiring changes. --- Glamourer/Gui/Tabs/DebugTab.cs | 2 +- Glamourer/Interop/Penumbra/PenumbraService.cs | 14 ++++++++++++++ Glamourer/State/StateApplier.cs | 17 ++++++++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Glamourer/Gui/Tabs/DebugTab.cs b/Glamourer/Gui/Tabs/DebugTab.cs index 1220f47..4314de7 100644 --- a/Glamourer/Gui/Tabs/DebugTab.cs +++ b/Glamourer/Gui/Tabs/DebugTab.cs @@ -526,7 +526,7 @@ public unsafe class DebugTab : ITab using (var disabled = ImRaii.Disabled(!_penumbra.Available)) { if (ImGui.SmallButton("Redraw")) - _penumbra.RedrawObject(_objectManager.Objects.GetObjectAddress(_gameObjectIndex), RedrawType.Redraw); + _penumbra.RedrawObject((ObjectIndex) _gameObjectIndex, RedrawType.Redraw); } ImGuiUtil.DrawTableColumn("Last Tooltip Date"); diff --git a/Glamourer/Interop/Penumbra/PenumbraService.cs b/Glamourer/Interop/Penumbra/PenumbraService.cs index 375d148..2bde8d1 100644 --- a/Glamourer/Interop/Penumbra/PenumbraService.cs +++ b/Glamourer/Interop/Penumbra/PenumbraService.cs @@ -11,6 +11,7 @@ using Glamourer.Interop.Structs; using Penumbra.Api; using Penumbra.Api.Enums; using Penumbra.Api.Helpers; +using Penumbra.GameData.Structs; namespace Glamourer.Interop.Penumbra; @@ -239,6 +240,19 @@ public unsafe class PenumbraService : IDisposable } } + /// Try to redraw the given actor. + public void RedrawObject(ObjectIndex index, RedrawType settings) + { + try + { + _redrawSubscriber.Invoke(index.Index, settings); + } + catch (Exception e) + { + PluginLog.Debug($"Failure redrawing object:\n{e}"); + } + } + /// Reattach to the currently running Penumbra IPC provider. Unattaches before if necessary. public void Reattach() { diff --git a/Glamourer/State/StateApplier.cs b/Glamourer/State/StateApplier.cs index 04f1049..88a97e3 100644 --- a/Glamourer/State/StateApplier.cs +++ b/Glamourer/State/StateApplier.cs @@ -1,4 +1,5 @@ using System.Linq; +using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using Glamourer.Customization; using Glamourer.Events; using Glamourer.Interop; @@ -61,7 +62,7 @@ public class StateApplier /// Change the customization values of actors either by applying them via update or redrawing, /// this depends on whether the changes include changes to Race, Gender, Body Type or Face. /// - public void ChangeCustomize(ActorData data, in Customize customize, ActorState? state = null) + public unsafe void ChangeCustomize(ActorData data, in Customize customize, ActorState? state = null) { foreach (var actor in data.Objects) { @@ -71,13 +72,22 @@ public class StateApplier var flags = Customize.Compare(mdl.GetCustomize(), customize); if (!flags.RequiresRedraw() || !mdl.IsHuman) + { _changeCustomize.UpdateCustomize(mdl, customize.Data); + } + else if (data.Objects.Count > 1 && _objects.IsInGPose && !actor.IsGPoseOrCutscene) + { + var mdlCustomize = (Customize*)&mdl.AsHuman->Customize; + mdlCustomize->Load(customize); + } else + { _penumbra.RedrawObject(actor, RedrawType.Redraw); + } } } - /// + /// public ActorData ChangeCustomize(ActorState state, bool apply) { var data = GetData(state); @@ -122,7 +132,8 @@ public class StateApplier // If the source is not IPC we do not want to apply restrictions. var data = GetData(state); if (apply) - ChangeArmor(data, slot, state.ModelData.Armor(slot), state[slot, false] is not StateChanged.Source.Ipc, state.ModelData.IsHatVisible()); + ChangeArmor(data, slot, state.ModelData.Armor(slot), state[slot, false] is not StateChanged.Source.Ipc, + state.ModelData.IsHatVisible()); return data; }