Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Text;
using System.Text;
using GameWorld.Core.Services;
using Serilog;
using Shared.Core.DependencyInjection;
Expand Down
47 changes: 45 additions & 2 deletions Editors/Kitbashing/KitbasherEditor/Core/KitbasherView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:behaviors="clr-namespace:Shared.Ui.Common.Behaviors;assembly=Shared.Ui"
xmlns:loc="clr-namespace:Shared.Ui.Common;assembly=Shared.Ui"
xmlns:menusystem="clr-namespace:Shared.Ui.Common.MenuSystem;assembly=Shared.Ui"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
AllowDrop="True">
Expand Down Expand Up @@ -43,11 +44,53 @@
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="48"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Left sidebar: Blender-style tool icons (vertical toolbar) -->
<ToolBarTray Grid.Row="0" Grid.Column="0" Orientation="Vertical" Background="{DynamicResource ToolBarTrayBackground}">
<ToolBar Band="0" BandIndex="0" ItemsSource="{Binding MenuBar.SidebarButtons, Mode=OneTime}">
<ToolBar.Resources>
<Style x:Key="SidebarSeparatorStyle" TargetType="Separator">
<Setter Property="Margin" Value="4,8,4,8"/>
<Setter Property="Background" Value="#606060"/>
</Style>
<DataTemplate x:Key="sidebarDefaultTemplate">
<Button ToolTip="{Binding Action.ToolTipAttribute.Value}" BorderThickness="0" Background="Transparent" Margin="2" Padding="6"
IsEnabled="{Binding Action.IsActionEnabled.Value, UpdateSourceTrigger=PropertyChanged}"
Command="{Binding Path=Action.Command}"
Visibility="{Binding IsVisible.Value, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToCollapsedConverter}}">
<Image Height="24" Width="24" Source="{Binding Image}"/>
</Button>
</DataTemplate>
<DataTemplate x:Key="sidebarRadioTemplate">
<RadioButton ToolTip="{Binding Action.ToolTipAttribute.Value}" BorderThickness="0" Background="Transparent" Margin="2" Padding="6"
IsChecked="{Binding IsChecked.Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Command="{Binding Path=Action.Command}"
GroupName="{Binding GroupName}"
Style="{StaticResource {x:Type ToggleButton}}"
IsEnabled="{Binding Action.IsActionEnabled.Value, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding IsVisible.Value, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource BoolToCollapsedConverter}}">
<Image Height="24" Width="24" Source="{Binding Image}"/>
</RadioButton>
</DataTemplate>
<DataTemplate x:Key="sidebarSeparatorTemplate">
<Separator Style="{StaticResource SidebarSeparatorStyle}"/>
</DataTemplate>
<local:SidebarTemplateSelector x:Key="sidebarTemplateSelector"
DefaultTemplate="{StaticResource sidebarDefaultTemplate}"
RadioTemplate="{StaticResource sidebarRadioTemplate}"
SeparatorTemplate="{StaticResource sidebarSeparatorTemplate}"/>
</ToolBar.Resources>
<ToolBar.ItemTemplateSelector>
<StaticResource ResourceKey="sidebarTemplateSelector"/>
</ToolBar.ItemTemplateSelector>
</ToolBar>
</ToolBarTray>

<ContentControl Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Content="{Binding Scene, Mode=OneTime}"/>


<ContentControl Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Content="{Binding Scene, Mode=OneTime}"/>
<editorviews:AnimationPlayerView DataContext="{Binding Animation}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>

<Grid Grid.Row="0" Grid.Column="1"
Expand Down
21 changes: 21 additions & 0 deletions Editors/Kitbashing/KitbasherEditor/Core/KitbasherView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Windows.Controls;
using Shared.Ui.BaseDialogs.PackFileTree;
using Shared.Ui.Common;
using Shared.Ui.Common.MenuSystem;

namespace KitbasherEditor.Views
{
Expand Down Expand Up @@ -33,4 +34,24 @@ private void treeView_Drop(object sender, DragEventArgs e)
}
}
}

public class SidebarTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate RadioTemplate { get; set; }
public DataTemplate SeparatorTemplate { get; set; }

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is MenuBarButton button)
{
if (button.IsSeperator)
return SeparatorTemplate;
if (button is MenuBarGroupButton)
return RadioTemplate;
return DefaultTemplate;
}
return DefaultTemplate;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class MenuBarViewModel : IKeyboardHandler
{
public ObservableCollection<ToolbarItem> MenuItems { get; set; } = new ObservableCollection<ToolbarItem>();
public ObservableCollection<MenuBarButton> CustomButtons { get; set; } = new ObservableCollection<MenuBarButton>();
public ObservableCollection<MenuBarButton> SidebarButtons { get; set; } = new ObservableCollection<MenuBarButton>();
public TransformToolViewModel TransformTool { get; set; }

private readonly IUiCommandFactory _uiCommandFactory;
Expand All @@ -43,6 +44,7 @@ public MenuBarViewModel(CommandExecutor commandExecutor, IEventHub eventHub, Men
RegisterActions();
RegisterHotkeys();
CustomButtons = CreateButtons();
SidebarButtons = CreateVerticalButtons();
MenuItems = CreateToolbarMenu();

eventHub.Register<CommandStackChangedEvent>(this, OnUndoStackChanged);
Expand Down Expand Up @@ -148,20 +150,6 @@ ObservableCollection<MenuBarButton> CreateButtons()
builder.CreateButton<UndoCommand>(IconLibrary.UndoIcon);
builder.CreateButtonSeparator();

// Gizmo buttons
builder.CreateGroupedButton<SelectGizmoModeCommand>("Gizmo", true, IconLibrary.Gizmo_CursorIcon);
builder.CreateGroupedButton<MoveGizmoModeCommand>("Gizmo", false, IconLibrary.Gizmo_MoveIcon);
builder.CreateGroupedButton<RotateGizmoModeCommand>("Gizmo", false, IconLibrary.Gizmo_RotateIcon);
builder.CreateGroupedButton<ScaleGizmoModeCommand>("Gizmo", false, IconLibrary.Gizmo_ScaleIcon);
builder.CreateButtonSeparator();

// Selection buttons
builder.CreateGroupedButton<ObjectSelectionModeCommand>("SelectionMode", true, IconLibrary.Selection_Object_Icon);
builder.CreateGroupedButton<FaceSelectionModeCommand>("SelectionMode", false, IconLibrary.Selection_Face_Icon);
builder.CreateGroupedButton<VertexSelectionModeCommand>("SelectionMode", false, IconLibrary.Selection_Vertex_Icon);
builder.CreateButton<ToggleViewSelectedCommand>(IconLibrary.ViewSelectedIcon);
builder.CreateButtonSeparator();

// Object buttons
builder.CreateButton<DivideSubMeshCommand>(IconLibrary.DivideIntoSubMeshIcon, ButtonVisibilityRule.ObjectMode);
builder.CreateButton<MergeObjectsCommand>(IconLibrary.MergeMeshIcon, ButtonVisibilityRule.ObjectMode);
Expand Down Expand Up @@ -189,6 +177,27 @@ ObservableCollection<MenuBarButton> CreateButtons()
return builder.Build();
}


ObservableCollection<MenuBarButton> CreateVerticalButtons()
{
var builder = new ButtonBuilder(_uiCommands);

// Gizmo buttons
builder.CreateGroupedButton<SelectGizmoModeCommand>("Gizmo", true, IconLibrary.Gizmo_CursorIcon);
builder.CreateGroupedButton<MoveGizmoModeCommand>("Gizmo", false, IconLibrary.Gizmo_MoveIcon);
builder.CreateGroupedButton<RotateGizmoModeCommand>("Gizmo", false, IconLibrary.Gizmo_RotateIcon);
builder.CreateGroupedButton<ScaleGizmoModeCommand>("Gizmo", false, IconLibrary.Gizmo_ScaleIcon);
builder.CreateButtonSeparator();

// Selection buttons
builder.CreateGroupedButton<ObjectSelectionModeCommand>("SelectionMode", true, IconLibrary.Selection_Object_Icon);
builder.CreateGroupedButton<FaceSelectionModeCommand>("SelectionMode", false, IconLibrary.Selection_Face_Icon);
builder.CreateGroupedButton<VertexSelectionModeCommand>("SelectionMode", false, IconLibrary.Selection_Vertex_Icon);
builder.CreateButton<ToggleViewSelectedCommand>(IconLibrary.ViewSelectedIcon);

return builder.Build();
}

void RegisterUiCommand<T>() where T : IKitbasherUiCommand
{
if (_uiCommands.ContainsKey(typeof(T)))
Expand Down Expand Up @@ -244,6 +253,9 @@ void OnSelectionChanged(SelectionChangedEvent notification)
foreach (var button in CustomButtons)
_menuItemVisibilityRuleEngine.Validate(button);

foreach (var button in SidebarButtons)
_menuItemVisibilityRuleEngine.Validate(button);

// Validate if menu action is enabled
foreach (var action in _uiCommands.Values)
_menuItemVisibilityRuleEngine.Validate(action);
Expand Down
12 changes: 12 additions & 0 deletions GameWorld/ContentProject/Content/Content.mgcb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,24 @@
/processorParam:DebugMode=Auto
/build:Shaders/GridShader.fx

#begin Shaders/EdgeQuadShader.fx
/importer:EffectImporter
/processor:EffectProcessor
/processorParam:DebugMode=Auto
/build:Shaders/EdgeQuadShader.fx

#begin Shaders/InstancingShader.fx
/importer:EffectImporter
/processor:EffectProcessor
/processorParam:DebugMode=Auto
/build:Shaders/InstancingShader.fx

#begin Shaders/VertexPointShader.fx
/importer:EffectImporter
/processor:EffectProcessor
/processorParam:DebugMode=Auto
/build:Shaders/VertexPointShader.fx

#begin Shaders/LineShader.fx
/importer:EffectImporter
/processor:EffectProcessor
Expand Down
113 changes: 113 additions & 0 deletions GameWorld/ContentProject/Content/Shaders/EdgeQuadShader.fx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
float4x4 View;
float4x4 Projection;
float ViewportWidth;
float ViewportHeight;

struct VSInput
{
float3 Position : POSITION0;
float3 P0 : POSITION1;
float3 P1 : POSITION2;
float3 C0 : COLOR1;
float3 C1 : COLOR2;
float Width : BLENDWEIGHT0;
};

struct VSOutput
{
float4 Position : SV_POSITION;
float3 Color : COLOR0;
float Edge : TEXCOORD0;
};

float2 WorldToScreen(float3 worldPos)
{
float4 clip = mul(mul(float4(worldPos, 1), View), Projection);
float2 ndc = clip.xy / clip.w;
return float2((ndc.x * 0.5 + 0.5) * ViewportWidth,
(0.5 - ndc.y * 0.5) * ViewportHeight);
}

float WorldToClipW(float3 worldPos)
{
float4 clip = mul(mul(float4(worldPos, 1), View), Projection);
return clip.w;
}

float4 ScreenToClip(float2 screen, float w)
{
float2 ndc = float2(screen.x / ViewportWidth * 2 - 1,
1 - screen.y / ViewportHeight * 2);
return float4(ndc * w, 0, w);
}

VSOutput EdgeQuadVS(VSInput input)
{
VSOutput output;

float2 s0 = WorldToScreen(input.P0);
float2 s1 = WorldToScreen(input.P1);

float2 dir = s1 - s0;
float len = length(dir);

if (len < 0.001)
{
dir = float2(1, 0);
len = 0.001;
}
else
{
dir /= len;
}

float2 perp = float2(-dir.y, dir.x);

float baseWidth = 1.2;
float halfW = baseWidth * 0.5 + 0.5;

float t = input.Position.x;
float side = input.Position.y;

float2 screenPos = lerp(s0, s1, t) + perp * side * halfW;

float w0 = WorldToClipW(input.P0);
float w1 = WorldToClipW(input.P1);
float w = lerp(w0, w1, t);

float4 clipPos = ScreenToClip(screenPos, w);

float bias = -0.00005;
float4 clipP0 = mul(mul(float4(input.P0, 1), View), Projection);
float4 clipP1 = mul(mul(float4(input.P1, 1), View), Projection);
float z0 = clipP0.z / clipP0.w;
float z1 = clipP1.z / clipP1.w;
float z = lerp(z0, z1, t) + bias;

clipPos.z = z * w;

output.Position = clipPos;
output.Color = lerp(input.C0, input.C1, t);
output.Edge = side * 2.0;

return output;
}

float4 EdgeQuadPS(VSOutput input) : SV_Target
{
float dist = abs(input.Edge);
float alpha = 1.0 - smoothstep(0.6, 1.0, dist);
if (alpha < 0.01)
discard;

return float4(input.Color, alpha);
}

technique EdgeQuad
{
pass P0
{
VertexShader = compile vs_4_0 EdgeQuadVS();
PixelShader = compile ps_4_0 EdgeQuadPS();
}
};
Loading
Loading