From 19bf7403f93c96420edfbec5039d4e61a3af4b34 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Sun, 21 Nov 2021 18:21:51 +0100 Subject: [PATCH 01/43] prout --- .github/workflows/main.yml | 4 ++-- FModel/FModel.csproj | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6e9a4217..6c02694b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,10 +21,10 @@ jobs: - name: Fetch Submodules Recursively run: git submodule update --init --recursive - - name: .NET 5 Setup + - name: .NET 6 Setup uses: actions/setup-dotnet@v1 with: - dotnet-version: 5.0.x + dotnet-version: 6.0.x - name: .NET Restore run: dotnet restore FModel diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 28e1b01b..929470cb 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -5,9 +5,9 @@ net6.0-windows true FModel.ico - 4.0.0 - 4.0.2.0 - 4.0.2.0 + 4.1.0 + 4.1.0.0 + 4.1.0.0 false true win-x64 From f2115b5bcc6c4f3fd9e83ab951f6a607cef5c3c3 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Sun, 21 Nov 2021 18:34:10 +0100 Subject: [PATCH 02/43] frustration? --- FModel/Views/SettingsView.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml index 4a3ce0a6..75d1fd6c 100644 --- a/FModel/Views/SettingsView.xaml +++ b/FModel/Views/SettingsView.xaml @@ -363,8 +363,8 @@ - - + Date: Sun, 21 Nov 2021 15:18:44 -0500 Subject: [PATCH 03/43] Update CUE4Parse --- CUE4Parse | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CUE4Parse b/CUE4Parse index d2163de3..ce78d925 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit d2163de354e97a0e62222221b96666a678255884 +Subproject commit ce78d9257da0adaf6c4c151c6fc42b045c170466 From 2dc8ae98fbd588df096710e28148365ddf4baf49 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Mon, 22 Nov 2021 22:46:26 +0100 Subject: [PATCH 04/43] save loaded and appended models --- FModel/ViewModels/ModelViewerViewModel.cs | 10 ++++++++++ FModel/Views/ModelViewer.xaml | 9 +-------- FModel/Views/Resources/Resources.xaml | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/FModel/ViewModels/ModelViewerViewModel.cs b/FModel/ViewModels/ModelViewerViewModel.cs index 3bbf7c4b..06afded6 100644 --- a/FModel/ViewModels/ModelViewerViewModel.cs +++ b/FModel/ViewModels/ModelViewerViewModel.cs @@ -133,7 +133,10 @@ public async Task LoadExport(UObject export) ModelAndCam p; if (AppendMode && CanAppend) + { p = SelectedModel; + _loadedModels.Add(new ModelAndCam(export) {IsVisible = false}); + } else { p = new ModelAndCam(export); @@ -505,6 +508,13 @@ public class ModelAndCam : ViewModel public Geometry3D ZAxis { get; set; } public int TriangleCount { get; set; } + private bool _isVisible = true; + public bool IsVisible + { + get => _isVisible; + set => SetProperty(ref _isVisible, value); + } + private MeshGeometryModel3D _selectedGeometry; // selected material public MeshGeometryModel3D SelectedGeometry { diff --git a/FModel/Views/ModelViewer.xaml b/FModel/Views/ModelViewer.xaml index dc07a792..73ae17d5 100644 --- a/FModel/Views/ModelViewer.xaml +++ b/FModel/Views/ModelViewer.xaml @@ -44,14 +44,7 @@ - - - - - - - + diff --git a/FModel/Views/Resources/Resources.xaml b/FModel/Views/Resources/Resources.xaml index e874d435..060dcf2a 100644 --- a/FModel/Views/Resources/Resources.xaml +++ b/FModel/Views/Resources/Resources.xaml @@ -618,6 +618,25 @@ + + + + + - - - + + + + + + + + + + + + + + + + + + + From 66c8672acea258bd92347cb3de53e8824989b755 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Mon, 6 Dec 2021 00:05:50 +0100 Subject: [PATCH 21/43] map viewer is back --- CUE4Parse | 2 +- FModel/Creator/Bases/FN/BaseIcon.cs | 13 ++- FModel/FModel.csproj | 6 +- FModel/MainWindow.xaml | 38 +++---- FModel/Settings/UserSettings.cs | 2 +- FModel/ViewModels/MapViewerViewModel.cs | 130 ++++-------------------- FModel/Views/MapViewer.xaml | 10 +- 7 files changed, 57 insertions(+), 144 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index 2f2e881f..493afb80 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 2f2e881f50ce8b1fb27b5831227169df1720e436 +Subproject commit 493afb80e59c1c97f4c0435dcfd81c07bf4a553c diff --git a/FModel/Creator/Bases/FN/BaseIcon.cs b/FModel/Creator/Bases/FN/BaseIcon.cs index a58a0aa0..61114b2b 100644 --- a/FModel/Creator/Bases/FN/BaseIcon.cs +++ b/FModel/Creator/Bases/FN/BaseIcon.cs @@ -199,8 +199,17 @@ protected string GetCosmeticSeason(string seasonNumber) { var s = seasonNumber["Cosmetics.Filter.Season.".Length..]; var number = int.Parse(s); - if (number == 10) - s = "X"; + + switch (number) + { + case 10: + s = "X"; + break; + case > 18: + number += 2; + s = number.ToString(); + break; + } var season = Utils.GetLocalizedResource("AthenaSeasonItemDefinitionInternal", "SeasonTextFormat", "Season {0}"); var introduced = Utils.GetLocalizedResource("Fort.Cosmetics", "CosmeticItemDescription_Season", "\nIntroduced in {0}."); diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 929470cb..8a153b12 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -6,12 +6,12 @@ true FModel.ico 4.1.0 - 4.1.0.0 - 4.1.0.0 + 4.1.0.1 + 4.1.0.1 false true win-x64 - true + true true FModel.App diff --git a/FModel/MainWindow.xaml b/FModel/MainWindow.xaml index 035b37ae..b0f7a876 100644 --- a/FModel/MainWindow.xaml +++ b/FModel/MainWindow.xaml @@ -177,25 +177,25 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/FModel/Settings/UserSettings.cs b/FModel/Settings/UserSettings.cs index f383972c..8fdf63a6 100644 --- a/FModel/Settings/UserSettings.cs +++ b/FModel/Settings/UserSettings.cs @@ -235,7 +235,7 @@ public IDictionary Presets private IDictionary _overridedGame = new Dictionary { {FGame.Unknown, EGame.GAME_UE4_LATEST}, - {FGame.FortniteGame, EGame.GAME_UE4_LATEST}, + {FGame.FortniteGame, EGame.GAME_UE5_LATEST}, {FGame.ShooterGame, EGame.GAME_Valorant}, {FGame.DeadByDaylight, EGame.GAME_UE4_LATEST}, {FGame.OakGame, EGame.GAME_Borderlands3}, diff --git a/FModel/ViewModels/MapViewerViewModel.cs b/FModel/ViewModels/MapViewerViewModel.cs index 556650c3..9c01248c 100644 --- a/FModel/ViewModels/MapViewerViewModel.cs +++ b/FModel/ViewModels/MapViewerViewModel.cs @@ -10,6 +10,7 @@ using CUE4Parse.UE4.Assets.Objects; using CUE4Parse.UE4.Objects.Core.i18N; using CUE4Parse.UE4.Objects.Core.Math; +using CUE4Parse.UE4.Objects.GameplayTags; using CUE4Parse.UE4.Objects.UObject; using FModel.Creator; using FModel.Extensions; @@ -95,13 +96,6 @@ public bool BrFireflies set => SetProperty(ref _brFireflies, value, "ApolloGameplay_Fireflies"); } - private bool _brCubeMovements; - public bool BrCubeMovements - { - get => _brCubeMovements; - set => SetProperty(ref _brCubeMovements, value, "ApolloGameplay_CubeMovements"); - } - private bool _prLandmarks; public bool PrLandmarks { @@ -276,9 +270,6 @@ private async void GenericToggle(string key, bool enabled) case "ApolloGameplay_Fireflies": await LoadFireflies(); break; - case "ApolloGameplay_CubeMovements": - await LoadCubeMovements(); - break; case "PapayaGameplay_CannonballGame": await LoadCannonballGame(); break; @@ -383,13 +374,13 @@ private async Task LoadBrMiniMap() await _threadWorkerView.Begin(_ => { - if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerBR.Default__UIMapManagerBR_C", out UObject mapManager) || - !mapManager.TryGetValue(out UObject mapMaterial, "MapMaterial") || - !mapMaterial.TryGetValue(out FStructFallback cachedExpressionData, "CachedExpressionData") || - !cachedExpressionData.TryGetValue(out FStructFallback parameters, "Parameters") || - !parameters.TryGetValue(out UTexture2D[] textureValues, "TextureValues")) return; + // if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerBR.Default__UIMapManagerBR_C", out UObject mapManager) || + // !mapManager.TryGetValue(out UObject mapMaterial, "MapMaterial") || + // !mapMaterial.TryGetValue(out FStructFallback cachedExpressionData, "CachedExpressionData") || + // !cachedExpressionData.TryGetValue(out FStructFallback parameters, "Parameters") || + // !parameters.TryGetValue(out UTexture2D[] textureValues, "TextureValues")) return; - _bitmaps[0][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap(textureValues[0]), IsEnabled = true}; + _bitmaps[0][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap("FortniteGame/Content/Athena/Apollo/Maps/UI/Apollo_Terrain_Minimap.Apollo_Terrain_Minimap"), IsEnabled = true}; _brMiniMapImage = GetImageSource(_bitmaps[0][_FIRST_BITMAP].Layer); }); } @@ -401,11 +392,11 @@ private async Task LoadPrMiniMap() await _threadWorkerView.Begin(_ => { - if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerPapaya.Default__UIMapManagerPapaya_C", out UObject mapManager) || - !mapManager.TryGetValue(out UMaterial mapMaterial, "MapMaterial") || - mapMaterial.ReferencedTextures.Count < 1) return; + // if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerPapaya.Default__UIMapManagerPapaya_C", out UObject mapManager) || + // !mapManager.TryGetValue(out UMaterial mapMaterial, "MapMaterial") || + // mapMaterial.ReferencedTextures.Count < 1) return; - _bitmaps[1][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap(mapMaterial.ReferencedTextures[0] as UTexture2D), IsEnabled = true}; + _bitmaps[1][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap("FortniteGame/Content/Athena/Apollo/Maps/Special/Papaya/UI/MiniMapPapaya.MiniMapPapaya"), IsEnabled = true}; _prMiniMapImage = GetImageSource(_bitmaps[1][_FIRST_BITMAP].Layer); }); } @@ -474,12 +465,16 @@ await _threadWorkerView.Begin(_ => var patrolsPathBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); using var c = new SKCanvas(patrolsPathBitmap); - var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Apollo_Terrain_NPCLibrary_Overlay_S18"); + var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Artemis_Overlay_S19_NPCLibrary"); foreach (var export in exports) { if (!export.ExportType.Equals("FortAthenaPatrolPath", StringComparison.OrdinalIgnoreCase) || !export.TryGetValue(out FPackageIndex[] patrolPoints, "PatrolPoints")) continue; + var displayName = export.Name["FortAthenaPatrolPath_".Length..]; + if (export.TryGetValue(out FGameplayTagContainer gameplayTags, "GameplayTags") && gameplayTags.GameplayTags.Length > 0) + displayName = gameplayTags.GameplayTags[0].Text["Athena.AI.SpawnLocation.Tandem.".Length..]; + if (!Utils.TryGetPackageIndexExport(patrolPoints[0], out UObject uObject) || !uObject.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || !Utils.TryGetPackageIndexExport(rootComponent, out uObject) || @@ -487,7 +482,6 @@ await _threadWorkerView.Begin(_ => var path = new SKPath(); var vector = GetMapPosition(relativeLocation, _brRadius); - var displayName = export.Name["FortAthenaPatrolPath_Tandem_S18_".Length..]; path.MoveTo(vector.X, vector.Y); for (var i = 1; i < patrolPoints.Length; i++) @@ -737,7 +731,7 @@ await _threadWorkerView.Begin(_ => var upgradeBenchesBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); using var c = new SKCanvas(upgradeBenchesBitmap); - var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Apollo_Terrain_NPCLibrary_Stations_UpgradeBenches"); + var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Artemis_Overlay_S19_UpgradeBenches"); foreach (var export in exports) { if (!export.ExportType.Equals("B_Athena_Spawner_UpgradeStation_C", StringComparison.OrdinalIgnoreCase)) continue; @@ -793,7 +787,7 @@ await _threadWorkerView.Begin(_ => var vendingMachinesBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); using var c = new SKCanvas(vendingMachinesBitmap); - var exports = Utils.LoadExports("FortniteGame/Content/Athena/Apollo/Maps/Special/ItemCollections/Apollo_Item_VendingMachines"); + var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Artemis_Overlay_S19_ServiceStations"); foreach (var export in exports) { if (!export.ExportType.Equals("B_Athena_Spawner_VendingMachine_MendingOnly_C", StringComparison.OrdinalIgnoreCase) && @@ -874,93 +868,5 @@ await _threadWorkerView.Begin(_ => _bitmaps[0]["ApolloGameplay_TagsLocation"] = new MapLayer {Layer = tagsLocationBitmap, IsEnabled = false}; }); } - - /// - /// FortniteGame/Plugins/GameFeatures/CorruptionGameplay/Content/CorruptionGameplay_LevelOverlay.uasset - /// too lazy to filters - /// - private async Task LoadCubeMovements() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var cubeMovementsBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(cubeMovementsBitmap); - - if (!Utils.TryLoadObject("/CorruptionGameplay/Levels/CorruptionGameplay_ApolloTerrain_Overlay.BP_CubeMovementGradient_2", out UObject overlay) || - !overlay.TryGetValue(out FSoftObjectPath[] cubeMovementStaticPaths, "cubeMovementStaticPaths") || cubeMovementStaticPaths.Length < 1) - return; - - var oldColor = _pathPaint.Color; - _pathPaint.Color = SKColors.Purple; - foreach (var cubeMovementStaticPath in cubeMovementStaticPaths) - { - var objectPath = cubeMovementStaticPath.AssetPathName.Text.SubstringBeforeLast("."); - var objectName = cubeMovementStaticPath.SubPathString.SubstringAfterLast("."); - if (!Utils.TryLoadObject($"{objectPath}.{objectName}", out UObject staticPath)) - return; - - DrawCubeMovements(c, staticPath, true); - } - - if (Utils.TryLoadObject("/CorruptionGameplay/Levels/CubeMovement/Apollo_CM_Gold_Overlay.CM_Spline_Gold", out UObject goldPath)) - { - _pathPaint.Color = SKColors.Gold; - DrawCubeMovements(c, goldPath, false); - } - - _pathPaint.Color = oldColor; - _bitmaps[0]["ApolloGameplay_CubeMovements"] = new MapLayer {Layer = cubeMovementsBitmap, IsEnabled = false}; - }); - } - - private void DrawCubeMovements(SKCanvas c, UObject staticPath, bool fixLocation) - { - if (!staticPath.TryGetValue(out FStructFallback[] pathTravelers, "PathTravelers") || pathTravelers.Length < 1 || - !pathTravelers[0].TryGetValue(out FPackageIndex[] generatedSplinesArray, "GeneratedSplinesArray") || generatedSplinesArray.Length < 1) - return; - - UObject uObject; - var parentRelativeLocation = new FVector(); - if (fixLocation) - { - if (!pathTravelers[0].TryGetValue(out FPackageIndex pathTraveler, "PathTraveler") || - !Utils.TryGetPackageIndexExport(pathTraveler, out uObject) || - !uObject.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out uObject) || - !uObject.TryGetValue(out parentRelativeLocation, "RelativeLocation")) - return; - } - - var bDone = false; - var path = new SKPath(); - foreach (var generatedSpline in generatedSplinesArray) - { - if (!Utils.TryGetPackageIndexExport(generatedSpline, out uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - if (!uObject.TryGetValue(out FStructFallback splineCurves, "SplineCurves") || - !splineCurves.TryGetValue(out FStructFallback positions, "Position") || - !positions.TryGetValue(out FStructFallback[] positionPoints, "Points")) continue; - - foreach (var positionPoint in positionPoints) - { - if (!positionPoint.TryGetValue(out FVector point, "OutVal")) continue; - - var vector = GetMapPosition(parentRelativeLocation + relativeLocation + point, _brRadius); - if (!bDone) - { - path.MoveTo(vector.X, vector.Y); - bDone = true; - } - else - { - path.LineTo(vector.X, vector.Y); - } - } - } - - c.DrawPath(path, _pathPaint); - } } } diff --git a/FModel/Views/MapViewer.xaml b/FModel/Views/MapViewer.xaml index a19778f7..b2b6dc60 100644 --- a/FModel/Views/MapViewer.xaml +++ b/FModel/Views/MapViewer.xaml @@ -33,14 +33,12 @@ DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.MapViewer}}}" IsEnabled="{Binding IsReady}" /> - + + - - + + From 7f14a5ca05bf0315f7896b313efe5fb16ea4f9cb Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Mon, 6 Dec 2021 13:48:50 +0100 Subject: [PATCH 22/43] improved model settings close #222 --- FModel/Creator/Bases/FN/BaseCommunity.cs | 15 +++- FModel/MainWindow.xaml | 16 ----- FModel/MainWindow.xaml.cs | 5 -- FModel/Settings/UserSettings.cs | 87 +++++++++++++++++++----- FModel/ViewModels/CUE4ParseViewModel.cs | 9 ++- FModel/Views/SettingsView.xaml | 58 +++++++++------- 6 files changed, 122 insertions(+), 68 deletions(-) diff --git a/FModel/Creator/Bases/FN/BaseCommunity.cs b/FModel/Creator/Bases/FN/BaseCommunity.cs index d0066e94..0ae9ceb3 100644 --- a/FModel/Creator/Bases/FN/BaseCommunity.cs +++ b/FModel/Creator/Bases/FN/BaseCommunity.cs @@ -102,10 +102,19 @@ private string GetCosmeticSeason(string seasonNumber, bool bShort) if (!bShort) return base.GetCosmeticSeason(seasonNumber); var s = seasonNumber["Cosmetics.Filter.Season.".Length..]; var number = int.Parse(s); - if (number == 10) - s = "X"; - return number > 10 ? $"C{number / 10 + 1} S{s[^1..]}" : $"C1 S{s}"; + switch (number) + { + case 10: + s = "X"; + break; + case > 18: + number += 2; + s = number.ToString(); + break; + } + + return $"C{number / 10 + 1} S{s[^1..]}"; } private new void DrawBackground(SKCanvas c) diff --git a/FModel/MainWindow.xaml b/FModel/MainWindow.xaml index b0f7a876..33c357cd 100644 --- a/FModel/MainWindow.xaml +++ b/FModel/MainWindow.xaml @@ -162,9 +162,6 @@ - @@ -866,19 +863,6 @@ - - - - - - - diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index c0983618..53f5a506 100644 --- a/FModel/MainWindow.xaml.cs +++ b/FModel/MainWindow.xaml.cs @@ -37,8 +37,6 @@ public MainWindow() {new KeyGesture(UserSettings.Default.AutoSaveAnimations.Key, UserSettings.Default.AutoSaveAnimations.Modifiers)}), OnAutoTriggerExecuted)); CommandBindings.Add(new CommandBinding(new RoutedCommand("AutoOpenSounds", typeof(MainWindow), new InputGestureCollection {new KeyGesture(UserSettings.Default.AutoOpenSounds.Key, UserSettings.Default.AutoOpenSounds.Modifiers)}), OnAutoTriggerExecuted)); - CommandBindings.Add(new CommandBinding(new RoutedCommand("AutoOpenMeshes", typeof(MainWindow), new InputGestureCollection - {new KeyGesture(UserSettings.Default.AutoOpenMeshes.Key, UserSettings.Default.AutoOpenMeshes.Modifiers)}), OnAutoTriggerExecuted)); CommandBindings.Add(new CommandBinding(new RoutedCommand("ReloadMappings", typeof(MainWindow), new InputGestureCollection {new KeyGesture(Key.F12)}), OnMappingsReload)); CommandBindings.Add(new CommandBinding(ApplicationCommands.Find, (s, e) => OnOpenAvalonFinder())); @@ -152,9 +150,6 @@ private void OnAutoTriggerExecuted(object sender, ExecutedRoutedEventArgs e) case "AutoOpenSounds": UserSettings.Default.IsAutoOpenSounds = !UserSettings.Default.IsAutoOpenSounds; break; - case "AutoOpenMeshes": - UserSettings.Default.IsAutoOpenMeshes = !UserSettings.Default.IsAutoOpenMeshes; - break; } } diff --git a/FModel/Settings/UserSettings.cs b/FModel/Settings/UserSettings.cs index 8fdf63a6..77fa8508 100644 --- a/FModel/Settings/UserSettings.cs +++ b/FModel/Settings/UserSettings.cs @@ -100,13 +100,6 @@ public bool IsAutoOpenSounds set => SetProperty(ref _isAutoOpenSounds, value); } - private bool _isAutoOpenMeshes = true; - public bool IsAutoOpenMeshes - { - get => _isAutoOpenMeshes; - set => SetProperty(ref _isAutoOpenMeshes, value); - } - private bool _isLoggerExpanded = true; public bool IsLoggerExpanded { @@ -478,13 +471,6 @@ public Hotkey AutoOpenSounds set => SetProperty(ref _autoOpenSounds, value); } - private Hotkey _autoOpenMeshes = new(Key.F6); - public Hotkey AutoOpenMeshes - { - get => _autoOpenMeshes; - set => SetProperty(ref _autoOpenMeshes, value); - } - private Hotkey _addAudio = new(Key.N, ModifierKeys.Control); public Hotkey AddAudio { @@ -527,11 +513,76 @@ public ELodFormat LodExportFormat set => SetProperty(ref _lodExportFormat, value); } - private bool _openMaterialsInModelViewer = true; - public bool OpenMaterialsInModelViewer + private bool _previewStaticMeshes = true; + public bool PreviewStaticMeshes + { + get => _previewStaticMeshes; + set + { + SetProperty(ref _previewStaticMeshes, value); + if (_previewStaticMeshes && SaveStaticMeshes) + SaveStaticMeshes = false; + } + } + + private bool _previewSkeletalMeshes = true; + public bool PreviewSkeletalMeshes + { + get => _previewSkeletalMeshes; + set + { + SetProperty(ref _previewSkeletalMeshes, value); + if (_previewSkeletalMeshes && SaveSkeletalMeshes) + SaveSkeletalMeshes = false; + } + } + + private bool _previewMaterials = true; + public bool PreviewMaterials { - get => _openMaterialsInModelViewer; - set => SetProperty(ref _openMaterialsInModelViewer, value); + get => _previewMaterials; + set + { + SetProperty(ref _previewMaterials, value); + if (_previewMaterials && SaveMaterials) + SaveMaterials = false; + } + } + + private bool _saveStaticMeshes; + public bool SaveStaticMeshes + { + get => _saveStaticMeshes; + set + { + SetProperty(ref _saveStaticMeshes, value); + if (_saveStaticMeshes && PreviewStaticMeshes) + PreviewStaticMeshes = false; + } + } + + private bool _saveSkeletalMeshes; + public bool SaveSkeletalMeshes + { + get => _saveSkeletalMeshes; + set + { + SetProperty(ref _saveSkeletalMeshes, value); + if (_saveSkeletalMeshes && PreviewSkeletalMeshes) + PreviewSkeletalMeshes = false; + } + } + + private bool _saveMaterials; + public bool SaveMaterials + { + get => _saveMaterials; + set + { + SetProperty(ref _saveMaterials, value); + if (_saveMaterials && PreviewMaterials) + PreviewMaterials = false; + } } private bool _saveSkeletonAsMesh; diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index 994ef42f..36596076 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -670,9 +670,9 @@ public void ExtractAndScroll(string fullPath, string objectName) SaveAndPlaySound(Path.Combine(TabControl.SelectedTab.Directory, TabControl.SelectedTab.Header.SubstringBeforeLast('.')).Replace('\\', '/'), audioFormat, data); return false; } - case UStaticMesh when UserSettings.Default.IsAutoOpenMeshes: - case USkeletalMesh when UserSettings.Default.IsAutoOpenMeshes: - case UMaterialInstance when UserSettings.Default.OpenMaterialsInModelViewer && !ModelIsSwappingMaterial && + case UStaticMesh when UserSettings.Default.PreviewStaticMeshes: + case USkeletalMesh when UserSettings.Default.PreviewSkeletalMeshes: + case UMaterialInstance when UserSettings.Default.PreviewMaterials && !ModelIsSwappingMaterial && !(Game == FGame.FortniteGame && export.Owner != null && (export.Owner.Name.EndsWith($"/MI_OfferImages/{export.Name}", StringComparison.OrdinalIgnoreCase) || export.Owner.Name.EndsWith($"/RenderSwitch_Materials/{export.Name}", StringComparison.OrdinalIgnoreCase) || export.Owner.Name.EndsWith($"/MI_BPTile/{export.Name}", StringComparison.OrdinalIgnoreCase))): @@ -693,6 +693,9 @@ public void ExtractAndScroll(string fullPath, string objectName) }); return true; } + case UStaticMesh when UserSettings.Default.SaveStaticMeshes: + case USkeletalMesh when UserSettings.Default.SaveSkeletalMeshes: + case UMaterialInstance when UserSettings.Default.SaveMaterials: case USkeleton when UserSettings.Default.SaveSkeletonAsMesh: case UAnimSequence when UserSettings.Default.IsAutoSaveAnimations: { diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml index defe4685..c2596baa 100644 --- a/FModel/Views/SettingsView.xaml +++ b/FModel/Views/SettingsView.xaml @@ -236,6 +236,7 @@ + @@ -263,20 +264,35 @@ - - - - - + + + + + + + + + + + + + + + - + - - + @@ -307,7 +323,6 @@ - @@ -354,23 +369,20 @@ - - - + - - + - - + - - + - - + From 845542a6bfcea7644cde254cf8cc732a02857765 Mon Sep 17 00:00:00 2001 From: MountainFlash Date: Mon, 6 Dec 2021 22:32:27 +0530 Subject: [PATCH 23/43] save models as scene Ctrl + S -> Save Ctrl + Shift + S -> Save as Scene --- FModel/ViewModels/ModelViewerViewModel.cs | 106 ++++++++++++++++++++++ FModel/Views/ModelViewer.xaml.cs | 6 ++ 2 files changed, 112 insertions(+) diff --git a/FModel/ViewModels/ModelViewerViewModel.cs b/FModel/ViewModels/ModelViewerViewModel.cs index decc2d93..4b8cc2c5 100644 --- a/FModel/ViewModels/ModelViewerViewModel.cs +++ b/FModel/ViewModels/ModelViewerViewModel.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; +using System.Numerics; using System.Threading.Tasks; using System.Windows; using System.Windows.Data; @@ -13,7 +15,10 @@ using CUE4Parse.UE4.Assets.Exports.StaticMesh; using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse.UE4.Objects.Core.Math; +using CUE4Parse.Utils; +using CUE4Parse_Conversion.Materials; using CUE4Parse_Conversion.Meshes; +using CUE4Parse_Conversion.Meshes.glTF; using CUE4Parse_Conversion.Meshes.PSK; using CUE4Parse_Conversion.Textures; using FModel.Framework; @@ -25,10 +30,18 @@ using Ookii.Dialogs.Wpf; using Serilog; using SharpDX; +using SharpGLTF.Geometry; +using SharpGLTF.Geometry.VertexTypes; +using SharpGLTF.Scenes; +using SharpGLTF.Schema2; +using SharpGLTF.Transforms; using SkiaSharp; using Camera = HelixToolkit.Wpf.SharpDX.Camera; using Geometry3D = HelixToolkit.SharpDX.Core.Geometry3D; using PerspectiveCamera = HelixToolkit.Wpf.SharpDX.PerspectiveCamera; +using Vector2 = SharpDX.Vector2; +using Vector3 = SharpDX.Vector3; +using VERTEX = SharpGLTF.Geometry.VertexTypes.VertexPositionNormalTangent; namespace FModel.ViewModels { @@ -188,6 +201,99 @@ public void SaveLoadedModels() } } + public bool CheckIfSaved(string path) + { + if (File.Exists(path)) + { + Log.Information("Successfully saved {FileName}", path); + FLogger.AppendInformation(); + FLogger.AppendText($"Successfully saved {path}", Constants.WHITE, true); + return true; + } + else + { + Log.Error("{FileName} could not be saved", path); + FLogger.AppendError(); + FLogger.AppendText($"Could not save '{path}'", Constants.WHITE, true); + return false; + } + } + + public void SaveAsScene() + { + if (_loadedModels.Count < 1) return; + + var fileBrowser = new VistaSaveFileDialog() + { + Title = "Save Loaded Models As...", + DefaultExt = ".glb", + Filter = "glTF Binary File (*.glb)|*.glb|glTF ASCII File (*.gltf)|*.gltf|All Files(*.*)|*.*", + AddExtension = true, + OverwritePrompt = true, + CheckPathExists = true, + }; + + if (fileBrowser.ShowDialog() == false || string.IsNullOrEmpty(fileBrowser.FileName)) return; + + var sceneBuilder = new SceneBuilder(); + var materialExports = new List(); + foreach (var model in _loadedModels) + { + switch (model.Export) + { + case UStaticMesh sm: + { + var mesh = new MeshBuilder(sm.Name); + if (sm.TryConvert(out var convertedMesh) && convertedMesh.LODs.Count > 0) + { + var lod = convertedMesh.LODs.First(); + for (var i = 0; i < lod.Sections.Value.Length; i++) + { + Gltf.ExportStaticMeshSections(i, lod, lod.Sections.Value[i], materialExports, mesh); + } + sceneBuilder.AddRigidMesh(mesh, AffineTransform.Identity); + } + break; + } + case USkeletalMesh sk: + { + var mesh = new MeshBuilder(sk.Name); + + if (sk.TryConvert(out var convertedMesh) && convertedMesh.LODs.Count > 0) + { + var lod = convertedMesh.LODs.First(); + for (var i = 0; i < lod.Sections.Value.Length; i++) + { + Gltf.ExportSkelMeshSections(i, lod, lod.Sections.Value[i], materialExports, mesh); + } + var armatureNodeBuilder = new NodeBuilder(sk.Name+".ao"); + var armature = Gltf.CreateGltfSkeleton(convertedMesh.RefSkeleton, armatureNodeBuilder); + sceneBuilder.AddSkinnedMesh(mesh, Matrix4x4.Identity, armature); + } + break; + } + } + } + + var scene = sceneBuilder.ToGltf2(); + var fileName = fileBrowser.FileName; + if (fileName.EndsWith(".glb", StringComparison.OrdinalIgnoreCase)) + scene.SaveGLB(fileName); + else if (fileName.EndsWith(".gltf", StringComparison.OrdinalIgnoreCase)) + scene.SaveGLTF(fileName); + else if (fileName.EndsWith(".obj", StringComparison.OrdinalIgnoreCase)) + scene.SaveAsWavefront(fileName); + else + throw new ArgumentOutOfRangeException(nameof(fileName),$@"Unknown file format {fileName. SubstringAfterWithLast('.')}"); + + if (!CheckIfSaved(fileName)) return; + foreach (var materialExport in materialExports) + { + materialExport.TryWriteToDir(new DirectoryInfo(StringUtils.SubstringBeforeWithLast(fileName, '\\')), + out var _); + } + } + public void CopySelectedMaterialName() { if (SelectedModel is not { } m || m.SelectedGeometry is null) diff --git a/FModel/Views/ModelViewer.xaml.cs b/FModel/Views/ModelViewer.xaml.cs index 6f0ef587..0993e361 100644 --- a/FModel/Views/ModelViewer.xaml.cs +++ b/FModel/Views/ModelViewer.xaml.cs @@ -71,6 +71,12 @@ private void OnWindowKeyDown(object sender, KeyEventArgs e) case Key.Decimal: _applicationView.ModelViewer.FocusOnSelectedMesh(); break; + case Key.S when Keyboard.Modifiers.HasFlag(ModifierKeys.Control) && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift): + _applicationView.ModelViewer.SaveAsScene(); + break; + case Key.S when Keyboard.Modifiers.HasFlag(ModifierKeys.Control): + _applicationView.ModelViewer.SaveLoadedModels(); + break; } } From b3d7930fc07798dcc8151de847a871bd097ab4ce Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Mon, 6 Dec 2021 18:06:06 +0100 Subject: [PATCH 24/43] fixed margins --- CUE4Parse | 2 +- FModel/Views/SettingsView.xaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index 493afb80..92a42455 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 493afb80e59c1c97f4c0435dcfd81c07bf4a553c +Subproject commit 92a42455893c21059bda79953d78f6f14b2956db diff --git a/FModel/Views/SettingsView.xaml b/FModel/Views/SettingsView.xaml index c2596baa..8d50380a 100644 --- a/FModel/Views/SettingsView.xaml +++ b/FModel/Views/SettingsView.xaml @@ -265,7 +265,7 @@ - + - + - - + From 9d2181b26001ff037e6af0dfa89fe71e577ade43 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Mon, 6 Dec 2021 21:35:55 +0100 Subject: [PATCH 25/43] dedicated model directory --- FModel/App.xaml.cs | 4 +- FModel/MainWindow.xaml | 16 ------ FModel/MainWindow.xaml.cs | 5 -- FModel/Settings/UserSettings.cs | 30 +++++------ FModel/ViewModels/CUE4ParseViewModel.cs | 4 +- FModel/ViewModels/ModelViewerViewModel.cs | 41 +++++++------- FModel/ViewModels/SettingsViewModel.cs | 3 ++ FModel/Views/SettingsView.xaml | 66 +++++++++++++---------- FModel/Views/SettingsView.xaml.cs | 5 +- 9 files changed, 83 insertions(+), 91 deletions(-) diff --git a/FModel/App.xaml.cs b/FModel/App.xaml.cs index 16ad94dc..b10a118f 100644 --- a/FModel/App.xaml.cs +++ b/FModel/App.xaml.cs @@ -44,9 +44,9 @@ protected override void OnStartup(StartupEventArgs e) } if (!Directory.Exists(UserSettings.Default.OutputDirectory)) - { UserSettings.Default.OutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Output"); - } + if (!Directory.Exists(UserSettings.Default.ModelDirectory)) + UserSettings.Default.ModelDirectory = Path.Combine(UserSettings.Default.OutputDirectory, "Saves"); Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FModel")); Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, "Backups")); diff --git a/FModel/MainWindow.xaml b/FModel/MainWindow.xaml index 33c357cd..757411ec 100644 --- a/FModel/MainWindow.xaml +++ b/FModel/MainWindow.xaml @@ -156,9 +156,6 @@ - @@ -838,19 +835,6 @@ - - - - - - - - + + + + + + + + + + + - + From a6d62d91bf642ebcc03e1f9f93bbf346ebcb4869 Mon Sep 17 00:00:00 2001 From: Not Officer Date: Wed, 8 Dec 2021 08:30:46 +0100 Subject: [PATCH 30/43] Update CUE4Parse --- CUE4Parse | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CUE4Parse b/CUE4Parse index 12ed351a..eb17756c 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 12ed351a1f623e042dfca16775072a1d652b8560 +Subproject commit eb17756cf0a6505e2ba5cec467db58cfab231fe4 From 5f1ddce5ed94a902401ff3a6aec601faee5ef067 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Thu, 9 Dec 2021 10:39:23 +0100 Subject: [PATCH 31/43] you don't need that anyway --- CUE4Parse | 2 +- FModel/MainWindow.xaml | 22 +++-------------- FModel/MainWindow.xaml.cs | 6 ----- FModel/Settings/UserSettings.cs | 20 +++------------- FModel/ViewModels/CUE4ParseViewModel.cs | 6 ----- FModel/ViewModels/MapViewerViewModel.cs | 16 +++++-------- FModel/Views/SettingsView.xaml | 32 +++++++++++-------------- 7 files changed, 27 insertions(+), 77 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index eb17756c..cf93fb7a 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit eb17756cf0a6505e2ba5cec467db58cfab231fe4 +Subproject commit cf93fb7ad93af74994f736db6cc134250e165a53 diff --git a/FModel/MainWindow.xaml b/FModel/MainWindow.xaml index 757411ec..12a9ad50 100644 --- a/FModel/MainWindow.xaml +++ b/FModel/MainWindow.xaml @@ -94,7 +94,7 @@ - + @@ -147,9 +147,6 @@ - @@ -394,7 +391,7 @@ - + @@ -522,7 +519,7 @@ - + @@ -796,19 +793,6 @@ - - - - - - -