Skip to content
Open
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
22 changes: 20 additions & 2 deletions .github/workflows/pr-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,23 @@ jobs:
- name: Build the project
run: dotnet build AssetEditor\AssetEditor.csproj --no-restore

- name: Run all tests
run: dotnet test AssetEditor.sln --configuration Release --no-restore --verbosity normal
- name: Run Shared.Core Tests
run: dotnet test Testing\Shared.Core.Test\Test.Shared.Core.csproj --no-restore --verbosity normal

- name: Run GameWorld.Core Tests
run: dotnet test Testing\GameWorld.Core.Test\Test.GameWorld.Core.csproj --no-restore --verbosity normal

- name: Run E2E Verification Tests
run: dotnet test Testing\E2EVerification\Test.E2EVerification.csproj --no-restore --verbosity normal

- name: Run Editors.ImportExport Tests
run: dotnet test Editors\ImportExportEditor\Test.ImportExport\Test.ImportExport.csproj --no-restore --verbosity normal

- name: Run Editors.SkeletonEditor Tests
run: dotnet test Editors\SkeletonEditor\Test.SkeletonEditor\Test.SkeletonEditor.csproj --no-restore --verbosity normal

- name: Run Editors.AnimatioReTarget Tests
run: dotnet test Editors\AnimationReTarget\Test.AnimatioReTarget\Test.AnimatioReTarget.csproj --no-restore --verbosity normal

- name: Run Editors.Kitbashing Tests
run: dotnet test Editors\Kitbashing\Test.KitbashEditor\Test.KitbashEditor.csproj --no-restore --verbosity normal
92 changes: 41 additions & 51 deletions AssetEditor/Views/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -158,54 +158,28 @@
<GridSplitter Grid.Row="1" Grid.RowSpan="1" Grid.Column="1" Width="2.9" HorizontalAlignment="Stretch" Background="{DynamicResource App.Border}"
Visibility="{Binding IsPackFileExplorerVisible, Converter={StaticResource BoolToVisibilityConverter}}"/>

<views:CachedTabControl Grid.Row="1" Grid.Column="2" ItemsSource="{Binding EditorManager.CurrentEditorsList, UpdateSourceTrigger=PropertyChanged}"
<TabControl Grid.Row="1" Grid.Column="2" ItemsSource="{Binding EditorManager.CurrentEditorsList, UpdateSourceTrigger=PropertyChanged}"
SelectedIndex="{Binding EditorManager.SelectedEditorIndex, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
ContentTemplateSelector="{StaticResource EditorSelector}" viewFactory:ToolFactoryParameter.ViewFactory="{Binding ToolsFactory}"
x:Name="EditorsTabControl" BorderThickness="1, 1, 0, 0" >
Name="EditorsTabControl" BorderThickness="1, 1, 0, 0" >

<views:CachedTabControl.Template>
<!-- [Crucial Fix]: TargetType must be strictly set to views:CachedTabControl to prevent rendering crashes or white screens -->
<ControlTemplate TargetType="{x:Type views:CachedTabControl}">
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabControl.Resources>
<common:BindingProxy x:Key="Proxy" Data="{Binding}" />
</TabControl.Resources>

<!-- This line controls the display of the tab headers -->
<TabPanel x:Name="HeaderPanel" Panel.ZIndex="1" Margin="0,2,2,0" IsItemsHost="True" KeyboardNavigation.TabIndex="1" Background="Transparent" />
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
<EventSetter Event="Drop" Handler="TabItem_Drop"/>
<EventSetter Event="PreviewMouseMove" Handler="TabItem_MouseMove"/>
<EventSetter Event="PreviewMouseDown" Handler="TabItem_MouseDown"/>
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="behaviors:MouseMiddleClick.Command" Value="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolCommand}"/>
<Setter Property="behaviors:MouseMiddleClick.CommandParameter" Value="{Binding}"/>
</Style>
</TabControl.ItemContainerStyle>

<!-- [Crucial Fix]: This binds to the AssetEditor exclusive dark theme color TabItem.Static.Background -->
<Border x:Name="Border" Grid.Row="1"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{DynamicResource App.Border}"
Background="{DynamicResource TabItem.Static.Background}"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2">
<Grid x:Name="PART_ItemsHolder" />
</Border>
</Grid>
</ControlTemplate>
</views:CachedTabControl.Template>

<views:CachedTabControl.Resources>
<common:BindingProxy x:Key="Proxy" Data="{Binding}" />
</views:CachedTabControl.Resources>

<views:CachedTabControl.ItemContainerStyle>
<!-- Ensure each child tab item inherits the native theme and events -->
<Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
<EventSetter Event="Drop" Handler="TabItem_Drop"/>
<EventSetter Event="PreviewMouseMove" Handler="TabItem_MouseMove"/>
<EventSetter Event="PreviewMouseDown" Handler="TabItem_MouseDown"/>
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="behaviors:MouseMiddleClick.Command" Value="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolCommand}"/>
<Setter Property="behaviors:MouseMiddleClick.CommandParameter" Value="{Binding}"/>
</Style>
</views:CachedTabControl.ItemContainerStyle>

<views:CachedTabControl.ItemTemplate>
<TabControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.Resources>
Expand All @@ -219,12 +193,22 @@

<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Close" Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolCommand}" CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}" />
<MenuItem Header="Close"
Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolCommand}"
CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}" />
<MenuItem Header="Close Multiple">
<MenuItem Header="Close Other Tabs" Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseOtherToolsCommand}" CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
<MenuItem Header="Close All Tabs" Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseAllToolsCommand}" CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
<MenuItem Header="Close Tabs To Left" Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolsToLeftCommand}" CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
<MenuItem Header="Close Tabs To Right" Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolsToRightCommand}" CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
<MenuItem Header="Close Other Tabs"
Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseOtherToolsCommand}"
CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
<MenuItem Header="Close All Tabs"
Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseAllToolsCommand}"
CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
<MenuItem Header="Close Tabs To Left"
Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolsToLeftCommand}"
CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
<MenuItem Header="Close Tabs To Right"
Command="{Binding Source={StaticResource Proxy}, Path=Data.CloseToolsToRightCommand}"
CommandParameter="{Binding Source={StaticResource GridProxy}, Path=Data}"/>
</MenuItem>
</ContextMenu>
</Grid.ContextMenu>
Expand All @@ -240,12 +224,18 @@
</Style>
</TextBlock.Style>
</TextBlock>
<Button Margin="4,0,-4,0" Grid.Column="1" Command="{Binding DataContext.CloseToolCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=TabControl}}" CommandParameter="{Binding}" HorizontalContentAlignment="Right" Content="{materialIcons:MaterialIconExt Kind=CloseThick, Size=13 }">
<Button
Margin="4,0,-4,0"
Grid.Column="1"
Command="{Binding DataContext.CloseToolCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=TabControl}}"
CommandParameter="{Binding}"
HorizontalContentAlignment="Right"
Content="{materialIcons:MaterialIconExt Kind=CloseThick, Size=13 }">
</Button>
</Grid>
</DataTemplate>
</views:CachedTabControl.ItemTemplate>
</views:CachedTabControl>
</TabControl.ItemTemplate>
</TabControl>
</Grid>
</Border>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using CommonControls.BaseDialogs.ErrorListDialog;
using CommonControls.BaseDialogs.ErrorListDialog;
using Editors.Shared.Core.Editors.TextEditor;
using GameWorld.Core.Services;
using Shared.Core.ErrorHandling;
Expand Down Expand Up @@ -301,8 +301,9 @@ private bool CheckForAnimationVersionsInMeta(string mainAnimationFile, string me

foreach (var item in metaItems)
{
if (item.DisplayName.Contains("SPLICE") && item is Splice_v11 splice)
if (item.DisplayName.Contains("SPLICE"))
{
var splice = (Splice_v11)item;
var animPath = splice.Animation;
if (animPath == null || animPath == "")
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ public override void Register(IServiceCollection services)
services.AddTransient<IExporterViewModel, DdsToMaterialPngViewModel>();
services.AddTransient<IExporterViewModel, DdsToNormalPngViewModel>();
services.AddTransient<IExporterViewModel, RmvToGltfExporterViewModel>();
services.AddTransient<IExporterViewModel, RmvToGltfStaticExporterViewModel>();

// Exporters
services.AddTransient<IDdsToMaterialPngExporter, DdsToMaterialPngExporter>();
services.AddTransient<DdsToPngExporter>();
services.AddTransient<IDdsToNormalPngExporter, DdsToNormalPngExporter>();
services.AddTransient<RmvToGltfExporter>();
services.AddTransient<RmvToGltfStaticExporter>();

// Importer ViewModels
RegisterWindow<ImportWindow>(services);
Expand All @@ -60,6 +62,7 @@ public override void Register(IServiceCollection services)
services.AddTransient<DisplayImportFileToolCommand>();

services.AddTransient<GltfMeshBuilder>();
services.AddTransient<GltfStaticMeshBuilder>();
services.AddTransient<IGltfTextureHandler, GltfTextureHandler>();
services.AddTransient<IGltfSceneSaver, GltfSceneSaver>();
services.AddTransient<IGltfSceneLoader, GltfSceneLoader>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0-windows</TargetFramework>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Drawing;
using System.Drawing;
using System.IO;
using System.Numerics;
using Editors.ImportExport.Misc;
Expand Down Expand Up @@ -43,7 +43,7 @@ public string Export(string filePath, string outputPath, bool convertToBlueNorma

var fileName = Path.GetFileNameWithoutExtension(filePath);
var outDirectory = Path.GetDirectoryName(outputPath);
var fullFilePath = outDirectory + "/" + fileName + ".png";
var rawFilePath = outDirectory + "/" + fileName + "_raw.png";

var bytes = packFile.DataSource.ReadData();
if (bytes == null || !bytes.Any())
Expand All @@ -53,73 +53,9 @@ public string Export(string filePath, string outputPath, bool convertToBlueNorma
if (imgBytes == null || !imgBytes.Any())
throw new Exception($"image data invalid/empty. imgBytes.Count = {imgBytes?.Length}");

if (convertToBlueNormalMap)
imgBytes = ConvertToBlueNormalMap(imgBytes, fullFilePath);
_imageSaveHandler.Save(imgBytes, rawFilePath);

_imageSaveHandler.Save(imgBytes, fullFilePath);
return fullFilePath;
return rawFilePath;
}


private byte[] ConvertToBlueNormalMap(byte[] imgBytes, string fileDirectory)
{
var inMs = new MemoryStream(imgBytes);
using Image inImg = Image.FromStream(inMs);

using Bitmap bitmap = new Bitmap(inImg);
{
for (int x = 0; x < bitmap.Width; x++)
{
for (int y = 0; y < bitmap.Height; y++)
{
// get pixel from orange map
var orangeMapRawPixel = bitmap.GetPixel(x, y);

// convert bytes to float to interval [0; 1]
Vector4 orangeMapVector = new Vector4()
{
X = (float)orangeMapRawPixel.R / 255.0f,
Y = (float)orangeMapRawPixel.G / 255.0f,
Z = (float)orangeMapRawPixel.B / 255.0f,
W = (float)orangeMapRawPixel.A / 255.0f,
};

// fill blue map pixels
Vector3 blueMapPixel = new Vector3()
{
X = orangeMapVector.X * orangeMapVector.W,
Y = orangeMapVector.Y,
Z = 0
};

// scale bluemap into interval [-1; 1]
blueMapPixel *= 2.0f;
blueMapPixel -= new Vector3(1, 1, 1);


// calculte z, using an orthogonal projection
blueMapPixel.Z = (float)Math.Sqrt(1.0f - blueMapPixel.X * blueMapPixel.X - blueMapPixel.Y * blueMapPixel.Y);


// convert the float values back to bytes, interval [0; 255]
var newColor = Color.FromArgb(
255,
(byte)((blueMapPixel.X + 1.0f) * 0.5f * 255.0f),
(byte)((blueMapPixel.Y + 1.0f) * 0.5f * 255.0f),
(byte)((blueMapPixel.Z + 1.0f) * 0.5f * 255.0f)
);

bitmap.SetPixel(x, y, newColor);
}
}

// get raw PNG bytes
using var b = new MemoryStream();
bitmap.Save(b, System.Drawing.Imaging.ImageFormat.Png);

return b.ToArray();
}
}

}
}
Loading
Loading