From 98b4da93a5e5ebffd629253bae437c79f2223186 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Fri, 10 Dec 2021 22:56:48 +0100 Subject: [PATCH] overwrite material in preview and in the mesh so saving the mesh will also save the new material instead of the overwritten one --- CUE4Parse | 2 +- FModel/FModel.csproj | 4 +-- FModel/ViewModels/CUE4ParseViewModel.cs | 14 ++++---- FModel/ViewModels/ModelViewerViewModel.cs | 39 ++++++++++++++++++----- FModel/Views/ModelViewer.xaml | 4 +-- FModel/Views/ModelViewer.xaml.cs | 15 ++++----- FModel/Views/Resources/Resources.xaml | 2 +- 7 files changed, 51 insertions(+), 29 deletions(-) diff --git a/CUE4Parse b/CUE4Parse index 1fc543a0..3dbe09d4 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 1fc543a0434c8a2aa020443a377659fd4a908895 +Subproject commit 3dbe09d4a83b9b3628a2a340394628c39a954eb9 diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index e5bc0c2f..a2f525c0 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -110,12 +110,12 @@ - + - + diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index fb8c18d2..13f296f4 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -59,11 +59,11 @@ namespace FModel.ViewModels set => SetProperty(ref _game, value); } - private bool _modelIsSwappingMaterial; - public bool ModelIsSwappingMaterial + private bool _modelIsOverwritingMaterial; + public bool ModelIsOverwritingMaterial { - get => _modelIsSwappingMaterial; - set => SetProperty(ref _modelIsSwappingMaterial, value); + get => _modelIsOverwritingMaterial; + set => SetProperty(ref _modelIsOverwritingMaterial, value); } public AbstractVfsFileProvider Provider { get; } @@ -675,7 +675,7 @@ namespace FModel.ViewModels } case UStaticMesh when UserSettings.Default.PreviewStaticMeshes: case USkeletalMesh when UserSettings.Default.PreviewSkeletalMeshes: - case UMaterialInstance when UserSettings.Default.PreviewMaterials && !ModelIsSwappingMaterial && + case UMaterialInstance when UserSettings.Default.PreviewMaterials && !ModelIsOverwritingMaterial && !(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))): @@ -687,12 +687,12 @@ namespace FModel.ViewModels }); return true; } - case UMaterialInstance m when ModelIsSwappingMaterial: + case UMaterialInstance m when ModelIsOverwritingMaterial: { Application.Current.Dispatcher.InvokeAsync(() => { var modelViewer = Helper.GetWindow("Model Viewer", () => new ModelViewer().Show()); - modelViewer.Swap(m); + modelViewer.Overwrite(m); }); return true; } diff --git a/FModel/ViewModels/ModelViewerViewModel.cs b/FModel/ViewModels/ModelViewerViewModel.cs index 1e8739cd..e2b19d43 100644 --- a/FModel/ViewModels/ModelViewerViewModel.cs +++ b/FModel/ViewModels/ModelViewerViewModel.cs @@ -9,12 +9,14 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Data; using System.Windows.Media.Media3D; +using CUE4Parse.UE4.Assets; using CUE4Parse.UE4.Assets.Exports; using CUE4Parse.UE4.Assets.Exports.Material; using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; using CUE4Parse.UE4.Assets.Exports.StaticMesh; using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse.UE4.Objects.Core.Math; +using CUE4Parse.UE4.Objects.UObject; using CUE4Parse.Utils; using CUE4Parse_Conversion.Materials; using CUE4Parse_Conversion.Meshes; @@ -284,9 +286,9 @@ namespace FModel.ViewModels Clipboard.SetText(m.SelectedGeometry.DisplayName.TrimEnd()); } - public async Task TryChangeSelectedMaterial(UMaterialInstance materialInstance) + public async Task TryOverwriteMaterial(UMaterialInstance materialInstance) { - if (SelectedModel is not { } model || model.SelectedGeometry is null) + if (SelectedModel is not { SelectedGeometry: {} geometry } model) return false; PBRMaterial m = null; @@ -297,7 +299,22 @@ namespace FModel.ViewModels }); if (m == null) return false; - model.SelectedGeometry.Material = m; + + var index = geometry.MaterialIndex; + var obj = new ResolvedLoadedObject(materialInstance); + switch (model.Export) + { + case UStaticMesh { Materials: { } } st: + st.Materials[index] = obj; + break; + case USkeletalMesh sk: + sk.Materials[index].Material = obj; + break; + case UMaterialInstance: + model.SwapExport(materialInstance); + break; + } + geometry.Material = m; return true; } #endregion @@ -317,7 +334,7 @@ namespace FModel.ViewModels cam.Group3d.Add(new CustomMeshGeometryModel3D { Transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1,0,0), -90)), - DisplayName = s, Geometry = builder.ToMeshGeometry3D(), + DisplayName = s, Geometry = builder.ToMeshGeometry3D(), MaterialIndex = 0, Material = m, IsTransparent = isTransparent, IsRendering = isRendering }); }); @@ -378,15 +395,15 @@ namespace FModel.ViewModels } } - if (section.Material == null || !section.Material.TryLoad(out var unrealMaterial)) + if (section.Material == null || !section.Material.TryLoad(out var o) || o is not UMaterialInterface material) continue; - var (m, isRendering, isTransparent) = LoadMaterial(unrealMaterial); + var (m, isRendering, isTransparent) = LoadMaterial(material); Application.Current.Dispatcher.Invoke(() => { cam.Group3d.Add(new CustomMeshGeometryModel3D { - DisplayName = FixName(section.MaterialName ?? unrealMaterial.Name), + DisplayName = FixName(section.MaterialName ?? material.Name), MaterialIndex = i, Geometry = builder.ToMeshGeometry3D(), Material = m, IsTransparent = isTransparent, IsRendering = isRendering }); @@ -618,7 +635,7 @@ namespace FModel.ViewModels public class ModelAndCam : ViewModel { - public UObject Export { get; } + public UObject Export { get; private set; } public Point3D Position { get; set; } public Vector3D LookDirection { get; set; } public Geometry3D XAxis { get; set; } @@ -743,6 +760,11 @@ namespace FModel.ViewModels private int B(int x) => (x & 0xFFF8) | _table2[x & 7] ^ 7; private int C(int x) => (x & 1) | ((x >> 2) & 2); + public void SwapExport(UObject e) + { + Export = e; + } + public void Dispose() { TriangleCount = 0; @@ -758,5 +780,6 @@ namespace FModel.ViewModels public class CustomMeshGeometryModel3D : MeshGeometryModel3D { public string DisplayName { get; set; } + public int MaterialIndex { get; set; } } } diff --git a/FModel/Views/ModelViewer.xaml b/FModel/Views/ModelViewer.xaml index 7d51f26e..bcf3ce38 100644 --- a/FModel/Views/ModelViewer.xaml +++ b/FModel/Views/ModelViewer.xaml @@ -90,11 +90,11 @@ - + - + diff --git a/FModel/Views/ModelViewer.xaml.cs b/FModel/Views/ModelViewer.xaml.cs index e4ca836f..152ee890 100644 --- a/FModel/Views/ModelViewer.xaml.cs +++ b/FModel/Views/ModelViewer.xaml.cs @@ -24,12 +24,12 @@ namespace FModel.Views } public async void Load(UObject export) => await _applicationView.ModelViewer.LoadExport(export); - public async void Swap(UMaterialInstance materialInstance) + public async void Overwrite(UMaterialInstance materialInstance) { - var sucess = await _applicationView.ModelViewer.TryChangeSelectedMaterial(materialInstance); + var sucess = await _applicationView.ModelViewer.TryOverwriteMaterial(materialInstance); if (sucess) { - _applicationView.CUE4Parse.ModelIsSwappingMaterial = false; + _applicationView.CUE4Parse.ModelIsOverwritingMaterial = false; } else { @@ -48,7 +48,7 @@ namespace FModel.Views { _applicationView.ModelViewer.Clear(); _applicationView.ModelViewer.AppendMode = false; - _applicationView.CUE4Parse.ModelIsSwappingMaterial = false; + _applicationView.CUE4Parse.ModelIsOverwritingMaterial = false; MyAntiCrashGroup.ItemsSource = null; // <3 } @@ -96,16 +96,15 @@ namespace FModel.Views private void Save(object sender, RoutedEventArgs e) => _applicationView.ModelViewer.SaveLoadedModels(); - private void OnChangeMaterialClick(object sender, RoutedEventArgs e) + private void OnOverwriteMaterialClick(object sender, RoutedEventArgs e) { - _applicationView.CUE4Parse.ModelIsSwappingMaterial = true; - + _applicationView.CUE4Parse.ModelIsOverwritingMaterial = true; if (!_messageShown) { MessageBox.Show(new MessageBoxModel { Text = "Simply extract a material once FModel will be brought to the foreground. This message will be shown once per Model Viewer's lifetime, close it to begin.", - Caption = "How To Change Material?", + Caption = "How To Overwrite Material?", Icon = MessageBoxImage.Information, IsSoundEnabled = false }); diff --git a/FModel/Views/Resources/Resources.xaml b/FModel/Views/Resources/Resources.xaml index 9be378e4..46afe381 100644 --- a/FModel/Views/Resources/Resources.xaml +++ b/FModel/Views/Resources/Resources.xaml @@ -70,7 +70,7 @@ M12 6.5c2.76 0 5 2.24 5 5 0 .51-.1 1-.24 1.46l3.06 3.06c1.39-1.23 2.49-2.77 3.18-4.53C21.27 7.11 17 4 12 4c-1.27 0-2.49.2-3.64.57l2.17 2.17c.47-.14.96-.24 1.47-.24zM2.71 3.16c-.39.39-.39 1.02 0 1.41l1.97 1.97C3.06 7.83 1.77 9.53 1 11.5 2.73 15.89 7 19 12 19c1.52 0 2.97-.3 4.31-.82l2.72 2.72c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L4.13 3.16c-.39-.39-1.03-.39-1.42 0zM12 16.5c-2.76 0-5-2.24-5-5 0-.77.18-1.5.49-2.14l1.57 1.57c-.03.18-.06.37-.06.57 0 1.66 1.34 3 3 3 .2 0 .38-.03.57-.07L14.14 16c-.65.32-1.37.5-2.14.5zm2.97-5.33c-.15-1.4-1.25-2.49-2.64-2.64l2.64 2.64z M3 5h2V3c-1.1 0-2 .9-2 2zm0 8h2v-2H3v2zm4 8h2v-2H7v2zM3 9h2V7H3v2zm10-6h-2v2h2V3zm6 0v2h2c0-1.1-.9-2-2-2zM5 21v-2H3c0 1.1.9 2 2 2zm-2-4h2v-2H3v2zM9 3H7v2h2V3zm2 18h2v-2h-2v2zm8-8h2v-2h-2v2zm0 8c1.1 0 2-.9 2-2h-2v2zm0-12h2V7h-2v2zm0 8h2v-2h-2v2zm-4 4h2v-2h-2v2zm0-16h2V3h-2v2zM8 17h8c.55 0 1-.45 1-1V8c0-.55-.45-1-1-1H8c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1zm1-8h6v6H9V9z M3,13h2v-2H3V13z M7,21h2v-2H7V21z M13,3h-2v2h2V3z M19,3v2h2C21,3.9,20.1,3,19,3z M5,21v-2H3C3,20.1,3.9,21,5,21z M3,17h2 v-2H3V17z M11,21h2v-2h-2V21z M19,13h2v-2h-2V13z M19,9h2V7h-2V9z M15,5h2V3h-2V5z M7.83,5L7,4.17V3h2v2H7.83z M19.83,17L19,16.17 V15h2v2H19.83z M9,15v-3.17L12.17,15H9z M2.1,3.51c-0.39,0.39-0.39,1.02,0,1.41L4.17,7H3v2h2V7.83l2,2V16c0,0.55,0.45,1,1,1h6.17 l2,2H15v2h2v-1.17l2.07,2.07c0.39,0.39,1.02,0.39,1.41,0c0.39-0.39,0.39-1.02,0-1.41L3.51,3.51C3.12,3.12,2.49,3.12,2.1,3.51z M17,8c0-0.55-0.45-1-1-1H9.83l2,2H15v3.17l2,2V8z - M16 17.01V11c0-.55-.45-1-1-1s-1 .45-1 1v6.01h-1.79c-.45 0-.67.54-.35.85l2.79 2.78c.2.19.51.19.71 0l2.79-2.78c.32-.31.09-.85-.35-.85H16zM8.65 3.35L5.86 6.14c-.32.31-.1.85.35.85H8V13c0 .55.45 1 1 1s1-.45 1-1V6.99h1.79c.45 0 .67-.54.35-.85L9.35 3.35c-.19-.19-.51-.19-.7 0z + M16 17.01V11c0-.55-.45-1-1-1s-1 .45-1 1v6.01h-1.79c-.45 0-.67.54-.35.85l2.79 2.78c.2.19.51.19.71 0l2.79-2.78c.32-.31.09-.85-.35-.85H16zM8.65 3.35L5.86 6.14c-.32.31-.1.85.35.85H8V13c0 .55.45 1 1 1s1-.45 1-1V6.99h1.79c.45 0 .67-.54.35-.85L9.35 3.35c-.19-.19-.51-.19-.7 0z