mirror of
https://github.com/4sval/FModel.git
synced 2026-06-21 07:20:05 -05:00
overwrite material in preview and in the mesh
so saving the mesh will also save the new material instead of the overwritten one
This commit is contained in:
parent
061a0de29b
commit
98b4da93a5
|
|
@ -1 +1 @@
|
|||
Subproject commit 1fc543a0434c8a2aa020443a377659fd4a908895
|
||||
Subproject commit 3dbe09d4a83b9b3628a2a340394628c39a954eb9
|
||||
|
|
@ -110,12 +110,12 @@
|
|||
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
|
||||
<PackageReference Include="EpicManifestParser" Version="1.2.70-temp" />
|
||||
<PackageReference Include="HelixToolkit.SharpDX.Core.Wpf" Version="2.20.0" />
|
||||
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.2.15" />
|
||||
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.2.16" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NVorbis" Version="0.10.4" />
|
||||
<PackageReference Include="Oodle.NET" Version="1.0.1" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.0" />
|
||||
<PackageReference Include="RestSharp" Version="106.13.0" />
|
||||
<PackageReference Include="RestSharp" Version="106.15.0" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.80.3" />
|
||||
|
|
|
|||
|
|
@ -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<ModelViewer>("Model Viewer", () => new ModelViewer().Show());
|
||||
modelViewer.Swap(m);
|
||||
modelViewer.Overwrite(m);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<bool> TryChangeSelectedMaterial(UMaterialInstance materialInstance)
|
||||
public async Task<bool> 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<UMaterialInterface>(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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,11 +90,11 @@
|
|||
</Viewbox>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Change Material" Click="OnChangeMaterialClick">
|
||||
<MenuItem Header="Overwrite Material" Click="OnOverwriteMaterialClick">
|
||||
<MenuItem.Icon>
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource SwapIcon}" />
|
||||
<Path Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource OverwriteIcon}" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</MenuItem.Icon>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
<Geometry x:Key="NotVisibleIcon">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</Geometry>
|
||||
<Geometry x:Key="WireframeIcon">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</Geometry>
|
||||
<Geometry x:Key="NotWireframeIcon">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</Geometry>
|
||||
<Geometry x:Key="SwapIcon">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</Geometry>
|
||||
<Geometry x:Key="OverwriteIcon">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</Geometry>
|
||||
|
||||
<Style x:Key="TabItemFillSpace" TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
|
||||
<Setter Property="Width">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user