Merge abel stuff
This commit is contained in:
@@ -11,6 +11,7 @@ using LightlessSync.LightlessConfiguration;
|
||||
using LightlessSync.Services;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using LightlessSync.Services.TextureCompression;
|
||||
using LightlessSync.UI.Models;
|
||||
using LightlessSync.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OtterTex;
|
||||
@@ -42,6 +43,7 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
private readonly Progress<TextureConversionProgress> _conversionProgress = new();
|
||||
private readonly IpcManager _ipcManager;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private readonly LightlessConfigService _configService;
|
||||
private readonly PlayerPerformanceConfigService _playerPerformanceConfig;
|
||||
private readonly TransientResourceManager _transientResourceManager;
|
||||
private readonly TransientConfigService _transientConfigService;
|
||||
@@ -106,10 +108,12 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
private TextureUsageCategory? _textureCategoryFilter = null;
|
||||
private TextureMapKind? _textureMapFilter = null;
|
||||
private TextureCompressionTarget? _textureTargetFilter = null;
|
||||
private TextureFormatSortMode _textureFormatSortMode = TextureFormatSortMode.None;
|
||||
|
||||
public DataAnalysisUi(ILogger<DataAnalysisUi> logger, LightlessMediator mediator,
|
||||
CharacterAnalyzer characterAnalyzer, IpcManager ipcManager,
|
||||
PerformanceCollectorService performanceCollectorService, UiSharedService uiSharedService,
|
||||
LightlessConfigService configService,
|
||||
PlayerPerformanceConfigService playerPerformanceConfig, TransientResourceManager transientResourceManager,
|
||||
TransientConfigService transientConfigService, TextureCompressionService textureCompressionService,
|
||||
TextureMetadataHelper textureMetadataHelper)
|
||||
@@ -118,6 +122,7 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
_characterAnalyzer = characterAnalyzer;
|
||||
_ipcManager = ipcManager;
|
||||
_uiSharedService = uiSharedService;
|
||||
_configService = configService;
|
||||
_playerPerformanceConfig = playerPerformanceConfig;
|
||||
_transientResourceManager = transientResourceManager;
|
||||
_transientConfigService = transientConfigService;
|
||||
@@ -971,6 +976,13 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
#if DEBUG
|
||||
ResetDebugCompressionModalState();
|
||||
#endif
|
||||
var savedFormatSort = _configService.Current.TextureFormatSortMode;
|
||||
if (!Enum.IsDefined(typeof(TextureFormatSortMode), savedFormatSort))
|
||||
{
|
||||
savedFormatSort = TextureFormatSortMode.None;
|
||||
}
|
||||
|
||||
SetTextureFormatSortMode(savedFormatSort, persist: false);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
@@ -2198,26 +2210,56 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
ImGui.TableSetupColumn("Original", ImGuiTableColumnFlags.PreferSortDescending);
|
||||
ImGui.TableSetupColumn("Compressed", ImGuiTableColumnFlags.PreferSortDescending);
|
||||
ImGui.TableSetupScrollFreeze(0, 1);
|
||||
ImGui.TableHeadersRow();
|
||||
DrawTextureTableHeaderRow();
|
||||
|
||||
var targets = _textureCompressionService.SelectableTargets;
|
||||
|
||||
IEnumerable<TextureRow> orderedRows = rows;
|
||||
var sortSpecs = ImGui.TableGetSortSpecs();
|
||||
var sizeSortColumn = -1;
|
||||
var sizeSortDirection = ImGuiSortDirection.Ascending;
|
||||
if (sortSpecs.SpecsCount > 0)
|
||||
{
|
||||
var spec = sortSpecs.Specs[0];
|
||||
orderedRows = spec.ColumnIndex switch
|
||||
if (spec.ColumnIndex is 7 or 8)
|
||||
{
|
||||
7 => spec.SortDirection == ImGuiSortDirection.Ascending
|
||||
? rows.OrderBy(r => r.OriginalSize)
|
||||
: rows.OrderByDescending(r => r.OriginalSize),
|
||||
8 => spec.SortDirection == ImGuiSortDirection.Ascending
|
||||
? rows.OrderBy(r => r.CompressedSize)
|
||||
: rows.OrderByDescending(r => r.CompressedSize),
|
||||
_ => rows
|
||||
};
|
||||
sizeSortColumn = spec.ColumnIndex;
|
||||
sizeSortDirection = spec.SortDirection;
|
||||
}
|
||||
}
|
||||
|
||||
var hasSizeSort = sizeSortColumn != -1;
|
||||
var indexedRows = rows.Select((row, idx) => (row, idx));
|
||||
|
||||
if (_textureFormatSortMode != TextureFormatSortMode.None)
|
||||
{
|
||||
bool compressedFirst = _textureFormatSortMode == TextureFormatSortMode.CompressedFirst;
|
||||
int GroupKey(TextureRow row) => row.IsAlreadyCompressed == compressedFirst ? 0 : 1;
|
||||
long SizeKey(TextureRow row) => sizeSortColumn == 7 ? row.OriginalSize : row.CompressedSize;
|
||||
|
||||
var ordered = indexedRows.OrderBy(pair => GroupKey(pair.row));
|
||||
if (hasSizeSort)
|
||||
{
|
||||
ordered = sizeSortDirection == ImGuiSortDirection.Ascending
|
||||
? ordered.ThenBy(pair => SizeKey(pair.row))
|
||||
: ordered.ThenByDescending(pair => SizeKey(pair.row));
|
||||
}
|
||||
|
||||
orderedRows = ordered
|
||||
.ThenBy(pair => pair.idx)
|
||||
.Select(pair => pair.row);
|
||||
}
|
||||
else if (hasSizeSort)
|
||||
{
|
||||
long SizeKey(TextureRow row) => sizeSortColumn == 7 ? row.OriginalSize : row.CompressedSize;
|
||||
|
||||
orderedRows = sizeSortDirection == ImGuiSortDirection.Ascending
|
||||
? indexedRows.OrderBy(pair => SizeKey(pair.row)).ThenBy(pair => pair.idx).Select(pair => pair.row)
|
||||
: indexedRows.OrderByDescending(pair => SizeKey(pair.row)).ThenBy(pair => pair.idx).Select(pair => pair.row);
|
||||
}
|
||||
|
||||
if (sortSpecs.SpecsCount > 0)
|
||||
{
|
||||
sortSpecs.SpecsDirty = false;
|
||||
}
|
||||
|
||||
@@ -2259,6 +2301,79 @@ public class DataAnalysisUi : WindowMediatorSubscriberBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawTextureTableHeaderRow()
|
||||
{
|
||||
ImGui.TableNextRow(ImGuiTableRowFlags.Headers);
|
||||
|
||||
DrawHeaderCell(0, "##select");
|
||||
DrawHeaderCell(1, "Texture");
|
||||
DrawHeaderCell(2, "Slot");
|
||||
DrawHeaderCell(3, "Map");
|
||||
DrawFormatHeaderCell();
|
||||
DrawHeaderCell(5, "Recommended");
|
||||
DrawHeaderCell(6, "Target");
|
||||
DrawHeaderCell(7, "Original");
|
||||
DrawHeaderCell(8, "Compressed");
|
||||
}
|
||||
|
||||
private static void DrawHeaderCell(int columnIndex, string label)
|
||||
{
|
||||
ImGui.TableSetColumnIndex(columnIndex);
|
||||
ImGui.TableHeader(label);
|
||||
}
|
||||
|
||||
private void DrawFormatHeaderCell()
|
||||
{
|
||||
ImGui.TableSetColumnIndex(4);
|
||||
ImGui.TableHeader(GetFormatHeaderLabel());
|
||||
|
||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
|
||||
{
|
||||
CycleTextureFormatSortMode();
|
||||
}
|
||||
|
||||
if (ImGui.IsItemHovered())
|
||||
{
|
||||
ImGui.SetTooltip("Click to cycle sort: normal, compressed first, uncompressed first.");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFormatHeaderLabel()
|
||||
=> _textureFormatSortMode switch
|
||||
{
|
||||
TextureFormatSortMode.CompressedFirst => "Format (C)##formatHeader",
|
||||
TextureFormatSortMode.UncompressedFirst => "Format (U)##formatHeader",
|
||||
_ => "Format##formatHeader"
|
||||
};
|
||||
|
||||
private void SetTextureFormatSortMode(TextureFormatSortMode mode, bool persist = true)
|
||||
{
|
||||
if (_textureFormatSortMode == mode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_textureFormatSortMode = mode;
|
||||
if (persist)
|
||||
{
|
||||
_configService.Current.TextureFormatSortMode = mode;
|
||||
_configService.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private void CycleTextureFormatSortMode()
|
||||
{
|
||||
var nextMode = _textureFormatSortMode switch
|
||||
{
|
||||
TextureFormatSortMode.None => TextureFormatSortMode.CompressedFirst,
|
||||
TextureFormatSortMode.CompressedFirst => TextureFormatSortMode.UncompressedFirst,
|
||||
_ => TextureFormatSortMode.None
|
||||
};
|
||||
|
||||
SetTextureFormatSortMode(nextMode);
|
||||
}
|
||||
|
||||
private void StartTextureConversion()
|
||||
{
|
||||
if (_conversionTask != null && !_conversionTask.IsCompleted)
|
||||
|
||||
@@ -103,10 +103,19 @@ public sealed class DtrEntry : IDisposable, IHostedService
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
await _cancellationTokenSource.CancelAsync().ConfigureAwait(false);
|
||||
_cancellationTokenSource.Cancel();
|
||||
|
||||
if (_dalamudUtilService.IsOnFrameworkThread)
|
||||
{
|
||||
_logger.LogDebug("Skipping Lightfinder DTR wait on framework thread during shutdown.");
|
||||
_cancellationTokenSource.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _runTask!.ConfigureAwait(false);
|
||||
if (_runTask != null)
|
||||
await _runTask.ConfigureAwait(false);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
|
||||
8
LightlessSync/UI/Models/TextureFormatSortMode.cs
Normal file
8
LightlessSync/UI/Models/TextureFormatSortMode.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace LightlessSync.UI.Models;
|
||||
|
||||
public enum TextureFormatSortMode
|
||||
{
|
||||
None = 0,
|
||||
CompressedFirst = 1,
|
||||
UncompressedFirst = 2
|
||||
}
|
||||
@@ -3697,6 +3697,14 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
ImGui.SameLine();
|
||||
_uiShared.DrawNoteLine("! ", UIColors.Get("LightlessYellow"), new SeStringUtils.RichTextEntry("If disabled, saved + effective VRAM usage information will not work.", UIColors.Get("LightlessYellow")));
|
||||
|
||||
var skipPreferredDownscale = textureConfig.SkipTextureDownscaleForPreferredPairs;
|
||||
if (ImGui.Checkbox("Skip downscale for preferred/direct pairs", ref skipPreferredDownscale))
|
||||
{
|
||||
textureConfig.SkipTextureDownscaleForPreferredPairs = skipPreferredDownscale;
|
||||
_playerPerformanceConfigService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("When enabled, textures for direct pairs with preferred permissions are left untouched.");
|
||||
|
||||
if (!textureConfig.EnableNonIndexTextureMipTrim && !textureConfig.EnableIndexTextureDownscale)
|
||||
{
|
||||
UiSharedService.ColorTextWrapped("Both trimming and downscale are disabled. Lightless will keep original textures regardless of size.", UIColors.Get("DimRed"));
|
||||
@@ -3734,8 +3742,31 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
new SeStringUtils.RichTextEntry("destructive", UIColors.Get("DimRed"), true),
|
||||
new SeStringUtils.RichTextEntry(" process and may cause broken or incorrect character appearances."));
|
||||
|
||||
|
||||
_uiShared.DrawNoteLine("! ", UIColors.Get("DimRed"),
|
||||
new SeStringUtils.RichTextEntry("this shit is placeholder still owo"));
|
||||
new SeStringUtils.RichTextEntry("This feature is encouraged to help "),
|
||||
new SeStringUtils.RichTextEntry("lower-end systems with limited VRAM", UIColors.Get("LightlessYellow"), true),
|
||||
new SeStringUtils.RichTextEntry(" and for use in "),
|
||||
new SeStringUtils.RichTextEntry("performance-critical scenarios", UIColors.Get("LightlessYellow"), true),
|
||||
new SeStringUtils.RichTextEntry("."));
|
||||
|
||||
_uiShared.DrawNoteLine("! ", UIColors.Get("DimRed"),
|
||||
new SeStringUtils.RichTextEntry("Runtime decimation "),
|
||||
new SeStringUtils.RichTextEntry("MAY", UIColors.Get("DimRed"), true),
|
||||
new SeStringUtils.RichTextEntry(" cause higher load on the system when processing downloads."));
|
||||
|
||||
_uiShared.DrawNoteLine("!!! ", UIColors.Get("DimRed"),
|
||||
new SeStringUtils.RichTextEntry("When enabled, we cannot provide support for appearance issues caused by this setting!", UIColors.Get("DimRed"), true));
|
||||
|
||||
ImGui.Dummy(new Vector2(15));
|
||||
|
||||
_uiShared.DrawNoteLine("! ", UIColors.Get("LightlessGreen"),
|
||||
new SeStringUtils.RichTextEntry("If a mesh exceeds the "),
|
||||
new SeStringUtils.RichTextEntry("triangle threshold", UIColors.Get("LightlessGreen"), true),
|
||||
new SeStringUtils.RichTextEntry(", it will be decimated automatically to the set "),
|
||||
new SeStringUtils.RichTextEntry("target triangle ratio", UIColors.Get("LightlessGreen"), true),
|
||||
new SeStringUtils.RichTextEntry(". This will reduce quality of the mesh or may break it's intended structure."));
|
||||
|
||||
|
||||
var performanceConfig = _playerPerformanceConfigService.Current;
|
||||
var enableDecimation = performanceConfig.EnableModelDecimation;
|
||||
@@ -3756,11 +3787,19 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
ImGui.SameLine();
|
||||
_uiShared.DrawNoteLine("! ", UIColors.Get("LightlessYellow"), new SeStringUtils.RichTextEntry("If disabled, saved + effective triangle usage information will not work.", UIColors.Get("LightlessYellow")));
|
||||
|
||||
var skipPreferredDecimation = performanceConfig.SkipModelDecimationForPreferredPairs;
|
||||
if (ImGui.Checkbox("Skip decimation for preferred/direct pairs", ref skipPreferredDecimation))
|
||||
{
|
||||
performanceConfig.SkipModelDecimationForPreferredPairs = skipPreferredDecimation;
|
||||
_playerPerformanceConfigService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText("When enabled, models for direct pairs with preferred permissions are left untouched.");
|
||||
|
||||
var triangleThreshold = performanceConfig.ModelDecimationTriangleThreshold;
|
||||
ImGui.SetNextItemWidth(300 * ImGuiHelpers.GlobalScale);
|
||||
if (ImGui.SliderInt("Decimate models above", ref triangleThreshold, 10_000, 100_000))
|
||||
if (ImGui.SliderInt("Decimate models above", ref triangleThreshold, 8_000, 100_000))
|
||||
{
|
||||
performanceConfig.ModelDecimationTriangleThreshold = Math.Clamp(triangleThreshold, 10_000, 100_000);
|
||||
performanceConfig.ModelDecimationTriangleThreshold = Math.Clamp(triangleThreshold, 8_000, 100_000);
|
||||
_playerPerformanceConfigService.Save();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
@@ -3768,7 +3807,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_uiShared.DrawHelpText($"Models below this triangle count are left untouched.{UiSharedService.TooltipSeparator}Default: 50,000");
|
||||
|
||||
var targetPercent = (float)(performanceConfig.ModelDecimationTargetRatio * 100.0);
|
||||
var clampedPercent = Math.Clamp(targetPercent, 70f, 99f);
|
||||
var clampedPercent = Math.Clamp(targetPercent, 60f, 99f);
|
||||
if (Math.Abs(clampedPercent - targetPercent) > float.Epsilon)
|
||||
{
|
||||
performanceConfig.ModelDecimationTargetRatio = clampedPercent / 100.0;
|
||||
@@ -3776,17 +3815,30 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
targetPercent = clampedPercent;
|
||||
}
|
||||
ImGui.SetNextItemWidth(300 * ImGuiHelpers.GlobalScale);
|
||||
if (ImGui.SliderFloat("Target triangle ratio", ref targetPercent, 70f, 99f, "%.0f%%"))
|
||||
if (ImGui.SliderFloat("Target triangle ratio", ref targetPercent, 60f, 99f, "%.0f%%"))
|
||||
{
|
||||
performanceConfig.ModelDecimationTargetRatio = Math.Clamp(targetPercent / 100f, 0.7f, 0.99f);
|
||||
performanceConfig.ModelDecimationTargetRatio = Math.Clamp(targetPercent / 100f, 0.6f, 0.99f);
|
||||
_playerPerformanceConfigService.Save();
|
||||
}
|
||||
_uiShared.DrawHelpText($"Target ratio relative to original triangle count (70% keeps 70% of triangles).{UiSharedService.TooltipSeparator}Default: 70%");
|
||||
_uiShared.DrawHelpText($"Target ratio relative to original triangle count (80% keeps 80% of triangles).{UiSharedService.TooltipSeparator}Default: 80%");
|
||||
|
||||
ImGui.Dummy(new Vector2(5));
|
||||
ImGui.Dummy(new Vector2(15));
|
||||
ImGui.TextUnformatted("Decimation targets");
|
||||
_uiShared.DrawHelpText("Hair mods are always excluded from decimation.");
|
||||
|
||||
_uiShared.DrawNoteLine("! ", UIColors.Get("LightlessGreen"),
|
||||
new SeStringUtils.RichTextEntry("Automatic decimation will only target the selected "),
|
||||
new SeStringUtils.RichTextEntry("decimation targets", UIColors.Get("LightlessGreen"), true),
|
||||
new SeStringUtils.RichTextEntry("."));
|
||||
|
||||
_uiShared.DrawNoteLine("! ", UIColors.Get("LightlessYellow"),
|
||||
new SeStringUtils.RichTextEntry("It is advised to not decimate any body related meshes which includes: "),
|
||||
new SeStringUtils.RichTextEntry("facial mods + sculpts, chest, legs, hands and feet", UIColors.Get("LightlessYellow"), true),
|
||||
new SeStringUtils.RichTextEntry("."));
|
||||
|
||||
_uiShared.DrawNoteLine("!!! ", UIColors.Get("DimRed"),
|
||||
new SeStringUtils.RichTextEntry("Remember, automatic decimation is not perfect and can cause meshes to be ruined, especially hair mods.", UIColors.Get("DimRed"), true));
|
||||
|
||||
var allowBody = performanceConfig.ModelDecimationAllowBody;
|
||||
if (ImGui.Checkbox("Body", ref allowBody))
|
||||
{
|
||||
@@ -3822,6 +3874,10 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
||||
_playerPerformanceConfigService.Save();
|
||||
}
|
||||
|
||||
ImGui.Dummy(new Vector2(5));
|
||||
|
||||
UiSharedService.ColoredSeparator(UIColors.Get("LightlessGrey"), 3f);
|
||||
|
||||
ImGui.Dummy(new Vector2(5));
|
||||
DrawTriangleDecimationCounters();
|
||||
ImGui.Dummy(new Vector2(5));
|
||||
|
||||
@@ -205,10 +205,8 @@ public sealed class ZoneChatUi : WindowMediatorSubscriberBase
|
||||
|
||||
private void ApplyUiVisibilitySettings()
|
||||
{
|
||||
var config = _chatConfigService.Current;
|
||||
_uiBuilder.DisableUserUiHide = true;
|
||||
_uiBuilder.DisableCutsceneUiHide = config.ShowInCutscenes;
|
||||
_uiBuilder.DisableGposeUiHide = config.ShowInGpose;
|
||||
_uiBuilder.DisableCutsceneUiHide = true;
|
||||
}
|
||||
|
||||
private bool ShouldHide()
|
||||
@@ -220,6 +218,16 @@ public sealed class ZoneChatUi : WindowMediatorSubscriberBase
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!config.ShowInGpose && _dalamudUtilService.IsInGpose)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!config.ShowInCutscenes && _dalamudUtilService.IsInCutscene)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (config.HideInCombat && _dalamudUtilService.IsInCombat)
|
||||
{
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user