mirror of
https://github.com/4sval/FModel.git
synced 2026-04-01 14:45:45 -05:00
Merge branch 'dev' into dev
This commit is contained in:
commit
1e3e4df206
|
|
@ -1 +1 @@
|
|||
Subproject commit 566bc1f731b993a09b50772fef8de4d9d5e36243
|
||||
Subproject commit b5a3fd7fc4463740e885ea1d17dc9a1697b3b9b9
|
||||
|
|
@ -123,15 +123,9 @@ public class BaseCommunity : BaseIcon
|
|||
{
|
||||
if (!bShort) return base.GetCosmeticSeason(seasonNumber);
|
||||
var s = seasonNumber["Cosmetics.Filter.Season.".Length..];
|
||||
(int chapterIdx, int seasonIdx) = GetInternalSID(int.Parse(s));
|
||||
return s switch
|
||||
{
|
||||
"10" => $"C{chapterIdx} SX",
|
||||
"27" => $"Fortnite: OG",
|
||||
"32" => $"Fortnite: Remix",
|
||||
"35" => $"C{chapterIdx} MS1",
|
||||
_ => $"C{chapterIdx} S{seasonIdx}"
|
||||
};
|
||||
(string chapterIdx, string seasonIdx, bool onlySeason) = GetInternalSID(s);
|
||||
var prefix = int.TryParse(seasonIdx, out _) ? "S" : "";
|
||||
return onlySeason ? $"{prefix}{seasonIdx}" : $"C{chapterIdx} {prefix}{seasonIdx}";
|
||||
}
|
||||
|
||||
private new void DrawBackground(SKCanvas c)
|
||||
|
|
|
|||
|
|
@ -221,55 +221,32 @@ public class BaseIcon : UCreator
|
|||
return Utils.RemoveHtmlTags(string.Format(format, name));
|
||||
}
|
||||
|
||||
protected (int, int) GetInternalSID(int number)
|
||||
protected (string, string, bool) GetInternalSID(string number)
|
||||
{
|
||||
static int GetSeasonsInChapter(int chapter) => chapter switch
|
||||
{
|
||||
1 => 10,
|
||||
2 => 8,
|
||||
3 => 4,
|
||||
4 => 5,
|
||||
5 => 5,
|
||||
_ => 10
|
||||
};
|
||||
if (!Utils.TryLoadObject("FortniteGame/Plugins/GameFeatures/BattlePassBase/Content/DataTables/Athena_SeasonTitles.Athena_SeasonTitles", out UDataTable seasonTitles) ||
|
||||
!seasonTitles.TryGetDataTableRow(number, StringComparison.InvariantCulture, out var row) ||
|
||||
!row.TryGetValue(out FText chapterText, "DisplayChapterText") ||
|
||||
!row.TryGetValue(out FText seasonText, "DisplaySeasonText") ||
|
||||
!row.TryGetValue(out FName displayType, "DisplayType"))
|
||||
return (string.Empty, string.Empty, true);
|
||||
|
||||
var chapterIdx = 0;
|
||||
var seasonIdx = 0;
|
||||
while (number > 0)
|
||||
{
|
||||
var seasonsInChapter = GetSeasonsInChapter(++chapterIdx);
|
||||
if (number > seasonsInChapter)
|
||||
number -= seasonsInChapter;
|
||||
else
|
||||
{
|
||||
seasonIdx = number;
|
||||
number = 0;
|
||||
}
|
||||
}
|
||||
return (chapterIdx, seasonIdx);
|
||||
var onlySeason = displayType.Text.EndsWith("::OnlySeason") || (chapterText.Text == seasonText.Text && !int.TryParse(seasonText.Text, out _));
|
||||
return (chapterText.Text, seasonText.Text, onlySeason);
|
||||
}
|
||||
|
||||
protected string GetCosmeticSeason(string seasonNumber)
|
||||
{
|
||||
var s = seasonNumber["Cosmetics.Filter.Season.".Length..];
|
||||
var initial = int.Parse(s);
|
||||
(int chapterIdx, int seasonIdx) = GetInternalSID(initial);
|
||||
(string chapterIdx, string seasonIdx, bool onlySeason) = GetInternalSID(s);
|
||||
|
||||
var season = Utils.GetLocalizedResource("AthenaSeasonItemDefinitionInternal", "SeasonTextFormat", "Season {0}");
|
||||
var introduced = Utils.GetLocalizedResource("Fort.Cosmetics", "CosmeticItemDescription_Season", "\nIntroduced in <SeasonText>{0}</>.");
|
||||
if (s == "10") return Utils.RemoveHtmlTags(string.Format(introduced, string.Format(season, "X")));
|
||||
if (initial <= 10) return Utils.RemoveHtmlTags(string.Format(introduced, string.Format(season, s)));
|
||||
if (onlySeason) return Utils.RemoveHtmlTags(string.Format(introduced, string.Format(season, seasonIdx)));
|
||||
|
||||
var chapter = Utils.GetLocalizedResource("AthenaSeasonItemDefinitionInternal", "ChapterTextFormat", "Chapter {0}");
|
||||
var chapterFormat = Utils.GetLocalizedResource("AthenaSeasonItemDefinitionInternal", "ChapterSeasonTextFormat", "{0}, {1}");
|
||||
var d = string.Format(chapterFormat, string.Format(chapter, chapterIdx), string.Format(season, seasonIdx));
|
||||
return s switch
|
||||
{
|
||||
"27" => Utils.RemoveHtmlTags(string.Format(introduced, string.Format("Fortnite: OG"))),
|
||||
"32" => Utils.RemoveHtmlTags(string.Format(introduced, string.Format("Fortnite: Remix"))),
|
||||
"35" => Utils.RemoveHtmlTags(string.Format(introduced, string.Format(chapterFormat, string.Format(chapter, chapterIdx), string.Format("MS1")))),
|
||||
_ => Utils.RemoveHtmlTags(string.Format(introduced, d))
|
||||
};
|
||||
return Utils.RemoveHtmlTags(string.Format(introduced, d));
|
||||
}
|
||||
|
||||
protected void CheckGameplayTags(FInstancedStruct[] dataList)
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ public class BaseIconStats : BaseIcon
|
|||
weaponRowValue.TryGetValue(out float heatMax, "OverheatingMaxValue"); //Maximum heat overheating weapons can hold before they need to cool off
|
||||
weaponRowValue.TryGetValue(out float heatPerShot, "OverheatHeatingValue"); //Heat generated per shot on overheat weapons
|
||||
weaponRowValue.TryGetValue(out float overheatCooldown, "OverheatedCooldownDelay"); //Cooldown after a weapon reaches its maximum heat capacity
|
||||
weaponRowValue.TryGetValue(out int cartridgePerFire, "CartridgePerFire"); //Amount of bullets shot after pressing the fire button once
|
||||
weaponRowValue.TryGetValue(out float burstFiringRate, "BurstFiringRate"); //Item firing rate during a burst, value is shots per second
|
||||
{
|
||||
var multiplier = bpc != 0f ? bpc : 1;
|
||||
if (dmgPb != 0f)
|
||||
|
|
@ -122,7 +124,12 @@ public class BaseIconStats : BaseIcon
|
|||
_statistics.Add(new IconStat(Utils.GetLocalizedResource("", "068239DD4327B36124498C9C5F61C038", "Magazine Size"), clipSize, 40));
|
||||
}
|
||||
|
||||
if (firingRate != 0f)
|
||||
var burstEquation = cartridgePerFire / (((cartridgePerFire - 1f) / burstFiringRate) + (1f / firingRate));
|
||||
if (burstEquation != 0f)
|
||||
{
|
||||
_statistics.Add(new IconStat(Utils.GetLocalizedResource("", "27B80BA44805ABD5A2D2BAB2902B250C", "Fire Rate"), burstEquation, 11));
|
||||
}
|
||||
else if (firingRate != 0f)
|
||||
{
|
||||
_statistics.Add(new IconStat(Utils.GetLocalizedResource("", "27B80BA44805ABD5A2D2BAB2902B250C", "Fire Rate"), firingRate, 11));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,21 @@ public class CustomDirectory : ViewModel
|
|||
new("Shop Backgrounds", "ShooterGame/Content/UI/OutOfGame/MainMenu/Store/Shared/Textures/"),
|
||||
new("Weapon Renders", "ShooterGame/Content/UI/Screens/OutOfGame/MainMenu/Collection/Assets/Large/")
|
||||
};
|
||||
case "Dead by Daylight":
|
||||
return new List<CustomDirectory>
|
||||
{
|
||||
new("Characters V1", "DeadByDaylight/Plugins/DBDCharacters/"),
|
||||
new("Characters V2", "DeadByDaylight/Plugins/Runtime/Bhvr/DBDCharacters/"),
|
||||
new("Characters (Deprecated)", "DeadbyDaylight/Content/Characters/"),
|
||||
new("Meshes", "DeadByDaylight/Content/Meshes/"),
|
||||
new("Textures", "DeadByDaylight/Content/Textures/"),
|
||||
new("Icons", "DeadByDaylight/Content/UI/UMGAssets/Icons/"),
|
||||
new("Blueprints", "DeadByDaylight/Content/Blueprints/"),
|
||||
new("Audio Events", "DeadByDaylight/Content/Audio/Events/"),
|
||||
new("Audio", "DeadByDaylight/Content/WwiseAudio/Cooked/"),
|
||||
new("Data Tables", "DeadByDaylight/Content/Data/"),
|
||||
new("Localization", "DeadByDaylight/Content/Localization/")
|
||||
};
|
||||
default:
|
||||
return new List<CustomDirectory>();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ namespace FModel.Settings
|
|||
CompressionFormat = Default.CompressionFormat,
|
||||
Platform = Default.CurrentDir.TexturePlatform,
|
||||
ExportMorphTargets = Default.SaveMorphTargets,
|
||||
ExportMaterials = Default.SaveEmbeddedMaterials
|
||||
ExportMaterials = Default.SaveEmbeddedMaterials,
|
||||
ExportHdrTexturesAsHdr = Default.SaveHdrTexturesAsHdr
|
||||
};
|
||||
|
||||
private bool _showChangelog = true;
|
||||
|
|
@ -446,6 +447,13 @@ namespace FModel.Settings
|
|||
set => SetProperty(ref _cameraMode, value);
|
||||
}
|
||||
|
||||
private int _wwiseMaxBnkPrefetch;
|
||||
public int WwiseMaxBnkPrefetch
|
||||
{
|
||||
get => _wwiseMaxBnkPrefetch;
|
||||
set => SetProperty(ref _wwiseMaxBnkPrefetch, value);
|
||||
}
|
||||
|
||||
private int _previewMaxTextureSize = 1024;
|
||||
public int PreviewMaxTextureSize
|
||||
{
|
||||
|
|
@ -508,5 +516,12 @@ namespace FModel.Settings
|
|||
get => _saveSkeletonAsMesh;
|
||||
set => SetProperty(ref _saveSkeletonAsMesh, value);
|
||||
}
|
||||
|
||||
private bool _saveHdrTexturesAsHdr = true;
|
||||
public bool SaveHdrTexturesAsHdr
|
||||
{
|
||||
get => _saveHdrTexturesAsHdr;
|
||||
set => SetProperty(ref _saveHdrTexturesAsHdr, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ using CUE4Parse.UE4.Localization;
|
|||
using CUE4Parse.UE4.Objects.Core.Serialization;
|
||||
using CUE4Parse.UE4.Objects.Engine;
|
||||
using CUE4Parse.UE4.Oodle.Objects;
|
||||
using CUE4Parse.UE4.Pak;
|
||||
using CUE4Parse.UE4.Readers;
|
||||
using CUE4Parse.UE4.Shaders;
|
||||
using CUE4Parse.UE4.Versions;
|
||||
|
|
@ -38,7 +39,9 @@ using CUE4Parse.UE4.Wwise;
|
|||
using CUE4Parse_Conversion;
|
||||
using CUE4Parse_Conversion.Sounds;
|
||||
using CUE4Parse.FileProvider.Objects;
|
||||
using CUE4Parse.GameTypes.AshEchoes.FileProvider;
|
||||
using CUE4Parse.UE4.Assets;
|
||||
using CUE4Parse.UE4.BinaryConfig;
|
||||
using CUE4Parse.UE4.Objects.UObject;
|
||||
using CUE4Parse.Utils;
|
||||
using EpicManifestParser;
|
||||
|
|
@ -86,6 +89,13 @@ public class CUE4ParseViewModel : ViewModel
|
|||
set => SetProperty(ref _modelIsOverwritingMaterial, value);
|
||||
}
|
||||
|
||||
private bool _modelIsWaitingAnimation;
|
||||
public bool ModelIsWaitingAnimation
|
||||
{
|
||||
get => _modelIsWaitingAnimation;
|
||||
set => SetProperty(ref _modelIsWaitingAnimation, value);
|
||||
}
|
||||
|
||||
public bool IsSnooperOpen => _snooper is { Exists: true, IsVisible: true };
|
||||
private Snooper _snooper;
|
||||
|
||||
|
|
@ -126,6 +136,8 @@ public class CUE4ParseViewModel : ViewModel
|
|||
public SearchViewModel SearchVm { get; }
|
||||
public TabControlViewModel TabControl { get; }
|
||||
public ConfigIni IoStoreOnDemand { get; }
|
||||
private Lazy<WwiseProvider> _wwiseProviderLazy;
|
||||
public WwiseProvider WwiseProvider => _wwiseProviderLazy.Value;
|
||||
|
||||
public CUE4ParseViewModel()
|
||||
{
|
||||
|
|
@ -164,6 +176,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
[
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\KONAMI\\eFootball\\ST\\Download")
|
||||
], SearchOption.AllDirectories, versionContainer, pathComparer),
|
||||
_ when versionContainer.Game is EGame.GAME_AshEchoes => new AEDefaultFileProvider(gameDirectory, SearchOption.AllDirectories, versionContainer, pathComparer),
|
||||
_ => new DefaultFileProvider(gameDirectory, SearchOption.AllDirectories, versionContainer, pathComparer)
|
||||
};
|
||||
|
||||
|
|
@ -275,6 +288,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
}
|
||||
|
||||
Provider.Initialize();
|
||||
_wwiseProviderLazy = new Lazy<WwiseProvider>(() => new WwiseProvider(Provider, UserSettings.Default.WwiseMaxBnkPrefetch));
|
||||
Log.Information($"{Provider.Versions.Game} ({Provider.Versions.Platform}) | Archives: x{Provider.UnloadedVfs.Count} | AES: x{Provider.RequiredKeys.Count} | Loose Files: x{Provider.Files.Count}");
|
||||
});
|
||||
}
|
||||
|
|
@ -594,6 +608,16 @@ public class CUE4ParseViewModel : ViewModel
|
|||
|
||||
break;
|
||||
}
|
||||
case "ini" when entry.Name.Contains("BinaryConfig"):
|
||||
{
|
||||
var ar = entry.CreateReader();
|
||||
var configCache = new FConfigCacheIni(ar);
|
||||
|
||||
TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("json");
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(configCache, Formatting.Indented), saveProperties, updateUi);
|
||||
|
||||
break;
|
||||
}
|
||||
case "upluginmanifest":
|
||||
case "code-workspace":
|
||||
case "projectstore":
|
||||
|
|
@ -606,6 +630,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case "gitignore":
|
||||
case "LICENSE":
|
||||
case "template":
|
||||
case "stUMeta": // LIS: Double Exposure
|
||||
case "vmodule":
|
||||
case "glslfx":
|
||||
case "cptake":
|
||||
|
|
@ -691,9 +716,11 @@ public class CUE4ParseViewModel : ViewModel
|
|||
var archive = entry.CreateReader();
|
||||
var wwise = new WwiseReader(archive);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(wwise, Formatting.Indented), saveProperties, updateUi);
|
||||
foreach (var (name, data) in wwise.WwiseEncodedMedias)
|
||||
|
||||
var medias = WwiseProvider.ExtractBankSounds(wwise);
|
||||
foreach (var media in medias)
|
||||
{
|
||||
SaveAndPlaySound(entry.Path.SubstringBeforeWithLast('/') + name, "WEM", data);
|
||||
SaveAndPlaySound(media.OutputPath, media.Extension, media.Data);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -772,6 +799,8 @@ public class CUE4ParseViewModel : ViewModel
|
|||
break;
|
||||
}
|
||||
case "res": // just skip
|
||||
case "luac": // compiled lua
|
||||
case "bytes": // wuthering waves
|
||||
break;
|
||||
default:
|
||||
{
|
||||
|
|
@ -878,22 +907,12 @@ public class CUE4ParseViewModel : ViewModel
|
|||
TabControl.SelectedTab.AddImage(sourceFile.SubstringAfterLast('/'), false, bitmap, false, updateUi);
|
||||
return false;
|
||||
}
|
||||
case UAkAudioEvent when isNone && pointer.Object.Value is UAkAudioEvent { EventCookedData: { } wwiseData }:
|
||||
case UAkAudioEvent when isNone && pointer.Object.Value is UAkAudioEvent audioEvent:
|
||||
{
|
||||
foreach (var kvp in wwiseData.EventLanguageMap)
|
||||
var extractedSounds = WwiseProvider.ExtractAudioEventSounds(audioEvent);
|
||||
foreach (var sound in extractedSounds)
|
||||
{
|
||||
if (!kvp.Value.HasValue) continue;
|
||||
|
||||
foreach (var media in kvp.Value.Value.Media)
|
||||
{
|
||||
if (!Provider.TrySaveAsset(Path.Combine("Game/WwiseAudio/", media.MediaPathName.Text), out var data)) continue;
|
||||
|
||||
var namedPath = string.Concat(
|
||||
Provider.ProjectName, "/Content/WwiseAudio/",
|
||||
media.DebugName.Text.SubstringBeforeLast('.').Replace('\\', '/'),
|
||||
" (", kvp.Key.LanguageName.Text, ")");
|
||||
SaveAndPlaySound(namedPath, media.MediaPathName.Text.SubstringAfterLast('.'), data);
|
||||
}
|
||||
SaveAndPlaySound(sound.OutputPath, sound.Extension, sound.Data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -940,7 +959,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
SnooperViewer.Run();
|
||||
return true;
|
||||
}
|
||||
case UAnimSequenceBase when isNone && UserSettings.Default.PreviewAnimations || SnooperViewer.Renderer.Options.ModelIsWaitingAnimation:
|
||||
case UAnimSequenceBase when isNone && UserSettings.Default.PreviewAnimations || ModelIsWaitingAnimation:
|
||||
{
|
||||
// animate all animations using their specified skeleton or when we explicitly asked for a loaded model to be animated (ignoring whether we wanted to preview animations)
|
||||
SnooperViewer.Renderer.Animate(pointer.Object.Value);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public class GameSelectorViewModel : ViewModel
|
|||
yield return GetUnrealEngineGame("9361c8c6d2f34b42b5f2f61093eedf48", "\\TslGame\\Content\\Paks", EGame.GAME_PlayerUnknownsBattlegrounds);
|
||||
yield return GetRiotGame("VALORANT", "ShooterGame\\Content\\Paks", EGame.GAME_Valorant);
|
||||
yield return DirectorySettings.Default("VALORANT [LIVE]", Constants._VAL_LIVE_TRIGGER, ue: EGame.GAME_Valorant);
|
||||
yield return GetSteamGame(381210, "\\DeadByDaylight\\Content\\Paks", EGame.GAME_UE4_27); // Dead By Daylight
|
||||
yield return GetSteamGame(381210, "\\DeadByDaylight\\Content\\Paks", EGame.GAME_DeadByDaylight, aesKey: "0x22b1639b548124925cf7b9cbaa09f9ac295fcf0324586d6b37ee1d42670b39b3"); // Dead By Daylight
|
||||
yield return GetSteamGame(578080, "\\TslGame\\Content\\Paks", EGame.GAME_PlayerUnknownsBattlegrounds); // PUBG
|
||||
yield return GetSteamGame(1172380, "\\SwGame\\Content\\Paks", EGame.GAME_StarWarsJediFallenOrder); // STAR WARS Jedi: Fallen Order™
|
||||
yield return GetSteamGame(677620, "\\PortalWars\\Content\\Paks", EGame.GAME_Splitgate); // Splitgate
|
||||
|
|
@ -151,13 +151,13 @@ public class GameSelectorViewModel : ViewModel
|
|||
return null;
|
||||
}
|
||||
|
||||
private DirectorySettings GetSteamGame(int id, string pakDirectory, EGame ueVersion)
|
||||
private DirectorySettings GetSteamGame(int id, string pakDirectory, EGame ueVersion, string aesKey = "")
|
||||
{
|
||||
var steamInfo = SteamDetection.GetSteamGameById(id);
|
||||
if (steamInfo is not null)
|
||||
{
|
||||
Log.Debug("Found {GameName} in steam manifests", steamInfo.Name);
|
||||
return DirectorySettings.Default(steamInfo.Name, $"{steamInfo.GameRoot}{pakDirectory}", ue: ueVersion);
|
||||
return DirectorySettings.Default(steamInfo.Name, $"{steamInfo.GameRoot}{pakDirectory}", ue: ueVersion, aes: aesKey);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ public class TabImage : ViewModel
|
|||
|
||||
if (PixelFormatUtils.IsHDR(bitmap.PixelFormat) || (UserSettings.Default.TextureExportFormat != ETextureFormat.Jpeg && UserSettings.Default.TextureExportFormat != ETextureFormat.Png))
|
||||
{
|
||||
ImageBuffer = bitmap.Encode(UserSettings.Default.TextureExportFormat, out var ext);
|
||||
ImageBuffer = bitmap.Encode(UserSettings.Default.TextureExportFormat, UserSettings.Default.SaveHdrTexturesAsHdr, out var ext);
|
||||
ExportName += "." + ext;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:FModel"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||
|
|
|
|||
|
|
@ -232,6 +232,11 @@
|
|||
<TextBlock Grid.Row="18" Grid.Column="0" Text="Show Blueprint Decompile" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Shows Decompiled Blueprints in a cpp format" />
|
||||
<CheckBox Grid.Row="18" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
|
||||
IsChecked="{Binding ShowDecompileOption, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 5 0 10"/>
|
||||
|
||||
<TextBlock Grid.Row="18" Grid.Column="0" Text="Max Wwise Bank (.BNK) Prefetch" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<Slider Grid.Row="18" Grid.Column="2" Grid.ColumnSpan="5" TickPlacement="None" Minimum="0" Maximum="512" Ticks="0,2,4,8,16,32,64,128,256,512"
|
||||
AutoToolTipPlacement="BottomRight" IsMoveToPointEnabled="True" IsSnapToTickEnabled="True" Margin="0 5 0 5"
|
||||
Value="{Binding WwiseMaxBnkPrefetch, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="CreatorTemplate">
|
||||
|
|
@ -322,6 +327,7 @@
|
|||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
|
|
@ -494,6 +500,11 @@
|
|||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="20" Grid.Column="0" Text="Save HDR Textures as Radiance .hdr" VerticalAlignment="Center" />
|
||||
<CheckBox Grid.Row="20" Grid.Column="2" Grid.ColumnSpan="3" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
|
||||
IsChecked="{Binding SaveHdrTexturesAsHdr, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"
|
||||
Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Margin="0 5 0 5"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="KeybindingsTemplate">
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ namespace FModel.Views.Snooper;
|
|||
public class Options
|
||||
{
|
||||
public FGuid SelectedModel { get; private set; }
|
||||
public bool ModelIsWaitingAnimation { get; private set; }
|
||||
public int SelectedSection { get; private set; }
|
||||
public int SelectedMorph { get; private set; }
|
||||
public int SelectedAnimation{ get; private set; }
|
||||
|
|
@ -238,7 +237,7 @@ public class Options
|
|||
|
||||
public void AnimateMesh(bool value)
|
||||
{
|
||||
ModelIsWaitingAnimation = value;
|
||||
Services.ApplicationService.ApplicationView.CUE4Parse.ModelIsWaitingAnimation = value;
|
||||
}
|
||||
|
||||
public void ResetModelsLightsAnimations()
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public class Renderer : IDisposable
|
|||
|
||||
public void Animate(UObject anim)
|
||||
{
|
||||
if (!Options.ModelIsWaitingAnimation)
|
||||
if (!Services.ApplicationService.ApplicationView.CUE4Parse.ModelIsWaitingAnimation)
|
||||
{
|
||||
if (anim is UAnimSequenceBase animBase)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -624,6 +624,9 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio
|
|||
ImGui.EndTable();
|
||||
}
|
||||
|
||||
ImGui.SeparatorText("Manual Inputs");
|
||||
model.Transforms[model.SelectedInstance].ImGuiTransform(s.Renderer.CameraOp.Speed / 100f);
|
||||
|
||||
ImGui.EndTabItem();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Numerics;
|
||||
using CUE4Parse.UE4.Objects.Core.Math;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace FModel.Views.Snooper;
|
||||
|
||||
|
|
@ -48,5 +49,55 @@ public class Transform
|
|||
ModifyLocal(_saved.Value);
|
||||
}
|
||||
|
||||
public void ImGuiTransform(float speed)
|
||||
{
|
||||
const float width = 100f;
|
||||
|
||||
if (ImGui.TreeNode("Position"))
|
||||
{
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("X", ref Position.X, speed, 0f, 0f, "%.2f m");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Y", ref Position.Y, speed, 0f, 0f, "%.2f m");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Z", ref Position.Z, speed, 0f, 0f, "%.2f m");
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
if (ImGui.TreeNode("Rotation"))
|
||||
{
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("W", ref Rotation.W, .005f, 0f, 0f, "%.3f rad");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("X", ref Rotation.X, .005f, 0f, 0f, "%.3f rad");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Y", ref Rotation.Y, .005f, 0f, 0f, "%.3f rad");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Z", ref Rotation.Z, .005f, 0f, 0f, "%.3f rad");
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
|
||||
if (ImGui.TreeNode("Scale"))
|
||||
{
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("X", ref Scale.X, speed, 0f, 0f, "%.3f");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Y", ref Scale.Y, speed, 0f, 0f, "%.3f");
|
||||
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.DragFloat("Z", ref Scale.Z, speed, 0f, 0f, "%.3f");
|
||||
|
||||
ImGui.TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => Matrix.Translation.ToString();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user