mirror of
https://github.com/4sval/FModel.git
synced 2026-08-23 01:44:32 -05:00
starting to look like something usable
This commit is contained in:
@@ -11,10 +11,9 @@ using CUE4Parse_Conversion.Meshes.PSK;
|
||||
using CUE4Parse_Conversion.Textures;
|
||||
using FModel.Framework;
|
||||
using HelixToolkit.SharpDX.Core;
|
||||
using HelixToolkit.SharpDX.Core.Model;
|
||||
using HelixToolkit.Wpf.SharpDX;
|
||||
using SharpDX;
|
||||
using SharpDX.DXGI;
|
||||
using SharpDX.Direct3D11;
|
||||
using Camera = HelixToolkit.Wpf.SharpDX.Camera;
|
||||
using Geometry3D = HelixToolkit.SharpDX.Core.Geometry3D;
|
||||
using PerspectiveCamera = HelixToolkit.Wpf.SharpDX.PerspectiveCamera;
|
||||
@@ -58,11 +57,33 @@ namespace FModel.ViewModels
|
||||
set => SetProperty(ref _zAxis, value);
|
||||
}
|
||||
|
||||
private FillMode _fillMode
|
||||
{
|
||||
get => _showWireframe ? FillMode.Wireframe : FillMode.Solid;
|
||||
}
|
||||
|
||||
private bool _showWireframe;
|
||||
public bool ShowWireframe
|
||||
{
|
||||
get => _showWireframe;
|
||||
set => SetProperty(ref _showWireframe, value);
|
||||
set
|
||||
{
|
||||
SetProperty(ref _showWireframe, value);
|
||||
foreach (var g in Group3d)
|
||||
{
|
||||
if (g is not MeshGeometryModel3D geometryModel)
|
||||
continue;
|
||||
|
||||
geometryModel.FillMode = _fillMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _appendModeEnabled;
|
||||
public bool AppendModeEnabled
|
||||
{
|
||||
get => _appendModeEnabled;
|
||||
set => SetProperty(ref _appendModeEnabled, value);
|
||||
}
|
||||
|
||||
private ObservableElement3DCollection _group3d;
|
||||
@@ -72,7 +93,7 @@ namespace FModel.ViewModels
|
||||
set => SetProperty(ref _group3d, value);
|
||||
}
|
||||
|
||||
private readonly int[] _FACES_INDEX = { 1, 0, 2 };
|
||||
private readonly int[] _facesIndex = { 1, 0, 2 };
|
||||
|
||||
public ModelViewerViewModel()
|
||||
{
|
||||
@@ -83,7 +104,7 @@ namespace FModel.ViewModels
|
||||
|
||||
public void LoadExport(UObject export)
|
||||
{
|
||||
Clear();
|
||||
if (!AppendModeEnabled) Clear();
|
||||
switch (export)
|
||||
{
|
||||
case UStaticMesh st:
|
||||
@@ -97,6 +118,17 @@ namespace FModel.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public void HideToggleAll()
|
||||
{
|
||||
foreach (var g in Group3d)
|
||||
{
|
||||
if (g is not MeshGeometryModel3D geometryModel)
|
||||
continue;
|
||||
|
||||
geometryModel.IsRendering = !geometryModel.IsRendering;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadStaticMesh(UStaticMesh mesh)
|
||||
{
|
||||
if (!mesh.TryConvert(out var convertedMesh) || convertedMesh.LODs.Count <= 0)
|
||||
@@ -139,7 +171,7 @@ namespace FModel.ViewModels
|
||||
// NumFaces * 3 (triangle) = next section FirstIndex
|
||||
for (var j = 0; j < section.NumFaces; j++) // draw a triangle for each face
|
||||
{
|
||||
foreach (var t in _FACES_INDEX) // triangle face 1 then 0 then 2
|
||||
foreach (var t in _facesIndex) // triangle face 1 then 0 then 2
|
||||
{
|
||||
var id = section.FirstIndex + j * 3 + t;
|
||||
var vert = verts[indices[id]];
|
||||
@@ -182,7 +214,8 @@ namespace FModel.ViewModels
|
||||
Name = unrealMaterial.Name,
|
||||
Geometry = builder.ToMeshGeometry3D(),
|
||||
Material = m,
|
||||
IsRendering = isRendering
|
||||
IsRendering = isRendering,
|
||||
FillMode = _fillMode
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:converters="clr-namespace:FModel.Views.Resources.Converters"
|
||||
xmlns:adonisUi="clr-namespace:AdonisUI;assembly=AdonisUI"
|
||||
xmlns:adonisControls="clr-namespace:AdonisUI.Controls;assembly=AdonisUI"
|
||||
xmlns:adonisExtensions="clr-namespace:AdonisUI.Extensions;assembly=AdonisUI"
|
||||
xmlns:helix="http://helix-toolkit.org/wpf/SharpDX"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="CanResize" IconVisibility="Collapsed" Background="#262630"
|
||||
PreviewKeyDown="OnWindowKeyDown" Closing="OnClosing"
|
||||
@@ -22,42 +23,43 @@
|
||||
</ResourceDictionary>
|
||||
</adonisControls:AdonisWindow.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="{adonisUi:Space 1}" />
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="250" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="4*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Menu Grid.Row="0">
|
||||
<MenuItem Header="Append" />
|
||||
</Menu>
|
||||
<Grid Grid.Column="0" Background="#2A2B34">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="3*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<ListBox Grid.Column="0" Style="{StaticResource MaterialsListBox}" />
|
||||
<helix:Viewport3DX Grid.Column="1" EffectsManager="{Binding ModelViewer.EffectManager}" Camera="{Binding ModelViewer.Cam}"
|
||||
IsChangeFieldOfViewEnabled="False" IsMoveEnabled="False" UseDefaultGestures="False" ShowViewCube="False"
|
||||
ShowCameraTarget="False" ModelUpDirection="0,0,1" EnableSSAO="True" MSAA="Maximum" FXAALevel="Ultra"
|
||||
SSAOQuality="High" BackgroundColor="#262630">
|
||||
<helix:Viewport3DX.InputBindings>
|
||||
<MouseBinding Command="helix:ViewportCommands.Rotate" Gesture="LeftClick" />
|
||||
<MouseBinding Command="helix:ViewportCommands.Zoom" Gesture="RightClick" />
|
||||
<MouseBinding Command="helix:ViewportCommands.Pan" Gesture="MiddleClick" />
|
||||
</helix:Viewport3DX.InputBindings>
|
||||
|
||||
<helix:AmbientLight3D Color="DimGray" />
|
||||
<helix:DirectionalLight3D Direction="{Binding ModelViewer.Cam.LookDirection}" Color="White" />
|
||||
|
||||
<helix:LineGeometryModel3D Geometry="{Binding ModelViewer.XAxis}" Color="#FC3854" />
|
||||
<helix:LineGeometryModel3D Geometry="{Binding ModelViewer.YAxis}" Color="#85CB22" />
|
||||
<helix:LineGeometryModel3D Geometry="{Binding ModelViewer.ZAxis}" Color="#388EED" />
|
||||
|
||||
<helix:GroupModel3D x:Name="MyAntiCrashGroup" ItemsSource="{Binding ModelViewer.Group3d}" />
|
||||
</helix:Viewport3DX>
|
||||
<ListBox Grid.Row="0" Style="{StaticResource MaterialsListBox}" />
|
||||
<CheckBox Content="Append Mode" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0 0 0 5"
|
||||
Grid.Row="1" IsChecked="{Binding ModelViewer.AppendModeEnabled}" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
|
||||
</Grid>
|
||||
|
||||
<GridSplitter Grid.Column="1" ResizeDirection="Columns" Width="4" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext"
|
||||
Background="{DynamicResource {x:Static adonisUi:Brushes.Layer0BackgroundBrush}}" />
|
||||
|
||||
<helix:Viewport3DX Grid.Column="2" EffectsManager="{Binding ModelViewer.EffectManager}" Camera="{Binding ModelViewer.Cam}"
|
||||
IsChangeFieldOfViewEnabled="False" IsMoveEnabled="False" UseDefaultGestures="False" ShowViewCube="False"
|
||||
ShowCameraTarget="False" ModelUpDirection="0,0,1" BackgroundColor="#2A2B34">
|
||||
<helix:Viewport3DX.InputBindings>
|
||||
<MouseBinding Command="helix:ViewportCommands.Rotate" Gesture="LeftClick" />
|
||||
<MouseBinding Command="helix:ViewportCommands.Zoom" Gesture="RightClick" />
|
||||
<MouseBinding Command="helix:ViewportCommands.Pan" Gesture="MiddleClick" />
|
||||
</helix:Viewport3DX.InputBindings>
|
||||
|
||||
<helix:AmbientLight3D Color="DimGray" />
|
||||
<helix:DirectionalLight3D Direction="{Binding ModelViewer.Cam.LookDirection}" Color="White" />
|
||||
|
||||
<helix:LineGeometryModel3D Geometry="{Binding ModelViewer.XAxis}" Color="#FC3854" />
|
||||
<helix:LineGeometryModel3D Geometry="{Binding ModelViewer.YAxis}" Color="#85CB22" />
|
||||
<helix:LineGeometryModel3D Geometry="{Binding ModelViewer.ZAxis}" Color="#388EED" />
|
||||
|
||||
<helix:GroupModel3D x:Name="MyAntiCrashGroup" ItemsSource="{Binding ModelViewer.Group3d}" />
|
||||
</helix:Viewport3DX>
|
||||
</Grid>
|
||||
</adonisControls:AdonisWindow>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Windows.Input;
|
||||
using CUE4Parse.UE4.Assets.Exports;
|
||||
using FModel.Services;
|
||||
using FModel.Settings;
|
||||
using FModel.ViewModels;
|
||||
|
||||
namespace FModel.Views
|
||||
@@ -22,12 +21,15 @@ namespace FModel.Views
|
||||
|
||||
private void OnWindowKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
/*if (UserSettings.Default.DirLeftTab.IsTriggered(e.Key))
|
||||
_applicationView.ModelViewer.PreviousLod();
|
||||
else if (UserSettings.Default.DirRightTab.IsTriggered(e.Key))
|
||||
_applicationView.ModelViewer.NextLod();
|
||||
else */if (e.Key == Key.W)
|
||||
_applicationView.ModelViewer.ShowWireframe = !_applicationView.ModelViewer.ShowWireframe;
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.W:
|
||||
_applicationView.ModelViewer.ShowWireframe = !_applicationView.ModelViewer.ShowWireframe;
|
||||
break;
|
||||
case Key.H:
|
||||
_applicationView.ModelViewer.HideToggleAll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
FModel/Views/Resources/Converters/BoolToFillModeConverter.cs
Normal file
30
FModel/Views/Resources/Converters/BoolToFillModeConverter.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
using SharpDX.Direct3D11;
|
||||
|
||||
namespace FModel.Views.Resources.Converters
|
||||
{
|
||||
public class BoolToFillModeConverter : IValueConverter
|
||||
{
|
||||
public static readonly BoolToFillModeConverter Instance = new();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value switch
|
||||
{
|
||||
FillMode.Solid => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value switch
|
||||
{
|
||||
true => FillMode.Solid,
|
||||
_ => FillMode.Wireframe
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:controls="clr-namespace:FModel.Views.Resources.Controls"
|
||||
xmlns:soundOut="clr-namespace:CSCore.SoundOut;assembly=CSCore"
|
||||
xmlns:sharpDx="clr-namespace:SharpDX.Direct3D11;assembly=SharpDX.Direct3D11"
|
||||
xmlns:audioControls="clr-namespace:FModel.Views.Resources.Controls.Aup"
|
||||
xmlns:converters="clr-namespace:FModel.Views.Resources.Converters"
|
||||
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
|
||||
@@ -67,6 +68,8 @@
|
||||
<Geometry x:Key="MaterialIcon">M11 9h2v2h-2V9zm-2 2h2v2H9v-2zm4 0h2v2h-2v-2zm2-2h2v2h-2V9zM7 9h2v2H7V9zm12-6H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 18H7v-2h2v2zm4 0h-2v-2h2v2zm4 0h-2v-2h2v2zm2-7h-2v2h2v2h-2v-2h-2v2h-2v-2h-2v2H9v-2H7v2H5v-2h2v-2H5V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v5z</Geometry>
|
||||
<Geometry x:Key="VisibleIcon">M12 4C7 4 2.73 7.11 1 11.5 2.73 15.89 7 19 12 19s9.27-3.11 11-7.5C21.27 7.11 17 4 12 4zm0 12.5c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z</Geometry>
|
||||
<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>
|
||||
|
||||
<Style x:Key="TabItemFillSpace" TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
|
||||
<Setter Property="Width">
|
||||
@@ -616,7 +619,7 @@
|
||||
|
||||
<Style x:Key="MaterialsListBox" TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
|
||||
<Setter Property="ItemsSource" Value="{Binding ModelViewer.Group3d, IsAsync=True}" />
|
||||
<Setter Property="SelectionMode" Value="Extended" />
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
|
||||
<Setter Property="adonisExtensions:ScrollViewerExtension.VerticalScrollBarExpansionMode" Value="NeverExpand"/>
|
||||
<Setter Property="adonisExtensions:ScrollViewerExtension.VerticalScrollBarPlacement" Value="Docked"/>
|
||||
<Setter Property="adonisExtensions:ScrollViewerExtension.HorizontalScrollBarExpansionMode" Value="NeverExpand"/>
|
||||
@@ -630,6 +633,7 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="25" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Image Grid.Column="0" Source="/FModel;component/Resources/materialicon.png" Width="16" Height="16" Margin="5 0" HorizontalAlignment="Center" />
|
||||
@@ -637,19 +641,34 @@
|
||||
<ToggleButton Grid.Column="3" IsChecked="{Binding IsRendering}" Padding="3" Style="{DynamicResource {x:Static adonisUi:Styles.ToolbarToggleButton}}">
|
||||
<Viewbox Width="16" Height="16" HorizontalAlignment="Center">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path x:Name="SvgIcon" Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource VisibleIcon}" />
|
||||
<Path x:Name="SvgIcon1" Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource VisibleIcon}" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</ToggleButton>
|
||||
<ToggleButton Grid.Column="4" IsChecked="{Binding FillMode, Converter={x:Static converters:BoolToFillModeConverter.Instance}}" Padding="3" Style="{DynamicResource {x:Static adonisUi:Styles.ToolbarToggleButton}}">
|
||||
<Viewbox Width="16" Height="16" HorizontalAlignment="Center">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path x:Name="SvgIcon2" Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource WireframeIcon}" />
|
||||
</Canvas>
|
||||
</Viewbox>
|
||||
</ToggleButton>
|
||||
</Grid>
|
||||
<DataTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding IsRendering}" Value="True">
|
||||
<Setter TargetName="SvgIcon" Property="Data" Value="{StaticResource VisibleIcon}" />
|
||||
<Setter TargetName="SvgIcon" Property="Fill" Value="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" />
|
||||
<Setter TargetName="SvgIcon1" Property="Data" Value="{StaticResource VisibleIcon}" />
|
||||
<Setter TargetName="SvgIcon1" Property="Fill" Value="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding IsRendering}" Value="False">
|
||||
<Setter TargetName="SvgIcon" Property="Data" Value="{StaticResource NotVisibleIcon}" />
|
||||
<Setter TargetName="SvgIcon" Property="Fill" Value="{DynamicResource {x:Static adonisUi:Brushes.ErrorBrush}}" />
|
||||
<Setter TargetName="SvgIcon1" Property="Data" Value="{StaticResource NotVisibleIcon}" />
|
||||
<Setter TargetName="SvgIcon1" Property="Fill" Value="{DynamicResource {x:Static adonisUi:Brushes.ErrorBrush}}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding FillMode}" Value="{x:Static sharpDx:FillMode.Solid}">
|
||||
<Setter TargetName="SvgIcon2" Property="Data" Value="{StaticResource WireframeIcon}" />
|
||||
<Setter TargetName="SvgIcon2" Property="Fill" Value="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding FillMode}" Value="{x:Static sharpDx:FillMode.Wireframe}">
|
||||
<Setter TargetName="SvgIcon2" Property="Data" Value="{StaticResource NotWireframeIcon}" />
|
||||
<Setter TargetName="SvgIcon2" Property="Fill" Value="{DynamicResource {x:Static adonisUi:Brushes.ErrorBrush}}" />
|
||||
</DataTrigger>
|
||||
</DataTemplate.Triggers>
|
||||
</DataTemplate>
|
||||
|
||||
Reference in New Issue
Block a user