Refactor Vector3Field and update project structure

Changed Vector3Field.cs to derive from ValueControl<Vector3> and use NumberBox controls for better UI handling.
Changed EditorControls.xaml to update resource paths for new controls.
Changed InternalControls.xaml to simplify the resource dictionary by removing unnecessary references.
Changed IComponentEditor.cs to reflect updates in the component editor's lifecycle methods.
Changed project files for Ghost.Editor and Ghost.Core to include new dependencies and project references.
Changed FileExtensions.cs and IInspectorService.cs to align with the new namespace structure.
Changed Result.cs to enhance error handling and success checking methods.
Changed TypeHandle.cs to improve type handling compatibility.
Changed AssemblyInfo.cs files to include new assembly visibility attributes for better encapsulation.
Added new graphics-related classes and interfaces in the Ghost.Engine project, including IGraphicsDevice and DX12GraphicsDevice.
Added a new Mesh class to handle 3D mesh data and provide methods for creating geometric shapes.
Added GraphicsPipeline.cs to manage the graphics rendering loop and device initialization.
Added ScenePage.xaml and ScenePage.xaml.cs to create a new page for rendering scenes.
Updated HierarchyPage.xaml.cs and InspectorPage.xaml.cs to use the new service locator pattern for service retrieval.
Updated LandingWindow.xaml.cs and EngineEditorWindow.xaml.cs to utilize the new service locator pattern for better service access.
Updated Logger.cs to enhance logging capabilities with optional stack traces and assertion logging.
Updated QueryFilter.cs and QueryEnumerable.cs to use the new TypeHandle structure for improved efficiency.
Updated WorldNode.cs and WorldNodeSerializer.cs to enhance serialization and management of world nodes.
Updated AssetDatabase and related classes to improve asset management and metadata generation.
Updated Ghost.UnitTest.csproj to include new project references and package dependencies for unit tests.
This commit is contained in:
2025-06-27 20:02:02 +09:00
parent 1724072f7e
commit 4110c166cf
191 changed files with 2286 additions and 1462 deletions

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Ghost.Editor.View.Pages.EngineEditor.ConsolePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Ghost.Editor.View.Pages.EngineEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource LayerFillColorDefaultBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Toolbar -->
<Grid
Grid.Row="0"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultSolid}"
BorderThickness="0,0,0,1">
<CommandBar DefaultLabelPosition="Collapsed">
<CommandBar.PrimaryCommands>
<AppBarButton Command="{x:Bind ViewModel.ClearLogsCommand}" Content="Clear" />
<AppBarSeparator />
<AppBarToggleButton Width="45" IsChecked="{x:Bind ViewModel.ShowInfo, Mode=TwoWay}">
<AppBarToggleButton.Icon>
<FontIcon Glyph="&#xF167;" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarToggleButton Width="45" IsChecked="{x:Bind ViewModel.ShowWarning, Mode=TwoWay}">
<AppBarToggleButton.Icon>
<FontIcon Glyph="&#xE814;" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarToggleButton Width="45" IsChecked="{x:Bind ViewModel.ShowError, Mode=TwoWay}">
<AppBarToggleButton.Icon>
<FontIcon Glyph="&#xEB90;" />
</AppBarToggleButton.Icon>
</AppBarToggleButton>
</CommandBar.PrimaryCommands>
<CommandBar.SecondaryCommands>
<AppBarToggleButton BorderThickness="0" Label="Clear On Play" />
<AppBarToggleButton
BorderThickness="0"
IsChecked="{x:Bind ViewModel.ShowStackTrace, Mode=TwoWay}"
Label="Show Stack Trace" />
</CommandBar.SecondaryCommands>
</CommandBar>
</Grid>
<!-- Log Content -->
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<ListView
x:Name="LogListView"
Grid.Row="0"
ItemsSource="{x:Bind ViewModel.Logs, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedLog, Mode=TwoWay}" />
<Grid
Grid.Row="1"
Padding="4"
BorderBrush="{ThemeResource CardStrokeColorDefaultSolid}"
BorderThickness="0,1,0,0">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TextBlock
IsTextSelectionEnabled="True"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind ViewModel.SelectedLog.ToStringWithStackTrace(), Mode=OneWay}"
TextWrapping="Wrap" />
</ScrollViewer>
</Grid>
</Grid>
</Grid>
</Page>

View File

@@ -0,0 +1,19 @@
using Ghost.Editor.ViewModels.Pages.EngineEditor;
using Microsoft.UI.Xaml.Controls;
namespace Ghost.Editor.View.Pages.EngineEditor;
internal sealed partial class ConsolePage : Page
{
public ConsoleViewModel ViewModel
{
get;
}
public ConsolePage()
{
ViewModel = App.GetService<ConsoleViewModel>();
InitializeComponent();
}
}

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" ?>
<internal:NavigationTabPage
x:Class="Ghost.Editor.View.Pages.EngineEditor.HierarchyPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:internal="using:Ghost.Editor.Controls.Internal"
xmlns:local="using:Ghost.Editor.View.Pages.EngineEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sg="using:Ghost.Editor.Core.SceneGraph"
mc:Ignorable="d">
<internal:NavigationTabPage.Resources>
<DataTemplate x:Key="SceneTemplate" x:DataType="sg:SceneGraphNode">
<TreeViewItem
AutomationProperties.Name="{x:Bind Name, Mode=OneWay}"
Background="{ThemeResource ControlSolidFillColorDefaultBrush}"
IsExpanded="True"
ItemsSource="{x:Bind Children, Mode=OneWay}">
<StackPanel Orientation="Horizontal">
<FontIcon FontSize="14" Glyph="&#xF159;" />
<TextBlock Margin="10,0" Text="{x:Bind Name, Mode=OneWay}" />
</StackPanel>
</TreeViewItem>
</DataTemplate>
<DataTemplate x:Key="EntityTemplate" x:DataType="sg:SceneGraphNode">
<TreeViewItem AutomationProperties.Name="{x:Bind Name, Mode=OneWay}" ItemsSource="{x:Bind Children, Mode=OneWay}">
<StackPanel Margin="10,0" Orientation="Horizontal">
<FontIcon FontSize="14" Glyph="&#xF158;" />
<TextBlock Margin="5,0,0,0" Text="{x:Bind Name, Mode=OneWay}" />
</StackPanel>
</TreeViewItem>
</DataTemplate>
</internal:NavigationTabPage.Resources>
<Grid Padding="4,6" Background="{ThemeResource LayerFillColorDefaultBrush}">
<TreeView ItemsSource="{x:Bind ViewModel.SceneList}" SelectionChanged="TreeView_SelectionChanged">
<TreeView.ItemTemplateSelector>
<local:HierarchyTemplateSector EntityTemplate="{StaticResource EntityTemplate}" WorldTemplate="{StaticResource SceneTemplate}" />
</TreeView.ItemTemplateSelector>
</TreeView>
</Grid>
</internal:NavigationTabPage>

View File

@@ -0,0 +1,79 @@
using Ghost.Editor.Controls.Internal;
using Ghost.Editor.Core.Inspector;
using Ghost.Editor.Core.SceneGraph;
using Ghost.Editor.ViewModels.Pages.EngineEditor;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Ghost.Editor.View.Pages.EngineEditor;
internal sealed partial class HierarchyPage : NavigationTabPage
{
private readonly IInspectorService _inspectorService;
public HierarchyViewModel ViewModel
{
get;
}
public HierarchyPage()
{
_inspectorService = App.GetService<IInspectorService>();
ViewModel = App.GetService<HierarchyViewModel>();
InitializeComponent();
}
public override void OnNavigatedTo(object? parameter)
{
ViewModel.OnNavigatedTo(parameter);
}
public override void OnNavigatedFrom()
{
ViewModel.OnNavigatedFrom();
}
private void TreeView_SelectionChanged(TreeView sender, TreeViewSelectionChangedEventArgs args)
{
if (args.AddedItems.Count > 0 && args.AddedItems[0] is IInspectable inspectable)
{
_inspectorService.SelectedInspectable = inspectable;
}
else
{
_inspectorService.SelectedInspectable = null;
}
}
}
internal partial class HierarchyTemplateSector : DataTemplateSelector
{
public DataTemplate? WorldTemplate
{
get;
set;
}
public DataTemplate? EntityTemplate
{
get;
set;
}
protected override DataTemplate SelectTemplateCore(object item)
{
if (WorldTemplate == null || EntityTemplate == null)
{
return base.SelectTemplateCore(item);
}
var node = (SceneGraphNode)item;
return node.NodeType switch
{
SceneGraphNodeType.Scene => WorldTemplate,
SceneGraphNodeType.Entity => EntityTemplate,
_ => base.SelectTemplateCore(item)
};
}
}

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8" ?>
<internal:NavigationTabPage
x:Class="Ghost.Editor.View.Pages.EngineEditor.InspectorPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:internal="using:Ghost.Editor.Controls.Internal"
xmlns:local="using:Ghost.Editor.View.Pages.EngineEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource LayerFillColorDefaultBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="75" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Header -->
<Grid
Grid.Row="0"
Padding="15,0,10,0"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultSolid}"
BorderThickness="0,0,0,1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<IconSourceElement
Grid.Column="0"
Margin="0,0,15,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
IconSource="{x:Bind ViewModel.Inspectable.Icon, Mode=OneWay}" />
<ContentPresenter Grid.Column="1" Content="{x:Bind ViewModel.Inspectable.HeaderContent, Mode=OneWay}" />
</Grid>
<!-- Content -->
<Grid Grid.Row="1" Padding="0,0,0,0">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<ContentPresenter Content="{x:Bind ViewModel.Inspectable.InspectorContent, Mode=OneWay}" />
</ScrollViewer>
</Grid>
</Grid>
</internal:NavigationTabPage>

View File

@@ -0,0 +1,29 @@
using Ghost.Editor.Controls.Internal;
using Ghost.Editor.ViewModels.Pages.EngineEditor;
namespace Ghost.Editor.View.Pages.EngineEditor;
internal sealed partial class InspectorPage : NavigationTabPage
{
public InspectorViewModel ViewModel
{
get;
}
public InspectorPage()
{
ViewModel = App.GetService<InspectorViewModel>();
InitializeComponent();
}
public override void OnNavigatedTo(object? parameter)
{
ViewModel.OnNavigatedTo(parameter);
}
public override void OnNavigatedFrom()
{
ViewModel.OnNavigatedFrom();
}
}

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Ghost.Editor.View.Pages.EngineEditor.ProjectPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converter="using:Ghost.Editor.Utilities.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Ghost.Editor.View.Pages.EngineEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:model="using:Ghost.Editor.Models"
mc:Ignorable="d">
<Page.Resources>
<converter:AssetPathToGlyphConverter x:Key="AssetPathToGlyphConverter" />
</Page.Resources>
<Grid Background="{ThemeResource LayerFillColorDefaultBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Folder Tree View -->
<Grid
Grid.Column="0"
Padding="4"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultSolid}"
BorderThickness="0,0,1,0">
<TreeView
x:Name="DirectoryTreeView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{x:Bind ViewModel.SubDirectories}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectedItem="{x:Bind ViewModel.SelectedDirectory, Mode=TwoWay}">
<TreeView.ItemTemplate>
<DataTemplate x:DataType="model:ExplorerItem">
<TreeViewItem ItemsSource="{x:Bind Children}">
<StackPanel Orientation="Horizontal">
<FontIcon
VerticalAlignment="Center"
FontSize="14"
Glyph="&#xE8B7;" />
<TextBlock
Margin="8,0,0,0"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind Name}"
TextTrimming="CharacterEllipsis" />
</StackPanel>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
<!-- Files -->
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid
Grid.Row="0"
Padding="4"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultSolid}"
BorderThickness="0,0,0,1">
<BreadcrumbBar Height="15" />
</Grid>
<ScrollViewer
Grid.Row="1"
Padding="8"
VerticalAlignment="Stretch"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<GridView
x:Name="AssetsGridView"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{x:Bind ViewModel.DirectoryAssets, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedAsset, Mode=TwoWay}">
<GridView.ItemContainerStyle>
<Style BasedOn="{StaticResource DefaultGridViewItemStyle}" TargetType="GridViewItem">
<Setter Property="Margin" Value="2" />
</Style>
</GridView.ItemContainerStyle>
<GridView.ItemTemplate>
<DataTemplate x:DataType="model:ExplorerItem">
<Grid
Width="100"
Height="100"
Padding="8"
DoubleTapped="GridViewItem_DoubleTapped"
IsDoubleTapEnabled="True">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="0.25*" />
</Grid.RowDefinitions>
<FontIcon FontSize="42" Glyph="{x:Bind FullName, Converter={StaticResource AssetPathToGlyphConverter}}" />
<TextBlock
Grid.Row="1"
Margin="8,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind Name}"
TextTrimming="CharacterEllipsis" />
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</ScrollViewer>
<Grid
Grid.Row="2"
Padding="4"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultSolid}"
BorderThickness="0,1,0,0">
<TextBlock
VerticalAlignment="Center"
HorizontalTextAlignment="Left"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind ViewModel.SelectedAsset.FullName, Mode=OneWay}"
TextTrimming="CharacterEllipsis" />
</Grid>
</Grid>
</Grid>
</Page>

View File

@@ -0,0 +1,25 @@
using Ghost.Editor.ViewModels.Pages.EngineEditor;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
namespace Ghost.Editor.View.Pages.EngineEditor;
internal sealed partial class ProjectPage : Page
{
public ProjectViewModel ViewModel
{
get;
}
public ProjectPage()
{
ViewModel = App.GetService<ProjectViewModel>();
InitializeComponent();
}
private void GridViewItem_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
ViewModel.OpenSelected();
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<internal:NavigationTabPage
x:Class="Ghost.Editor.View.Pages.EngineEditor.ScenePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:internal="using:Ghost.Editor.Controls.Internal"
xmlns:local="using:Ghost.Editor.View.Pages.EngineEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<SwapChainPanel
x:Name="SwapChainPanel"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
</internal:NavigationTabPage>

View File

@@ -0,0 +1,54 @@
using Ghost.Editor.Controls.Internal;
using Ghost.Graphics;
using Ghost.Graphics.Contracts;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using SharpGen.Runtime;
using WinRT;
namespace Ghost.Editor.View.Pages.EngineEditor;
internal sealed partial class ScenePage : NavigationTabPage
{
private IRenderView? _renderer;
public ScenePage()
{
InitializeComponent();
SwapChainPanel.Loaded += SwapChainPanel_Loaded;
SwapChainPanel.Unloaded += SwapChainPanel_Unloaded;
SwapChainPanel.SizeChanged += SwapChainPanel_SizeChanged;
}
private void OnRendering(object? sender, object e)
{
_renderer?.Render();
}
private void SwapChainPanel_Loaded(object sender, RoutedEventArgs e)
{
var guid = typeof(Vortice.WinUI.ISwapChainPanelNative).GUID;
Result result = ((IWinRTObject)SwapChainPanel).NativeObject.TryAs(guid, out var swapChainPanelNativeHandle);
result.CheckError();
var swapChainPanelNative = new Vortice.WinUI.ISwapChainPanelNative(swapChainPanelNativeHandle);
_renderer = GraphicsPipeline.GraphicsDevice.CreateRenderView(new(swapChainPanelNative, (uint)SwapChainPanel.ActualWidth, (uint)SwapChainPanel.ActualHeight));
CompositionTarget.Rendering += OnRendering;
}
private void SwapChainPanel_Unloaded(object sender, RoutedEventArgs e)
{
CompositionTarget.Rendering -= OnRendering;
_renderer?.Dispose();
}
private void SwapChainPanel_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.NewSize.Width > 8.0 && e.NewSize.Height > 8.0)
{
_renderer?.Resize((uint)e.NewSize.Width, (uint)e.NewSize.Height);
}
}
}