1 Commits

Author SHA1 Message Date
fd5c50635c some mac changes?
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2026-02-12 18:40:05 +02:00
654 changed files with 6565 additions and 59240 deletions

17
.github/data/bt.sh vendored
View File

@@ -1,17 +0,0 @@
#!/bin/sh
# https://gist.github.com/ongardie/aa15f1f0d0e6b59890a9
gdb -q --batch \
-ex 'handle SIGHUP nostop pass' \
-ex 'handle SIGQUIT nostop pass' \
-ex 'handle SIGPIPE nostop pass' \
-ex 'handle SIGALRM nostop pass' \
-ex 'handle SIGTERM nostop pass' \
-ex 'handle SIGUSR1 nostop pass' \
-ex 'handle SIGUSR2 nostop pass' \
-ex 'handle SIGCHLD nostop pass' \
-ex 'set print thread-events off' \
-return-child-result \
-ex 'run' \
-ex 'thread apply all bt' \
--tty=/dev/stdout \
--args $*

View File

@@ -45,8 +45,7 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev libwayland-dev
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
- name: Setup Vulkan - name: Setup Vulkan
uses: ./.github/actions/vulkan uses: ./.github/actions/vulkan
- name: Setup .NET - name: Setup .NET

View File

@@ -88,7 +88,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan - name: Setup Vulkan
uses: ./.github/actions/vulkan uses: ./.github/actions/vulkan
- name: Setup .NET - name: Setup .NET
@@ -120,7 +120,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan - name: Setup Vulkan
uses: ./.github/actions/vulkan uses: ./.github/actions/vulkan
- name: Setup .NET - name: Setup .NET

View File

@@ -29,22 +29,25 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev gdb sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
chmod +x .github/data/bt.sh
- name: Build - name: Build
run: | run: |
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8 ./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=8 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true ./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=8 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
- name: Test - name: Test
run: | run: |
${GITHUB_WORKSPACE}/.github/data/bt.sh ./Binaries/Editor/Linux/Development/FlaxTests -headless ${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
dotnet test -f net8.0 Binaries/Tests/Flax.Build.Tests.dll dotnet test -f net8.0 Binaries/Tests/Flax.Build.Tests.dll
cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.dll Binaries/Tests cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.dll Binaries/Tests
cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.runtimeconfig.json Binaries/Tests cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.runtimeconfig.json Binaries/Tests
cp Binaries/Editor/Linux/Development/Newtonsoft.Json.dll Binaries/Tests cp Binaries/Editor/Linux/Development/Newtonsoft.Json.dll Binaries/Tests
dotnet test -f net8.0 Binaries/Tests/FlaxEngine.CSharp.dll dotnet test -f net8.0 Binaries/Tests/FlaxEngine.CSharp.dll
- name: Test UseLargeWorlds
run: |
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=8 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
# Tests on Windows # Tests on Windows
tests-windows: tests-windows:
@@ -74,7 +77,7 @@ jobs:
shell: pwsh shell: pwsh
run: | run: |
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
.\Binaries\Editor\Win64\Development\FlaxTests.exe -headless .\Binaries\Editor\Win64\Development\FlaxTests.exe
if(!$?) { Write-Host "Tests failed with exit code $LastExitCode" -ForegroundColor Red; Exit $LastExitCode } if(!$?) { Write-Host "Tests failed with exit code $LastExitCode" -ForegroundColor Red; Exit $LastExitCode }
dotnet test -f net8.0 Binaries\Tests\Flax.Build.Tests.dll dotnet test -f net8.0 Binaries\Tests\Flax.Build.Tests.dll
xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.dll Binaries\Tests xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.dll Binaries\Tests

View File

@@ -1,4 +1,4 @@
# Redirect to our own Git LFS server # Redirect to our own Git LFS server
[lfs] [lfs]
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs" url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false locksverify = false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -42,10 +42,10 @@ struct MaterialInput
float2 SvPositionToDecalUV(float4 svPosition) float2 SvPositionToDecalUV(float4 svPosition)
{ {
float2 screenUV = svPosition.xy * ScreenSize.zw; float2 screenUV = svPosition.xy * ScreenSize.zw;
svPosition.z = SAMPLE_RT_DEPTH(DepthBuffer, screenUV); svPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
float4 positionHS = PROJECT_POINT(float4(svPosition.xyz, 1), SvPositionToWorld); float4 positionHS = mul(float4(svPosition.xyz, 1), SvPositionToWorld);
float3 positionWS = positionHS.xyz / positionHS.w; float3 positionWS = positionHS.xyz / positionHS.w;
float3 positionOS = PROJECT_POINT(float4(positionWS, 1), InvWorld).xyz; float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
return positionOS.xz + 0.5f; return positionOS.xz + 0.5f;
} }
@@ -182,10 +182,10 @@ META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true)
void VS_Decal(in float3 Position : POSITION0, out float4 SvPosition : SV_Position) void VS_Decal(in float3 Position : POSITION0, out float4 SvPosition : SV_Position)
{ {
// Compute world space vertex position // Compute world space vertex position
float3 worldPosition = PROJECT_POINT(float4(Position.xyz, 1), WorldMatrix).xyz; float3 worldPosition = mul(float4(Position.xyz, 1), WorldMatrix).xyz;
// Compute clip space position // Compute clip space position
SvPosition = PROJECT_POINT(float4(worldPosition.xyz, 1), ViewProjectionMatrix); SvPosition = mul(float4(worldPosition.xyz, 1), ViewProjectionMatrix);
} }
// Pixel Shader function for decals rendering // Pixel Shader function for decals rendering
@@ -213,11 +213,11 @@ void PS_Decal(
} }
float2 screenUV = SvPosition.xy * ScreenSize.zw; float2 screenUV = SvPosition.xy * ScreenSize.zw;
SvPosition.z = SAMPLE_RT_DEPTH(DepthBuffer, screenUV); SvPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
float4 positionHS = PROJECT_POINT(float4(SvPosition.xyz, 1), SvPositionToWorld); float4 positionHS = mul(float4(SvPosition.xyz, 1), SvPositionToWorld);
float3 positionWS = positionHS.xyz / positionHS.w; float3 positionWS = positionHS.xyz / positionHS.w;
float3 positionOS = PROJECT_POINT(float4(positionWS, 1), InvWorld).xyz; float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
clip(0.5 - abs(positionOS.xyz)); clip(0.5 - abs(positionOS.xyz));
float2 decalUVs = positionOS.xz + 0.5f; float2 decalUVs = positionOS.xz + 0.5f;

View File

@@ -308,7 +308,7 @@ VertexOutput VS_SplineModel(ModelInput input)
world = mul(world, WorldMatrix); world = mul(world, WorldMatrix);
// Compute clip space position // Compute clip space position
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes // Pass vertex attributes
output.Geometry.TexCoord = input.TexCoord0; output.Geometry.TexCoord = input.TexCoord0;
@@ -338,7 +338,7 @@ VertexOutput VS_SplineModel(ModelInput input)
#if USE_POSITION_OFFSET #if USE_POSITION_OFFSET
output.Geometry.WorldPosition += material.PositionOffset; output.Geometry.WorldPosition += material.PositionOffset;
output.Geometry.PrevWorldPosition += material.PositionOffset; output.Geometry.PrevWorldPosition += material.PositionOffset;
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
#endif #endif
// Get tessalation multiplier (per vertex) // Get tessalation multiplier (per vertex)

View File

@@ -67,7 +67,7 @@ float Rand(inout uint seed)
float3 ReprojectPosition(float2 uv, float rawDepth) float3 ReprojectPosition(float2 uv, float rawDepth)
{ {
uv = uv * float2(2.0, -2.0) + float2(-1.0, 1.0); uv = uv * float2(2.0, -2.0) + float2(-1.0, 1.0);
float4 pos = PROJECT_POINT(float4(uv.x, uv.y, rawDepth, 1.0f), InvViewProjectionMatrix); float4 pos = mul(float4(uv.x, uv.y, rawDepth, 1.0f), InvViewProjectionMatrix);
return pos.xyz / pos.w; return pos.xyz / pos.w;
} }
@@ -158,7 +158,7 @@ void SpawnParticle(Context context)
@4} @4}
// Main entry point for the particles simulation and spawning // Main entry point for the particles simulation and spawning
META_CS(true, AUTO) META_CS(true, FEATURE_LEVEL_SM5)
[numthreads(THREAD_GROUP_SIZE, 1, 1)] [numthreads(THREAD_GROUP_SIZE, 1, 1)]
void CS_Main(uint3 dispatchThreadId : SV_DispatchThreadID) void CS_Main(uint3 dispatchThreadId : SV_DispatchThreadID)
{ {

View File

@@ -227,7 +227,7 @@ VertexOutput VS_GUI(Render2DVertex input)
if ((int)input.CustomDataAndClipOrigin.y & 1) if ((int)input.CustomDataAndClipOrigin.y & 1)
input.Position = (int2)input.Position; input.Position = (int2)input.Position;
output.Position = PROJECT_POINT(float4(input.Position, 0, 1), ViewProjectionMatrix); output.Position = mul(float4(input.Position, 0, 1), ViewProjectionMatrix);
output.WorldPosition = mul(float4(input.Position, 0, 1), WorldMatrix).xyz; output.WorldPosition = mul(float4(input.Position, 0, 1), WorldMatrix).xyz;
output.TexCoord = input.TexCoord; output.TexCoord = input.TexCoord;
output.WindowPos = input.Position; output.WindowPos = input.Position;

View File

@@ -393,7 +393,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
output.WorldPosition = position + spriteVertexPosition; output.WorldPosition = position + spriteVertexPosition;
// Compute clip space position // Compute clip space position
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
// Pass vertex attributes // Pass vertex attributes
output.TexCoord = input.TexCoord; output.TexCoord = input.TexCoord;
@@ -431,7 +431,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
// Apply world position offset per-vertex // Apply world position offset per-vertex
#if USE_POSITION_OFFSET #if USE_POSITION_OFFSET
output.WorldPosition += material.PositionOffset; output.WorldPosition += material.PositionOffset;
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
#endif #endif
// Copy interpolants for other shader stages // Copy interpolants for other shader stages
@@ -511,7 +511,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
output.WorldPosition = mul(float4(input.Position, 1), world).xyz; output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
// Compute clip space position // Compute clip space position
output.Position = PROJECT_POINT(float4(output.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes // Pass vertex attributes
output.TexCoord = input.TexCoord0; output.TexCoord = input.TexCoord0;
@@ -549,7 +549,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
// Apply world position offset per-vertex // Apply world position offset per-vertex
#if USE_POSITION_OFFSET #if USE_POSITION_OFFSET
output.WorldPosition += material.PositionOffset; output.WorldPosition += material.PositionOffset;
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
#endif #endif
// Copy interpolants for other shader stages // Copy interpolants for other shader stages
@@ -617,7 +617,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
output.WorldPosition = position + tangentRight * vertexSign * (ribbonWidth.xxx * 0.5f); output.WorldPosition = position + tangentRight * vertexSign * (ribbonWidth.xxx * 0.5f);
// Compute clip space position // Compute clip space position
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
// Pass vertex attributes // Pass vertex attributes
output.ParticleIndex = particleIndex; output.ParticleIndex = particleIndex;
@@ -655,7 +655,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
// Apply world position offset per-vertex // Apply world position offset per-vertex
#if USE_POSITION_OFFSET #if USE_POSITION_OFFSET
output.WorldPosition += material.PositionOffset; output.WorldPosition += material.PositionOffset;
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix); output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
#endif #endif
// Copy interpolants for other shader stages // Copy interpolants for other shader stages

View File

@@ -342,7 +342,7 @@ VertexOutput VS(ModelInput input)
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), object.PrevWorldMatrix).xyz; output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), object.PrevWorldMatrix).xyz;
// Compute clip space position // Compute clip space position
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes // Pass vertex attributes
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1); output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
@@ -378,7 +378,7 @@ VertexOutput VS(ModelInput input)
#if USE_POSITION_OFFSET #if USE_POSITION_OFFSET
output.Geometry.WorldPosition += material.PositionOffset; output.Geometry.WorldPosition += material.PositionOffset;
output.Geometry.PrevWorldPosition += material.PositionOffset; output.Geometry.PrevWorldPosition += material.PositionOffset;
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
#endif #endif
// Get tessalation multiplier (per vertex) // Get tessalation multiplier (per vertex)
@@ -412,7 +412,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
// Transform vertex position into the screen // Transform vertex position into the screen
float3 worldPosition = mul(float4(input.Position.xyz, 1), object.WorldMatrix).xyz; float3 worldPosition = mul(float4(input.Position.xyz, 1), object.WorldMatrix).xyz;
float4 position = PROJECT_POINT(float4(worldPosition, 1), ViewProjectionMatrix); float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
return position; return position;
} }
@@ -518,7 +518,7 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
#endif #endif
// Compute clip space position // Compute clip space position
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes // Pass vertex attributes
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1); output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
@@ -549,7 +549,7 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
#if USE_POSITION_OFFSET #if USE_POSITION_OFFSET
output.Geometry.WorldPosition += material.PositionOffset; output.Geometry.WorldPosition += material.PositionOffset;
output.Geometry.PrevWorldPosition += material.PositionOffset; output.Geometry.PrevWorldPosition += material.PositionOffset;
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
#endif #endif
// Get tessalation multiplier (per vertex) // Get tessalation multiplier (per vertex)

View File

@@ -388,7 +388,7 @@ VertexOutput VS(TerrainVertexInput input)
output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz; output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz;
// Compute clip space position // Compute clip space position
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes // Pass vertex attributes
#if USE_SMOOTH_LOD_TRANSITION #if USE_SMOOTH_LOD_TRANSITION
@@ -436,7 +436,7 @@ VertexOutput VS(TerrainVertexInput input)
// Apply world position offset per-vertex // Apply world position offset per-vertex
#if USE_POSITION_OFFSET #if USE_POSITION_OFFSET
output.Geometry.WorldPosition += material.PositionOffset; output.Geometry.WorldPosition += material.PositionOffset;
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix); output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
#endif #endif
// Get tessalation multiplier (per vertex) // Get tessalation multiplier (per vertex)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -4,7 +4,7 @@
"Major": 1, "Major": 1,
"Minor": 12, "Minor": 12,
"Revision": 0, "Revision": 0,
"Build": 6908 "Build": 6905
}, },
"Company": "Flax", "Company": "Flax",
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.", "Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",

View File

@@ -12,6 +12,6 @@ cd "`dirname "$0"`"
bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@" bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
# Build bindings for all editor configurations # Build bindings for all editor configurations
echo Building C# bindings... #echo Building C# bindings...
# TODO: Detect the correct architecture here # TODO: Detect the correct architecture here
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor #Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor

View File

@@ -45,8 +45,6 @@ namespace FlaxEditor.Content.Thumbnails
{ {
if (item == null) if (item == null)
throw new ArgumentNullException(); throw new ArgumentNullException();
if (_task == null)
return;
// Check if use default icon // Check if use default icon
var defaultThumbnail = item.DefaultThumbnail; var defaultThumbnail = item.DefaultThumbnail;
@@ -225,12 +223,11 @@ namespace FlaxEditor.Content.Thumbnails
/// <inheritdoc /> /// <inheritdoc />
public override void OnInit() public override void OnInit()
{ {
if (Editor.IsHeadlessMode || (GPUDevice.Instance != null && GPUDevice.Instance.RendererType == RendererType.Null))
return;
// Create cache folder // Create cache folder
if (!Directory.Exists(_cacheFolder)) if (!Directory.Exists(_cacheFolder))
{
Directory.CreateDirectory(_cacheFolder); Directory.CreateDirectory(_cacheFolder);
}
// Find atlases in a Editor cache directory // Find atlases in a Editor cache directory
var files = Directory.GetFiles(_cacheFolder, "cache_*.flax", SearchOption.TopDirectoryOnly); var files = Directory.GetFiles(_cacheFolder, "cache_*.flax", SearchOption.TopDirectoryOnly);
@@ -485,7 +482,7 @@ namespace FlaxEditor.Content.Thumbnails
public override void OnUpdate() public override void OnUpdate()
{ {
// Wait some frames before start generating previews (late init feature) // Wait some frames before start generating previews (late init feature)
if (Time.TimeSinceStartup < 1.0f || HasAllAtlasesLoaded() == false || _task == null) if (Time.TimeSinceStartup < 1.0f || HasAllAtlasesLoaded() == false)
return; return;
lock (_requests) lock (_requests)

View File

@@ -141,11 +141,6 @@ API_ENUM() enum class BuildPlatform
/// </summary> /// </summary>
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")") API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
WindowsARM64 = 15, WindowsARM64 = 15,
/// <summary>
/// Web
/// </summary>
Web = 16,
}; };
/// <summary> /// <summary>
@@ -193,11 +188,6 @@ enum class DotNetAOTModes
/// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library. /// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library.
/// </summary> /// </summary>
MonoAOTStatic, MonoAOTStatic,
/// <summary>
/// Target platform doesn't support .NET or it has been disabled.
/// </summary>
NoDotnet,
}; };
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform); extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);

View File

@@ -69,10 +69,6 @@
#include "Platform/iOS/iOSPlatformTools.h" #include "Platform/iOS/iOSPlatformTools.h"
#include "Engine/Platform/iOS/iOSPlatformSettings.h" #include "Engine/Platform/iOS/iOSPlatformSettings.h"
#endif #endif
#if PLATFORM_TOOLS_WEB
#include "Platform/Web/WebPlatformTools.h"
#include "Engine/Platform/Web/WebPlatformSettings.h"
#endif
namespace GameCookerImpl namespace GameCookerImpl
{ {
@@ -155,8 +151,6 @@ const Char* ToString(const BuildPlatform platform)
return TEXT("iOS ARM64"); return TEXT("iOS ARM64");
case BuildPlatform::WindowsARM64: case BuildPlatform::WindowsARM64:
return TEXT("Windows ARM64"); return TEXT("Windows ARM64");
case BuildPlatform::Web:
return TEXT("Web");
default: default:
return TEXT(""); return TEXT("");
} }
@@ -189,8 +183,6 @@ const Char* ToString(const DotNetAOTModes mode)
return TEXT("MonoAOTDynamic"); return TEXT("MonoAOTDynamic");
case DotNetAOTModes::MonoAOTStatic: case DotNetAOTModes::MonoAOTStatic:
return TEXT("MonoAOTStatic"); return TEXT("MonoAOTStatic");
case DotNetAOTModes::NoDotnet:
return TEXT("NoDotnet");
default: default:
return TEXT(""); return TEXT("");
} }
@@ -315,10 +307,6 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
platform = TEXT("Windows"); platform = TEXT("Windows");
architecture = TEXT("ARM64"); architecture = TEXT("ARM64");
break; break;
case BuildPlatform::Web:
platform = TEXT("Web");
architecture = TEXT("x86");
break;
default: default:
LOG(Fatal, "Unknown or unsupported build platform."); LOG(Fatal, "Unknown or unsupported build platform.");
} }
@@ -473,11 +461,6 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
case BuildPlatform::iOSARM64: case BuildPlatform::iOSARM64:
result = New<iOSPlatformTools>(); result = New<iOSPlatformTools>();
break; break;
#endif
#if PLATFORM_TOOLS_WEB
case BuildPlatform::Web:
result = New<WebPlatformTools>();
break;
#endif #endif
} }
Tools.Add(platform, result); Tools.Add(platform, result);
@@ -621,9 +604,6 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
case PlatformType::iOS: case PlatformType::iOS:
buildPlatform = BuildPlatform::iOSARM64; buildPlatform = BuildPlatform::iOSARM64;
break; break;
case PlatformType::Web:
buildPlatform = BuildPlatform::Web;
break;
default: ; default: ;
} }
} }

View File

@@ -106,7 +106,6 @@ namespace FlaxEditor
case BuildPlatform.MacOSARM64: case BuildPlatform.MacOSARM64:
case BuildPlatform.MacOSx64: return PlatformType.Mac; case BuildPlatform.MacOSx64: return PlatformType.Mac;
case BuildPlatform.iOSARM64: return PlatformType.iOS; case BuildPlatform.iOSARM64: return PlatformType.iOS;
case BuildPlatform.Web: return PlatformType.Web;
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null); default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
} }
} }

View File

@@ -138,7 +138,6 @@ Array<byte> AndroidPlatformTools::SaveCache(CookingData& data, IBuildCache* cach
result.Add((const byte*)&platformCache, sizeof(platformCache)); result.Add((const byte*)&platformCache, sizeof(platformCache));
return result; return result;
} }
void AndroidPlatformTools::OnBuildStarted(CookingData& data) void AndroidPlatformTools::OnBuildStarted(CookingData& data)
{ {
// Adjust the cooking output folder to be located inside the Gradle assets directory // Adjust the cooking output folder to be located inside the Gradle assets directory
@@ -413,6 +412,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
} }
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024); LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
return false; return false;
} }

View File

@@ -1,271 +0,0 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#if PLATFORM_TOOLS_WEB
#include "WebPlatformTools.h"
#include "Engine/Platform/File.h"
#include "Engine/Platform/FileSystem.h"
#include "Engine/Platform/CreateProcessSettings.h"
#include "Engine/Platform/Web/WebPlatformSettings.h"
#include "Engine/Core/Types/Span.h"
#include "Engine/Core/Math/Vector2.h"
#include "Engine/Core/Config/GameSettings.h"
#include "Engine/Core/Config/BuildSettings.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/JsonAsset.h"
#include "Engine/Graphics/PixelFormatExtensions.h"
#include "Engine/Graphics/Textures/TextureBase.h"
#include "Editor/Cooker/GameCooker.h"
IMPLEMENT_SETTINGS_GETTER(WebPlatformSettings, WebPlatform);
namespace
{
struct WebPlatformCache
{
WebPlatformSettings::TextureCompression TexturesCompression;
};
}
const Char* WebPlatformTools::GetDisplayName() const
{
return TEXT("Web");
}
const Char* WebPlatformTools::GetName() const
{
return TEXT("Web");
}
PlatformType WebPlatformTools::GetPlatform() const
{
return PlatformType::Web;
}
ArchitectureType WebPlatformTools::GetArchitecture() const
{
return ArchitectureType::x86;
}
DotNetAOTModes WebPlatformTools::UseAOT() const
{
return DotNetAOTModes::MonoAOTDynamic;//MonoAOTStatic;// DotNetAOTModes::None;//DotNetAOTModes::MonoAOTStatic;//DotNetAOTModes::NoDotnet;
}
PixelFormat WebPlatformTools::GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format)
{
const auto platformSettings = WebPlatformSettings::Get();
const auto uncompressed = PixelFormatExtensions::FindUncompressedFormat(format);
switch (platformSettings->TexturesCompression)
{
case WebPlatformSettings::TextureCompression::Uncompressed:
return uncompressed;
case WebPlatformSettings::TextureCompression::BC:
return format;
case WebPlatformSettings::TextureCompression::ASTC:
switch (format)
{
case PixelFormat::BC4_SNorm:
return PixelFormat::R8_SNorm;
case PixelFormat::BC5_SNorm:
return PixelFormat::R16G16_SNorm;
case PixelFormat::BC6H_Typeless:
case PixelFormat::BC6H_Uf16:
case PixelFormat::BC6H_Sf16:
case PixelFormat::BC7_Typeless:
case PixelFormat::BC7_UNorm:
case PixelFormat::BC7_UNorm_sRGB:
return PixelFormat::R16G16B16A16_Float; // TODO: ASTC HDR
default:
return PixelFormatExtensions::IsSRGB(format) ? PixelFormat::ASTC_6x6_UNorm_sRGB : PixelFormat::ASTC_6x6_UNorm;
}
case WebPlatformSettings::TextureCompression::Basis:
switch (format)
{
case PixelFormat::BC7_Typeless:
case PixelFormat::BC7_UNorm:
case PixelFormat::BC7_UNorm_sRGB:
return PixelFormat::R16G16B16A16_Float; // Basic Universal doesn't support alpha in BC7 (and it can be loaded only from LDR formats)
default:
if (uncompressed != format && texture->Size().MinValue() >= 16)
return PixelFormat::Basis;
return uncompressed;
}
default:
return format;
}
}
void WebPlatformTools::LoadCache(CookingData& data, IBuildCache* cache, const Span<byte>& bytes)
{
const auto platformSettings = WebPlatformSettings::Get();
bool invalidTextures = true;
if (bytes.Length() == sizeof(WebPlatformCache))
{
auto* platformCache = (WebPlatformCache*)bytes.Get();
invalidTextures = platformCache->TexturesCompression != platformSettings->TexturesCompression;
}
if (invalidTextures)
{
LOG(Info, "{0} option has been modified.", TEXT("TexturesQuality"));
cache->InvalidateCacheTextures();
}
}
Array<byte> WebPlatformTools::SaveCache(CookingData& data, IBuildCache* cache)
{
const auto platformSettings = WebPlatformSettings::Get();
WebPlatformCache platformCache;
platformCache.TexturesCompression = platformSettings->TexturesCompression;
Array<byte> result;
result.Add((const byte*)&platformCache, sizeof(platformCache));
return result;
}
bool WebPlatformTools::IsNativeCodeFile(CookingData& data, const String& file)
{
String extension = FileSystem::GetExtension(file);
return extension.IsEmpty() || extension == TEXT("html") || extension == TEXT("js") || extension == TEXT("wasm");
}
void WebPlatformTools::OnBuildStarted(CookingData& data)
{
// Adjust the cooking output folder for the data files so file_packager tool can compress and output final data inside the cooker output folder
data.DataOutputPath = data.CacheDirectory / TEXT("Files");
}
bool WebPlatformTools::OnPostProcess(CookingData& data)
{
const auto gameSettings = GameSettings::Get();
const auto platformSettings = WebPlatformSettings::Get();
const auto platformDataPath = data.GetPlatformBinariesRoot();
// Get name of the output binary (JavaScript and WebAssembly files match)
String gameJs;
{
Array<String> files;
FileSystem::DirectoryGetFiles(files, data.OriginalOutputPath, TEXT("*"), DirectorySearchOption::TopDirectoryOnly);
for (const String& file : files)
{
if (file.EndsWith(TEXT(".js")))
{
String outputWasm = String(StringUtils::GetPathWithoutExtension(file)) + TEXT(".wasm");
if (files.Contains(outputWasm))
{
gameJs = file;
break;
}
}
}
}
if (gameJs.IsEmpty())
{
data.Error(TEXT("Failed to find the main JavaScript for the output game"));
return true;
}
// Move .wasm assemblies into the data files in order for dlopen to work (blocking)
{
Array<String> files, files2;
FileSystem::DirectoryGetFiles(files, data.OriginalOutputPath, TEXT("*.wasm"), DirectorySearchOption::AllDirectories);
FileSystem::DirectoryGetFiles(files, data.OriginalOutputPath, TEXT("*.so"), DirectorySearchOption::AllDirectories);
StringView gameWasm = StringUtils::GetFileNameWithoutExtension(gameJs);
for (const String& file : files)
{
if (StringUtils::GetFileNameWithoutExtension(file) == gameWasm)
continue; // Skip the main game module
FileSystem::MoveFile(data.DataOutputPath / StringUtils::GetFileName(file), file, true);
}
for (const String& file : files2)
{
if (StringUtils::GetFileNameWithoutExtension(file) == gameWasm)
continue; // Skip the main game module
FileSystem::MoveFile(data.DataOutputPath / StringUtils::GetFileName(file), file, true);
}
}
// Pack data files into a single file using Emscripten's file_packager tool
{
CreateProcessSettings procSettings;
String emscriptenSdk = TEXT("EMSDK");
Platform::GetEnvironmentVariable(emscriptenSdk, emscriptenSdk);
procSettings.FileName = emscriptenSdk / TEXT("upstream/emscripten/tools/file_packager");
#if PLATFORM_WIN32
procSettings.FileName += TEXT(".bat");
#endif
procSettings.Arguments = String::Format(TEXT("files.data --preload \"{}@/\" --lz4 --js-output=files.js"), data.DataOutputPath);
procSettings.WorkingDirectory = data.OriginalOutputPath;
const int32 result = Platform::CreateProcess(procSettings);
if (result != 0)
{
if (!FileSystem::FileExists(procSettings.FileName))
data.Error(TEXT("Missing file_packager.bat. Ensure Emscripten SDK installation is valid and 'EMSDK' environment variable points to it."));
data.Error(String::Format(TEXT("Failed to package project files (result code: {0}). See log for more info."), result));
return true;
}
}
// Copy icon file
{
String dstIcon = data.OriginalOutputPath / TEXT("favicon.ico");
if (!FileSystem::FileExists(dstIcon))
FileSystem::CopyFile(dstIcon, platformDataPath / TEXT("favicon.ico"));
}
// TODO: customizable HTML templates
// Insert packaged file system with game data
{
String gameJsText;
if (File::ReadAllText(gameJs, gameJsText))
{
data.Error(String::Format(TEXT("Failed to load file '{}'"), gameJs));
return true;
}
const String filesIncludeBegin = TEXT("// include: files.js");
const String filesIncludeEnd = TEXT("// end include: files.js");
String fileJs = data.OriginalOutputPath / TEXT("files.js");
if (!gameJsText.Contains(filesIncludeBegin))
{
// Insert generated files.js into the main game file after the minimum_runtime_check.js include
String fileJsText;
if (File::ReadAllText(fileJs, fileJsText))
{
data.Error(String::Format(TEXT("Failed to load file '{}'"), fileJs));
return true;
}
const String insertPrefixLocation = TEXT("// end include: minimum_runtime_check.js");
int32 location = gameJsText.Find(insertPrefixLocation);
if (location != -1)
{
location += insertPrefixLocation.Length() + 1;
fileJsText = filesIncludeBegin + TEXT("\n") + fileJsText + TEXT("\n") + filesIncludeEnd + TEXT("\n");
gameJsText.Insert(location, fileJsText);
}
else
{
// Comments are missing in Release when JS/HTML are minified
fileJsText.Insert(0, filesIncludeBegin);
fileJsText.Insert(0, TEXT("\n"));
gameJsText.Insert(0, fileJsText);
}
File::WriteAllText(gameJs, gameJsText, Encoding::UTF8);
}
// Remove the generated files.js as it's now included in the main game JS file
FileSystem::DeleteFile(fileJs);
}
const auto buildSettings = BuildSettings::Get();
if (buildSettings->SkipPackaging)
return false;
GameCooker::PackageFiles();
// TODO: minify/compress output JS files (in Release builds)
LOG(Info, "Output website size: {0} MB", FileSystem::GetDirectorySize(data.OriginalOutputPath) / 1024 / 1024);
return false;
}
#endif

View File

@@ -1,29 +0,0 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#if PLATFORM_TOOLS_WEB
#include "../../PlatformTools.h"
/// <summary>
/// The Web platform support tools.
/// </summary>
class WebPlatformTools : public PlatformTools
{
public:
// [PlatformTools]
const Char* GetDisplayName() const override;
const Char* GetName() const override;
PlatformType GetPlatform() const override;
ArchitectureType GetArchitecture() const override;
DotNetAOTModes UseAOT() const override;
PixelFormat GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format) override;
void LoadCache(CookingData& data, IBuildCache* cache, const Span<byte>& bytes) override;
Array<byte> SaveCache(CookingData& data, IBuildCache* cache) override;
bool IsNativeCodeFile(CookingData& data, const String& file) override;
void OnBuildStarted(CookingData& data) override;
bool OnPostProcess(CookingData& data) override;
};
#endif

View File

@@ -572,14 +572,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE); COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
break; break;
} }
#endif
#if PLATFORM_TOOLS_WEB
case BuildPlatform::Web:
{
const char* platformDefineName = "PLATFORM_WEB";
COMPILE_PROFILE(WebGPU, SHADER_FILE_CHUNK_INTERNAL_GENERIC_CACHE);
break;
}
#endif #endif
default: default:
{ {
@@ -742,8 +734,37 @@ bool ProcessTextureBase(CookAssetsStep::AssetCookData& data)
{ {
auto chunk = New<FlaxChunk>(); auto chunk = New<FlaxChunk>();
data.InitData.Header.Chunks[mipIndex] = chunk; data.InitData.Header.Chunks[mipIndex] = chunk;
if (TextureTool::WriteTextureData(chunk->Data, *textureData, mipIndex))
return true; // Calculate the texture data storage layout
uint32 rowPitch, slicePitch;
const int32 mipWidth = Math::Max(1, textureData->Width >> mipIndex);
const int32 mipHeight = Math::Max(1, textureData->Height >> mipIndex);
RenderTools::ComputePitch(textureData->Format, mipWidth, mipHeight, rowPitch, slicePitch);
chunk->Data.Allocate(slicePitch * textureData->GetArraySize());
// Copy array slices into mip data (sequential)
for (int32 arrayIndex = 0; arrayIndex < textureData->Items.Count(); arrayIndex++)
{
auto& mipData = textureData->Items[arrayIndex].Mips[mipIndex];
byte* src = mipData.Data.Get();
byte* dst = chunk->Data.Get() + (slicePitch * arrayIndex);
// Faster path if source and destination data layout matches
if (rowPitch == mipData.RowPitch && slicePitch == mipData.DepthPitch)
{
Platform::MemoryCopy(dst, src, slicePitch);
}
else
{
const auto copyRowSize = Math::Min(mipData.RowPitch, rowPitch);
for (uint32 line = 0; line < mipData.Lines; line++)
{
Platform::MemoryCopy(dst, src, copyRowSize);
src += mipData.RowPitch;
dst += rowPitch;
}
}
}
} }
// Clone any custom asset chunks (eg. sprite atlas data, mips are in 0-13 chunks) // Clone any custom asset chunks (eg. sprite atlas data, mips are in 0-13 chunks)

View File

@@ -39,23 +39,17 @@ bool DeployDataStep::Perform(CookingData& data)
} }
String dstDotnet = data.DataOutputPath / TEXT("Dotnet"); String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
const DotNetAOTModes aotMode = data.Tools->UseAOT(); const DotNetAOTModes aotMode = data.Tools->UseAOT();
const bool usAOT = aotMode != DotNetAOTModes::None && aotMode != DotNetAOTModes::NoDotnet; const bool usAOT = aotMode != DotNetAOTModes::None;
if (usAOT) if (usAOT)
{ {
// Deploy Dotnet files into intermediate cooking directory for AOT // Deploy Dotnet files into intermediate cooking directory for AOT
FileSystem::DeleteDirectory(dstDotnet); FileSystem::DeleteDirectory(dstDotnet);
dstDotnet = data.ManagedCodeOutputPath; dstDotnet = data.ManagedCodeOutputPath;
} }
if (aotMode == DotNetAOTModes::NoDotnet) if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
{
// No .NET
FileSystem::DeleteDirectory(dstDotnet);
}
else if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
{ {
// Use system-installed .NET Runtime // Use system-installed .NET Runtime
FileSystem::DeleteDirectory(dstDotnet); FileSystem::DeleteDirectory(dstDotnet);
LOG(Info, "Not using .NET Runtime");
} }
else else
{ {

View File

@@ -12,9 +12,7 @@
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data) void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
{ {
const DotNetAOTModes aotMode = data.Tools->UseAOT(); const DotNetAOTModes aotMode = data.Tools->UseAOT();
if (aotMode == DotNetAOTModes::None || if (aotMode == DotNetAOTModes::None || EnumHasAllFlags(data.Options, BuildOptions::NoCook))
aotMode == DotNetAOTModes::NoDotnet ||
EnumHasAllFlags(data.Options, BuildOptions::NoCook))
return; return;
const auto& buildSettings = *BuildSettings::Get(); const auto& buildSettings = *BuildSettings::Get();
@@ -37,8 +35,8 @@ void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
if (cachedData != aotModeCacheValue) if (cachedData != aotModeCacheValue)
{ {
LOG(Info, "AOT cache invalidation"); LOG(Info, "AOT cache invalidation");
//FileSystem::DeleteDirectory(data.ManagedCodeOutputPath); // Remove AOT cache FileSystem::DeleteDirectory(data.ManagedCodeOutputPath); // Remove AOT cache
//FileSystem::DeleteDirectory(data.DataOutputPath / TEXT("Dotnet")); // Remove deployed Dotnet libs (be sure to remove any leftovers from previous build) FileSystem::DeleteDirectory(data.DataOutputPath / TEXT("Dotnet")); // Remove deployed Dotnet libs (be sure to remove any leftovers from previous build)
} }
} }
if (!FileSystem::DirectoryExists(data.ManagedCodeOutputPath)) if (!FileSystem::DirectoryExists(data.ManagedCodeOutputPath))
@@ -51,8 +49,7 @@ void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
bool PrecompileAssembliesStep::Perform(CookingData& data) bool PrecompileAssembliesStep::Perform(CookingData& data)
{ {
const DotNetAOTModes aotMode = data.Tools->UseAOT(); const DotNetAOTModes aotMode = data.Tools->UseAOT();
if (aotMode == DotNetAOTModes::None || if (aotMode == DotNetAOTModes::None)
aotMode == DotNetAOTModes::NoDotnet)
return false; return false;
const auto& buildSettings = *BuildSettings::Get(); const auto& buildSettings = *BuildSettings::Get();
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet()) if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())

View File

@@ -103,12 +103,11 @@ namespace FlaxEditor.CustomEditors.Dedicated
var actors = ScriptsEditor.ParentEditor.Values; var actors = ScriptsEditor.ParentEditor.Values;
foreach (var a in actors) foreach (var a in actors)
{ {
if (a.GetType() == requireActor.RequiredType) if (a.GetType() != requireActor.RequiredType)
continue; {
if (requireActor.IncludeInheritedTypes && a.GetType().IsSubclassOf(requireActor.RequiredType)) item.Enabled = false;
continue; break;
item.Enabled = false; }
break;
} }
} }
cm.AddItem(item); cm.AddItem(item);
@@ -740,8 +739,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
/// <inheritdoc /> /// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout) public override void Initialize(LayoutElementsContainer layout)
{ {
var style = FlaxEngine.GUI.Style.Current;
// Area for drag&drop scripts // Area for drag&drop scripts
var dragArea = layout.CustomContainer<DragAreaControl>(); var dragArea = layout.CustomContainer<DragAreaControl>();
dragArea.CustomControl.ScriptsEditor = this; dragArea.CustomControl.ScriptsEditor = this;
@@ -803,10 +800,17 @@ namespace FlaxEditor.CustomEditors.Dedicated
bool hasAllRequirements = true; bool hasAllRequirements = true;
if (scriptType.HasAttribute(typeof(RequireScriptAttribute), false)) if (scriptType.HasAttribute(typeof(RequireScriptAttribute), false))
{ {
var attribute = (RequireScriptAttribute)scriptType.GetAttributes(false).FirstOrDefault(x => x is RequireScriptAttribute); RequireScriptAttribute scriptAttribute = null;
if (attribute != null) foreach (var e in scriptType.GetAttributes(false))
{ {
foreach (var type in attribute.RequiredTypes) if (e is not RequireScriptAttribute requireScriptAttribute)
continue;
scriptAttribute = requireScriptAttribute;
}
if (scriptAttribute != null)
{
foreach (var type in scriptAttribute.RequiredTypes)
{ {
if (!type.IsSubclassOf(typeof(Script))) if (!type.IsSubclassOf(typeof(Script)))
continue; continue;
@@ -821,11 +825,19 @@ namespace FlaxEditor.CustomEditors.Dedicated
} }
if (scriptType.HasAttribute(typeof(RequireActorAttribute), false)) if (scriptType.HasAttribute(typeof(RequireActorAttribute), false))
{ {
var attribute = (RequireActorAttribute)scriptType.GetAttributes(false).FirstOrDefault(x => x is RequireActorAttribute); RequireActorAttribute attribute = null;
foreach (var e in scriptType.GetAttributes(false))
{
if (e is not RequireActorAttribute requireActorAttribute)
continue;
attribute = requireActorAttribute;
break;
}
if (attribute != null) if (attribute != null)
{ {
var actor = script.Actor; var actor = script.Actor;
if (actor.GetType() != attribute.RequiredType && (attribute.IncludeInheritedTypes && !actor.GetType().IsSubclassOf(attribute.RequiredType))) if (actor.GetType() != attribute.RequiredType && !actor.GetType().IsSubclassOf(attribute.RequiredType))
{ {
Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` on `{script.Actor}` is missing a required Actor of type `{attribute.RequiredType}`."); Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` on `{script.Actor}` is missing a required Actor of type `{attribute.RequiredType}`.");
hasAllRequirements = false; hasAllRequirements = false;
@@ -838,7 +850,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var title = Utilities.Utils.GetPropertyNameUI(scriptType.Name); var title = Utilities.Utils.GetPropertyNameUI(scriptType.Name);
var group = layout.Group(title, editor); var group = layout.Group(title, editor);
if (!hasAllRequirements) if (!hasAllRequirements)
group.Panel.HeaderTextColor = style.Statusbar.Failed; group.Panel.HeaderTextColor = FlaxEngine.GUI.Style.Current.Statusbar.Failed;
if ((Presenter.Features & FeatureFlags.CacheExpandedGroups) != 0) if ((Presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
{ {
if (Editor.Instance.ProjectCache.IsGroupToggled(title)) if (Editor.Instance.ProjectCache.IsGroupToggled(title))
@@ -851,10 +863,9 @@ namespace FlaxEditor.CustomEditors.Dedicated
group.Panel.Open(); group.Panel.Open();
// Customize // Customize
float totalHeaderButtonsOffset = 0f;
group.Panel.TooltipText = Editor.Instance.CodeDocs.GetTooltip(scriptType); group.Panel.TooltipText = Editor.Instance.CodeDocs.GetTooltip(scriptType);
if (script.HasPrefabLink) if (script.HasPrefabLink)
group.Panel.HeaderTextColor = style.ProgressNormal; group.Panel.HeaderTextColor = FlaxEngine.GUI.Style.Current.ProgressNormal;
// Add toggle button to the group // Add toggle button to the group
var headerHeight = group.Panel.HeaderHeight; var headerHeight = group.Panel.HeaderHeight;
@@ -878,7 +889,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
TooltipText = "Script reference.", TooltipText = "Script reference.",
AutoFocus = true, AutoFocus = true,
IsScrollable = false, IsScrollable = false,
Color = style.ForegroundGrey, Color = FlaxEngine.GUI.Style.Current.ForegroundGrey,
Parent = group.Panel, Parent = group.Panel,
Bounds = new Rectangle(scriptToggle.Right, 0.5f, headerHeight, headerHeight), Bounds = new Rectangle(scriptToggle.Right, 0.5f, headerHeight, headerHeight),
Margin = new Margin(1), Margin = new Margin(1),
@@ -897,35 +908,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
var settingsButton = group.AddSettingsButton(); var settingsButton = group.AddSettingsButton();
settingsButton.Tag = script; settingsButton.Tag = script;
settingsButton.Clicked += OnSettingsButtonClicked; settingsButton.Clicked += OnSettingsButtonClicked;
totalHeaderButtonsOffset += settingsButton.Width + FlaxEditor.Utilities.Constants.UIMargin;
// Add script obsolete icon to the group
if (scriptType.HasAttribute(typeof(ObsoleteAttribute), false))
{
var attribute = (ObsoleteAttribute)scriptType.GetAttributes(false).First(x => x is ObsoleteAttribute);
var tooltip = "Script marked as obsolete." +
(string.IsNullOrEmpty(attribute.Message) ? "" : $"\n{attribute.Message}") +
(string.IsNullOrEmpty(attribute.DiagnosticId) ? "" : $"\n{attribute.DiagnosticId}");
var obsoleteButton = group.AddHeaderButton(tooltip, totalHeaderButtonsOffset, Editor.Instance.Icons.Info32);
obsoleteButton.Color = Color.Orange;
obsoleteButton.MouseOverColor = Color.DarkOrange;
totalHeaderButtonsOffset += obsoleteButton.Width;
}
// Show visual indicator if script only exists in prefab instance and is not part of the prefab
bool isPrefabActor = scripts.Any(s => s.Actor.HasPrefabLink);
if (isPrefabActor && script.PrefabID == Guid.Empty)
{
var prefabInstanceButton = group.AddHeaderButton("Script only exists in this prefab instance.", totalHeaderButtonsOffset, Editor.Instance.Icons.Add32);
prefabInstanceButton.Color = style.ProgressNormal;
prefabInstanceButton.MouseOverColor = style.ProgressNormal * 0.9f;
totalHeaderButtonsOffset += prefabInstanceButton.Width;
}
// Adjust margin to not overlap with other ui elements in the header // Adjust margin to not overlap with other ui elements in the header
group.Panel.HeaderTextMargin = group.Panel.HeaderTextMargin with { Left = scriptDrag.Right - 12, Right = settingsButton.Width + Utilities.Constants.UIMargin }; group.Panel.HeaderTextMargin = group.Panel.HeaderTextMargin with { Left = scriptDrag.Right - 12, Right = settingsButton.Width + Utilities.Constants.UIMargin };
group.Object(values, editor); group.Object(values, editor);
// Remove drop down arrows and containment lines if no objects in the group // Remove drop down arrows and containment lines if no objects in the group
if (group.Children.Count == 0) if (group.Children.Count == 0)
{ {

View File

@@ -18,7 +18,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
public class SplineEditor : ActorEditor public class SplineEditor : ActorEditor
{ {
/// <summary> /// <summary>
/// Stores undo spline data. /// Storage undo spline data
/// </summary> /// </summary>
private struct UndoData private struct UndoData
{ {
@@ -83,7 +83,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
} }
/// <summary> /// <summary>
/// Edit curve options manipulate the curve as free mode. /// Edit curve options manipulate the curve as free mode
/// </summary> /// </summary>
private sealed class FreeTangentMode : EditTangentOptionBase private sealed class FreeTangentMode : EditTangentOptionBase
{ {
@@ -98,7 +98,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
} }
/// <summary> /// <summary>
/// Edit curve options to set tangents to linear. /// Edit curve options to set tangents to linear
/// </summary> /// </summary>
private sealed class LinearTangentMode : EditTangentOptionBase private sealed class LinearTangentMode : EditTangentOptionBase
{ {
@@ -107,13 +107,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
{ {
SetKeyframeLinear(spline, index); SetKeyframeLinear(spline, index);
// Change the selection to tangent parent (a spline point / keyframe) // change the selection to tangent parent (a spline point / keyframe)
Editor.SetSelectSplinePointNode(spline, index); Editor.SetSelectSplinePointNode(spline, index);
} }
} }
/// <summary> /// <summary>
/// Edit curve options to align tangents of selected spline. /// Edit curve options to align tangents of selected spline
/// </summary> /// </summary>
private sealed class AlignedTangentMode : EditTangentOptionBase private sealed class AlignedTangentMode : EditTangentOptionBase
{ {
@@ -168,7 +168,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
} }
/// <summary> /// <summary>
/// Edit curve options manipulate the curve setting selected point tangent in as smoothed but tangent out as linear. /// Edit curve options manipulate the curve setting selected point
/// tangent in as smoothed but tangent out as linear
/// </summary> /// </summary>
private sealed class SmoothInTangentMode : EditTangentOptionBase private sealed class SmoothInTangentMode : EditTangentOptionBase
{ {
@@ -181,7 +182,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
} }
/// <summary> /// <summary>
/// Edit curve options manipulate the curve setting selected point tangent in as linear but tangent out as smoothed. /// Edit curve options manipulate the curve setting selected point
/// tangent in as linear but tangent out as smoothed
/// </summary> /// </summary>
private sealed class SmoothOutTangentMode : EditTangentOptionBase private sealed class SmoothOutTangentMode : EditTangentOptionBase
{ {
@@ -217,8 +219,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var enabled = EnabledInHierarchy && tab.EnabledInHierarchy; var enabled = EnabledInHierarchy && tab.EnabledInHierarchy;
var style = FlaxEngine.GUI.Style.Current; var style = FlaxEngine.GUI.Style.Current;
var size = Size; var size = Size;
var textHeight = 30.0f; var textHeight = 16.0f;
// Make icons smaller when tabs get thinner
var iconSize = size.Y - textHeight; var iconSize = size.Y - textHeight;
var iconRect = new Rectangle((Width - iconSize) / 2, 0, iconSize, iconSize); var iconRect = new Rectangle((Width - iconSize) / 2, 0, iconSize, iconSize);
if (tab._mirrorIcon) if (tab._mirrorIcon)
@@ -229,11 +230,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
var color = style.Foreground; var color = style.Foreground;
if (!enabled) if (!enabled)
color *= 0.6f; color *= 0.6f;
var textRect = new Rectangle(0, size.Y - textHeight, size.X, textHeight);
Render2D.PushClip(new Rectangle(Float2.Zero, Size));
Render2D.DrawSprite(tab._customIcon, iconRect, color); Render2D.DrawSprite(tab._customIcon, iconRect, color);
Render2D.DrawText(style.FontMedium, tab._customText, textRect, color, TextAlignment.Center, TextAlignment.Center, TextWrapping.WrapWords, 0.65f); Render2D.DrawText(style.FontMedium, tab._customText, new Rectangle(0, iconSize, size.X, textHeight), color, TextAlignment.Center, TextAlignment.Center);
Render2D.PopClip();
} }
} }
@@ -293,21 +291,18 @@ namespace FlaxEditor.CustomEditors.Dedicated
return; return;
_selectedSpline = spline; _selectedSpline = spline;
//var tabSize = 46; layout.Space(10);
var tabSize = 60; var tabSize = 46;
var icons = Editor.Instance.Icons; var icons = Editor.Instance.Icons;
var group = layout.Group("Selected Point"); layout.Header("Selected spline point");
_selectedPointsTabs = new Tabs _selectedPointsTabs = new Tabs
{ {
Height = tabSize, Height = tabSize,
TabsSize = new Float2(tabSize), TabsSize = new Float2(tabSize),
AutoTabsSize = true, AutoTabsSize = true,
Parent = group.ContainerControl, Parent = layout.ContainerControl,
}; };
// Move the group above the group containing spline points
group.Control.IndexInParent = 3;
_linearTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedLinear, "Linear", icons.SplineLinear64)); _linearTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedLinear, "Linear", icons.SplineLinear64));
_freeTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedFree, "Free", icons.SplineFree64)); _freeTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedFree, "Free", icons.SplineFree64));
_alignedTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedAligned, "Aligned", icons.SplineAligned64)); _alignedTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedAligned, "Aligned", icons.SplineAligned64));
@@ -315,13 +310,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
_smoothOutTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedSmoothOut, "Smooth Out", icons.SplineSmoothIn64, true)); _smoothOutTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedSmoothOut, "Smooth Out", icons.SplineSmoothIn64, true));
_selectedPointsTabs.SelectedTabIndex = -1; _selectedPointsTabs.SelectedTabIndex = -1;
group = layout.Group("All Points"); layout.Header("All spline points");
_allPointsTabs = new Tabs _allPointsTabs = new Tabs
{ {
Height = tabSize, Height = tabSize,
TabsSize = new Float2(tabSize), TabsSize = new Float2(tabSize),
AutoTabsSize = true, AutoTabsSize = true,
Parent = group.ContainerControl, Parent = layout.ContainerControl,
}; };
_setLinearAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsLinear, "Set Linear Tangents", icons.SplineLinear64)); _setLinearAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsLinear, "Set Linear Tangents", icons.SplineLinear64));
_setSmoothAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsSmooth, "Set Smooth Tangents", icons.SplineAligned64)); _setSmoothAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsSmooth, "Set Smooth Tangents", icons.SplineAligned64));

View File

@@ -690,7 +690,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
return grid; return grid;
} }
private CustomElementsContainer<UniformGridPanel> UniformPanelCapsuleForObjectWithText(LayoutElementsContainer el, string text, ValueContainer values, Color highlightColor, out FloatValueBox valueBox) private CustomElementsContainer<UniformGridPanel> UniformPanelCapsuleForObjectWithText(LayoutElementsContainer el, string text, ValueContainer values, Color borderColor, out FloatValueBox valueBox)
{ {
valueBox = null; valueBox = null;
var grid = UniformGridTwoByOne(el); var grid = UniformGridTwoByOne(el);
@@ -701,8 +701,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
{ {
valueBox = floatEditorElement.ValueBox; valueBox = floatEditorElement.ValueBox;
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground; var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
valueBox.HighlightColor = highlightColor; valueBox.BorderColor = Color.Lerp(borderColor, back, ActorTransformEditor.AxisGreyOutFactor);
valueBox.BorderSelectedColor = highlightColor; valueBox.BorderSelectedColor = borderColor;
} }
return grid; return grid;
} }

View File

@@ -14,17 +14,22 @@ namespace FlaxEditor.CustomEditors.Editors
/// <summary> /// <summary>
/// The X axis color. /// The X axis color.
/// </summary> /// </summary>
public static Color AxisColorX = new Color(0.8f, 0.0f, 0.027f, 1.0f); public static Color AxisColorX = new Color(1.0f, 0.0f, 0.02745f, 1.0f);
/// <summary> /// <summary>
/// The Y axis color. /// The Y axis color.
/// </summary> /// </summary>
public static Color AxisColorY = new Color(0.239215f, 0.65f, 0.047058f, 1.0f); public static Color AxisColorY = new Color(0.239215f, 1.0f, 0.047058f, 1.0f);
/// <summary> /// <summary>
/// The Z axis color. /// The Z axis color.
/// </summary> /// </summary>
public static Color AxisColorZ = new Color(0.0f, 0.42352f, 0.8f, 1.0f); public static Color AxisColorZ = new Color(0.0f, 0.0235294f, 1.0f, 1.0f);
/// <summary>
/// The axes colors grey out scale when input field is not focused.
/// </summary>
public static float AxisGreyOutFactor = 0.6f;
/// <summary> /// <summary>
/// Custom editor for actor position property. /// Custom editor for actor position property.
@@ -38,20 +43,18 @@ namespace FlaxEditor.CustomEditors.Editors
base.Initialize(layout); base.Initialize(layout);
if (XElement.ValueBox.Parent is UniformGridPanel ug) if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.SlotPadding = new Margin(3.0f, 0.0f, 0.0f, 0.0f);
CheckLayout(ug); CheckLayout(ug);
}
// Override colors // Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor);
XElement.ValueBox.BorderSelectedColor = AxisColorX; XElement.ValueBox.BorderSelectedColor = AxisColorX;
YElement.ValueBox.BorderSelectedColor = AxisColorY;
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
XElement.ValueBox.HighlightColor = AxisColorX;
XElement.ValueBox.Category = Utils.ValueCategory.Distance; XElement.ValueBox.Category = Utils.ValueCategory.Distance;
YElement.ValueBox.HighlightColor = AxisColorY; YElement.ValueBox.BorderColor = Color.Lerp(AxisColorY, back, AxisGreyOutFactor);
YElement.ValueBox.BorderSelectedColor = AxisColorY;
YElement.ValueBox.Category = Utils.ValueCategory.Distance; YElement.ValueBox.Category = Utils.ValueCategory.Distance;
ZElement.ValueBox.HighlightColor = AxisColorZ; ZElement.ValueBox.BorderColor = Color.Lerp(AxisColorZ, back, AxisGreyOutFactor);
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
ZElement.ValueBox.Category = Utils.ValueCategory.Distance; ZElement.ValueBox.Category = Utils.ValueCategory.Distance;
} }
} }
@@ -68,20 +71,18 @@ namespace FlaxEditor.CustomEditors.Editors
base.Initialize(layout); base.Initialize(layout);
if (XElement.ValueBox.Parent is UniformGridPanel ug) if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.SlotPadding = new Margin(3.0f, 0.0f, 0.0f, 0.0f);
CheckLayout(ug); CheckLayout(ug);
}
// Override colors // Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor);
XElement.ValueBox.BorderSelectedColor = AxisColorX; XElement.ValueBox.BorderSelectedColor = AxisColorX;
YElement.ValueBox.BorderSelectedColor = AxisColorY;
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
XElement.ValueBox.HighlightColor = AxisColorX;
XElement.ValueBox.Category = Utils.ValueCategory.Angle; XElement.ValueBox.Category = Utils.ValueCategory.Angle;
YElement.ValueBox.HighlightColor = AxisColorY; YElement.ValueBox.BorderColor = Color.Lerp(AxisColorY, back, AxisGreyOutFactor);
YElement.ValueBox.BorderSelectedColor = AxisColorY;
YElement.ValueBox.Category = Utils.ValueCategory.Angle; YElement.ValueBox.Category = Utils.ValueCategory.Angle;
ZElement.ValueBox.HighlightColor = AxisColorZ; ZElement.ValueBox.BorderColor = Color.Lerp(AxisColorZ, back, AxisGreyOutFactor);
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
ZElement.ValueBox.Category = Utils.ValueCategory.Angle; ZElement.ValueBox.Category = Utils.ValueCategory.Angle;
} }
} }
@@ -128,19 +129,17 @@ namespace FlaxEditor.CustomEditors.Editors
} }
if (XElement.ValueBox.Parent is UniformGridPanel ug) if (XElement.ValueBox.Parent is UniformGridPanel ug)
{
ug.SlotPadding = new Margin(3.0f, 0.0f, 0.0f, 0.0f);
CheckLayout(ug); CheckLayout(ug);
}
// Override colors // Override colors
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground; var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
var grayOutFactor = 0.6f;
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, grayOutFactor);
XElement.ValueBox.BorderSelectedColor = AxisColorX; XElement.ValueBox.BorderSelectedColor = AxisColorX;
YElement.ValueBox.BorderColor = Color.Lerp(AxisColorY, back, grayOutFactor);
YElement.ValueBox.BorderSelectedColor = AxisColorY; YElement.ValueBox.BorderSelectedColor = AxisColorY;
ZElement.ValueBox.BorderColor = Color.Lerp(AxisColorZ, back, grayOutFactor);
ZElement.ValueBox.BorderSelectedColor = AxisColorZ; ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
XElement.ValueBox.HighlightColor = AxisColorX;
YElement.ValueBox.HighlightColor = AxisColorY;
ZElement.ValueBox.HighlightColor = AxisColorZ;
} }
/// <summary> /// <summary>

View File

@@ -37,35 +37,25 @@ namespace FlaxEditor.CustomEditors.Elements
public override ContainerControl ContainerControl => Panel; public override ContainerControl ContainerControl => Panel;
/// <summary> /// <summary>
/// Add utility settings button to the group header. /// Adds utility settings button to the group header.
/// </summary> /// </summary>
/// <returns>The created control.</returns> /// <returns>The created control.</returns>
public Image AddSettingsButton() public Image AddSettingsButton()
{
return AddHeaderButton("Settings", 0, Style.Current.Settings);
}
/// <summary>
/// Adds a button to the group header.
/// </summary>
/// <returns>The created control.</returns>
public Image AddHeaderButton(string tooltipText, float xOffset, SpriteHandle sprite)
{ {
var style = Style.Current; var style = Style.Current;
const float padding = 2.0f;
var settingsButtonSize = Panel.HeaderHeight; var settingsButtonSize = Panel.HeaderHeight;
Panel.HeaderTextMargin = Panel.HeaderTextMargin with { Right = settingsButtonSize + Utilities.Constants.UIMargin }; Panel.HeaderTextMargin = Panel.HeaderTextMargin with { Right = settingsButtonSize + Utilities.Constants.UIMargin };
; return new Image ; return new Image
{ {
TooltipText = tooltipText, TooltipText = "Settings",
AutoFocus = true, AutoFocus = true,
AnchorPreset = AnchorPresets.TopRight, AnchorPreset = AnchorPresets.TopRight,
Parent = Panel, Parent = Panel,
Bounds = new Rectangle(Panel.Width - settingsButtonSize - xOffset, padding * 0.5f, settingsButtonSize - padding, settingsButtonSize - padding), Bounds = new Rectangle(Panel.Width - settingsButtonSize, 0, settingsButtonSize, settingsButtonSize),
IsScrollable = false, IsScrollable = false,
Color = style.ForegroundGrey, Color = style.ForegroundGrey,
Margin = new Margin(1), Margin = new Margin(1),
Brush = new SpriteBrush(sprite), Brush = new SpriteBrush(style.Settings),
}; };
} }
} }

View File

@@ -70,9 +70,9 @@ namespace FlaxEditor.CustomEditors.GUI
UpdateSplitRect(); UpdateSplitRect();
} }
private void AutoSizeSplitter(bool ignoreCustomSplitterValue = false) private void AutoSizeSplitter()
{ {
if (_hasCustomSplitterValue && !ignoreCustomSplitterValue) if (_hasCustomSplitterValue || !Editor.Instance.Options.Options.Interface.AutoSizePropertiesPanelSplitter)
return; return;
Font font = Style.Current.FontMedium; Font font = Style.Current.FontMedium;
@@ -178,21 +178,6 @@ namespace FlaxEditor.CustomEditors.GUI
return base.OnMouseDown(location, button); return base.OnMouseDown(location, button);
} }
/// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{
if (button == MouseButton.Left && _splitterRect.Contains(location))
{
if (_splitterClicked)
EndTracking();
AutoSizeSplitter(true);
return true;
}
return base.OnMouseDoubleClick(location, button);
}
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button) public override bool OnMouseUp(Float2 location, MouseButton button)
{ {
@@ -235,8 +220,7 @@ namespace FlaxEditor.CustomEditors.GUI
// Refresh // Refresh
UpdateSplitRect(); UpdateSplitRect();
PerformLayout(true); PerformLayout(true);
if (Editor.Instance.Options.Options.Interface.AutoSizePropertiesPanelSplitter) AutoSizeSplitter();
AutoSizeSplitter();
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -87,7 +87,6 @@ public class Editor : EditorModule
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Android", "PLATFORM_TOOLS_ANDROID"); AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Android", "PLATFORM_TOOLS_ANDROID");
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "iOS", "PLATFORM_TOOLS_IOS"); AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "iOS", "PLATFORM_TOOLS_IOS");
} }
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Web", "PLATFORM_TOOLS_WEB");
// Visual Studio integration // Visual Studio integration
if (options.Platform.Target == TargetPlatform.Windows && Flax.Build.Platform.BuildTargetPlatform == TargetPlatform.Windows) if (options.Platform.Target == TargetPlatform.Windows && Flax.Build.Platform.BuildTargetPlatform == TargetPlatform.Windows)

View File

@@ -526,23 +526,6 @@ int32 Editor::LoadProduct()
return 12; return 12;
} }
// Get the last opened project path
String localCachePath;
FileSystem::GetSpecialFolderPath(SpecialFolder::AppData, localCachePath);
String editorConfigPath = localCachePath / TEXT("Flax");
String lastProjectSettingPath = editorConfigPath / TEXT("LastProject.txt");
if (!FileSystem::DirectoryExists(editorConfigPath))
FileSystem::CreateDirectory(editorConfigPath);
String lastProjectPath;
if (FileSystem::FileExists(lastProjectSettingPath))
File::ReadAllText(lastProjectSettingPath, lastProjectPath);
if (!FileSystem::DirectoryExists(lastProjectPath))
lastProjectPath = String::Empty;
// Try to open the last project when requested
if (projectPath.IsEmpty() && CommandLine::Options.LastProject.IsTrue() && !lastProjectPath.IsEmpty())
projectPath = lastProjectPath;
// Missing project case // Missing project case
if (projectPath.IsEmpty()) if (projectPath.IsEmpty())
{ {
@@ -558,7 +541,7 @@ int32 Editor::LoadProduct()
Array<String> files; Array<String> files;
if (FileSystem::ShowOpenFileDialog( if (FileSystem::ShowOpenFileDialog(
nullptr, nullptr,
lastProjectPath, StringView::Empty,
TEXT("Project files (*.flaxproj)\0*.flaxproj\0All files (*.*)\0*.*\0"), TEXT("Project files (*.flaxproj)\0*.flaxproj\0All files (*.*)\0*.*\0"),
false, false,
TEXT("Select project to open in Editor"), TEXT("Select project to open in Editor"),
@@ -642,10 +625,6 @@ int32 Editor::LoadProduct()
} }
} }
// Update the last opened project path
if (lastProjectPath.Compare(Project->ProjectFolderPath) != 0)
File::WriteAllText(lastProjectSettingPath, Project->ProjectFolderPath, Encoding::UTF8);
return 0; return 0;
} }

View File

@@ -407,6 +407,7 @@ namespace FlaxEditor
// Close splash and show main window // Close splash and show main window
CloseSplashScreen(); CloseSplashScreen();
Assert.IsNotNull(Windows.MainWindow);
if (!IsHeadlessMode) if (!IsHeadlessMode)
{ {
Windows.MainWindow.Show(); Windows.MainWindow.Show();

View File

@@ -151,8 +151,6 @@ namespace FlaxEditor
public SpriteHandle LocalizationSettings128; public SpriteHandle LocalizationSettings128;
public SpriteHandle Json128; public SpriteHandle Json128;
public SpriteHandle AppleSettings128; public SpriteHandle AppleSettings128;
public SpriteHandle Web128;
public SpriteHandle WebSettings128;
internal void LoadIcons() internal void LoadIcons()
{ {

View File

@@ -89,11 +89,6 @@ namespace FlaxEditor.GUI.Input
/// </summary> /// </summary>
public bool IsSliding => _isSliding; public bool IsSliding => _isSliding;
/// <summary>
/// The color of the highlight to the left of the value box.
/// </summary>
public Color HighlightColor;
/// <summary> /// <summary>
/// Occurs when sliding starts. /// Occurs when sliding starts.
/// </summary> /// </summary>
@@ -216,12 +211,6 @@ namespace FlaxEditor.GUI.Input
Render2D.DrawRectangle(bounds, style.SelectionBorder); Render2D.DrawRectangle(bounds, style.SelectionBorder);
} }
} }
if (HighlightColor != Color.Transparent)
{
var highlightRect = new Rectangle(-3.0f, 0.0f, 3.0f, Height);
Render2D.FillRectangle(highlightRect, HighlightColor);
}
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -303,10 +292,10 @@ namespace FlaxEditor.GUI.Input
return base.OnMouseDown(location, button); return base.OnMouseDown(location, button);
} }
#if !PLATFORM_SDL
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
#if !PLATFORM_SDL
if (_isSliding && !RootWindow.Window.IsMouseFlippingHorizontally) if (_isSliding && !RootWindow.Window.IsMouseFlippingHorizontally)
{ {
// Update sliding // Update sliding
@@ -314,7 +303,6 @@ namespace FlaxEditor.GUI.Input
ApplySliding(Mathf.RoundToInt(slideLocation.X - _startSlideLocation.X) * _slideSpeed); ApplySliding(Mathf.RoundToInt(slideLocation.X - _startSlideLocation.X) * _slideSpeed);
return; return;
} }
#endif
// Update cursor type so user knows they can slide value // Update cursor type so user knows they can slide value
if (CanUseSliding && SlideRect.Contains(location) && !_isSliding) if (CanUseSliding && SlideRect.Contains(location) && !_isSliding)
@@ -331,7 +319,8 @@ namespace FlaxEditor.GUI.Input
base.OnMouseMove(location); base.OnMouseMove(location);
} }
#if PLATFORM_SDL #else
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMoveRelative(Float2 motion) public override void OnMouseMoveRelative(Float2 motion)
{ {
@@ -357,6 +346,7 @@ namespace FlaxEditor.GUI.Input
base.OnMouseMoveRelative(motion); base.OnMouseMoveRelative(motion);
} }
#endif #endif
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -93,7 +93,6 @@ namespace FlaxEditor.GUI
new PlatformData(PlatformType.PS5, icons.PS5Icon128, "PlayStation 5"), new PlatformData(PlatformType.PS5, icons.PS5Icon128, "PlayStation 5"),
new PlatformData(PlatformType.Mac, icons.MacOSIcon128, "macOS"), new PlatformData(PlatformType.Mac, icons.MacOSIcon128, "macOS"),
new PlatformData(PlatformType.iOS, icons.IOSIcon128, "iOS"), new PlatformData(PlatformType.iOS, icons.IOSIcon128, "iOS"),
new PlatformData(PlatformType.Web, icons.Web128, "Web"),
}; };
const float IconSize = 64.0f; const float IconSize = 64.0f;
@@ -121,7 +120,7 @@ namespace FlaxEditor.GUI
} }
// Select the first platform // Select the first platform
_selected = PlatformType.Web; _selected = platforms[0].PlatformType;
((Image)Children[0]).Color = _selectedColor; ((Image)Children[0]).Color = _selectedColor;
((Image)Children[0]).MouseOverColor = _selectedColor; ((Image)Children[0]).MouseOverColor = _selectedColor;
} }

View File

@@ -201,9 +201,10 @@ namespace FlaxEditor.GUI.Timeline
var idx = stream.ReadInt32(); var idx = stream.ReadInt32();
var id = stream.ReadGuid(); var id = stream.ReadGuid();
object value = null; object value = null;
if (version <= 2) if (version == 2)
throw new Exception("Not supported asset version. Open and re-save asset with Flax 1.11."); stream.ReadCommonValue(ref value);
value = stream.ReadVariant(); else
value = stream.ReadVariant();
Emitters[idx].ParametersOverrides.Add(id, value); Emitters[idx].ParametersOverrides.Add(id, value);
} }

View File

@@ -180,11 +180,6 @@ namespace FlaxEditor
/// </summary> /// </summary>
public bool EnableCamera => _view != null && EnableBackground; public bool EnableCamera => _view != null && EnableBackground;
/// <summary>
/// True if enable grid drawing.
/// </summary>
public bool ShowGrid { get; set; } = true;
/// <summary> /// <summary>
/// Transform gizmo to use sync with (selection, snapping, transformation settings). /// Transform gizmo to use sync with (selection, snapping, transformation settings).
/// </summary> /// </summary>
@@ -392,53 +387,19 @@ namespace FlaxEditor
if (_mouseMovesWidget && _activeWidget.UIControl) if (_mouseMovesWidget && _activeWidget.UIControl)
{ {
// Calculate transform delta // Calculate transform delta
var resizeAxisAbs = _activeWidget.ResizeAxis.Absolute;
var resizeAxisPos = Float2.Clamp(_activeWidget.ResizeAxis, Float2.Zero, Float2.One);
var resizeAxisNeg = Float2.Clamp(-_activeWidget.ResizeAxis, Float2.Zero, Float2.One);
var delta = location - _mouseMovesPos; var delta = location - _mouseMovesPos;
// TODO: scale/size snapping? // TODO: scale/size snapping?
delta *= resizeAxisAbs;
// Resize control via widget // Resize control via widget
var moveLocation = _mouseMovesPos + delta; var moveLocation = _mouseMovesPos + delta;
var control = _activeWidget.UIControl.Control; var control = _activeWidget.UIControl.Control;
var uiControlDelta = GetControlDelta(control, ref _mouseMovesPos, ref moveLocation); var uiControlDelta = GetControlDelta(control, ref _mouseMovesPos, ref moveLocation);
control.LocalLocation += uiControlDelta * resizeAxisNeg;
// Transform delta to control local space control.Size += uiControlDelta * resizeAxisPos - uiControlDelta * resizeAxisNeg;
var rotation = GetTotalRotation(control) * Mathf.DegreesToRadians;
var cos = Mathf.Cos(rotation);
var sin = Mathf.Sin(rotation);
var localDeltaX = uiControlDelta.X * cos + uiControlDelta.Y * sin;
var localDeltaY = uiControlDelta.Y * cos - uiControlDelta.X * sin;
var localDelta = new Float2(localDeltaX, localDeltaY);
localDelta *= _activeWidget.ResizeAxis.Absolute;
// Calculate size change
var resizeAxisPos = Float2.Clamp(_activeWidget.ResizeAxis, Float2.Zero, Float2.One);
var resizeAxisNeg = Float2.Clamp(-_activeWidget.ResizeAxis, Float2.Zero, Float2.One);
var dSizeScaled = localDelta * resizeAxisPos - localDelta * resizeAxisNeg;
var scale = control.Scale;
var dSize = new Float2(
Mathf.Abs(scale.X) > Mathf.Epsilon ? dSizeScaled.X / scale.X : 0,
Mathf.Abs(scale.Y) > Mathf.Epsilon ? dSizeScaled.Y / scale.Y : 0);
// Apply size change
control.Size += dSize;
// Calculate location offset to keep the opposite edge stationary
// When PivotRelative is false, resizing keeps Top-Left (Location) constant,
// so we only need to slide back if we are resizing Left or Top edges.
if (!control.PivotRelative)
{
var pivotOffset = Float2.Zero;
if (_activeWidget.ResizeAxis.X < 0 && Mathf.Abs(dSize.X) > Mathf.Epsilon)
pivotOffset.X = -dSize.X * scale.X;
if (_activeWidget.ResizeAxis.Y < 0 && Mathf.Abs(dSize.Y) > Mathf.Epsilon)
pivotOffset.Y = -dSize.Y * scale.Y;
// Transform offset back to parent space and apply
var dLocationX = pivotOffset.X * cos - pivotOffset.Y * sin;
var dLocationY = pivotOffset.X * sin + pivotOffset.Y * cos;
var dLocation = new Float2(dLocationX, dLocationY);
control.LocalLocation += dLocation;
}
// Don't move if layout doesn't allow it // Don't move if layout doesn't allow it
if (control.Parent != null) if (control.Parent != null)
@@ -531,20 +492,17 @@ namespace FlaxEditor
// Draw background // Draw background
Surface.VisjectSurface.DrawBackgroundDefault(Editor.Instance.UI.VisjectSurfaceBackground, Width, Height); Surface.VisjectSurface.DrawBackgroundDefault(Editor.Instance.UI.VisjectSurfaceBackground, Width, Height);
if (ShowGrid) // Draw grid
{ var viewRect = GetClientArea();
// Draw grid var upperLeft = _view.PointFromParent(viewRect.Location);
var viewRect = GetClientArea(); var bottomRight = _view.PointFromParent(viewRect.Size);
var upperLeft = _view.PointFromParent(viewRect.Location); var min = Float2.Min(upperLeft, bottomRight);
var bottomRight = _view.PointFromParent(viewRect.Size); var max = Float2.Max(upperLeft, bottomRight);
var min = Float2.Min(upperLeft, bottomRight); var pixelRange = (max - min) * ViewScale;
var max = Float2.Max(upperLeft, bottomRight); Render2D.PushClip(ref viewRect);
var pixelRange = (max - min) * ViewScale; DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X);
Render2D.PushClip(ref viewRect); DrawAxis(Float2.UnitY, viewRect, min.Y, max.Y, pixelRange.Y);
DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X); Render2D.PopClip();
DrawAxis(Float2.UnitY, viewRect, min.Y, max.Y, pixelRange.Y);
Render2D.PopClip();
}
} }
base.Draw(); base.Draw();
@@ -676,7 +634,7 @@ namespace FlaxEditor
// Draw sizing widgets // Draw sizing widgets
if (_widgets == null) if (_widgets == null)
_widgets = new List<Widget>(); _widgets = new List<Widget>();
var widgetSize = 8.0f; var widgetSize = 10.0f;
var viewScale = ViewScale; var viewScale = ViewScale;
if (viewScale < 0.7f) if (viewScale < 0.7f)
widgetSize *= viewScale; widgetSize *= viewScale;
@@ -727,7 +685,7 @@ namespace FlaxEditor
anchorRectSize *= viewScale; anchorRectSize *= viewScale;
// Make anchor rects and rotate if parent is rotated. // Make anchor rects and rotate if parent is rotated.
var parentRotation = GetTotalRotation(controlParent) * Mathf.DegreesToRadians; var parentRotation = controlParent.Rotation * Mathf.DegreesToRadians;
var rect1Axis = new Float2(-1, -1); var rect1Axis = new Float2(-1, -1);
var rect1 = new Rectangle(anchorUpperLeft + var rect1 = new Rectangle(anchorUpperLeft +
@@ -759,24 +717,16 @@ namespace FlaxEditor
} }
} }
private float GetTotalRotation(Control control)
{
if (control.Parent != null)
return control.Rotation + GetTotalRotation(control.Parent);
return control.Rotation;
}
private void DrawControlWidget(UIControl uiControl, ref Float2 pos, ref Float2 mousePos, ref Float2 size, float scale, Float2 resizeAxis, CursorType cursor) private void DrawControlWidget(UIControl uiControl, ref Float2 pos, ref Float2 mousePos, ref Float2 size, float scale, Float2 resizeAxis, CursorType cursor)
{ {
var style = Style.Current; var style = Style.Current;
var control = uiControl.Control; var control = uiControl.Control;
var rotation = GetTotalRotation(control); var rotation = control.Rotation;
var rotationInRadians = rotation * Mathf.DegreesToRadians; var rotationInRadians = rotation * Mathf.DegreesToRadians;
var position = (pos + new Float2(resizeAxis.X * Mathf.Cos(rotationInRadians) - resizeAxis.Y * Mathf.Sin(rotationInRadians), var rect = new Rectangle((pos +
resizeAxis.Y * Mathf.Cos(rotationInRadians) + resizeAxis.X * Mathf.Sin(rotationInRadians)) * 4 * (scale < 0.7f ? scale : 1)); new Float2(resizeAxis.X * Mathf.Cos(rotationInRadians) - resizeAxis.Y * Mathf.Sin(rotationInRadians),
var halfSize = size * 0.5f; resizeAxis.Y * Mathf.Cos(rotationInRadians) + resizeAxis.X * Mathf.Sin(rotationInRadians)) * 10 * scale) - size * 0.5f,
// Keep at 0, 0 rect position until later to correctly render rotation. size);
var rect = new Rectangle(0, 0, size);
// Find more correct cursor at different angles // Find more correct cursor at different angles
var unwindRotation = Mathf.UnwindDegrees(rotation); var unwindRotation = Mathf.UnwindDegrees(rotation);
@@ -799,10 +749,6 @@ namespace FlaxEditor
default: break; default: break;
} }
} }
Render2D.PushTransform(Matrix3x3.Translation2D(position));
Render2D.PushTransform(Matrix3x3.RotationZ(rotationInRadians));
Render2D.PushTransform(Matrix3x3.Translation2D(-1 * halfSize));
if (rect.Contains(ref mousePos)) if (rect.Contains(ref mousePos))
{ {
Render2D.FillRectangle(rect, style.Foreground); Render2D.FillRectangle(rect, style.Foreground);
@@ -813,14 +759,9 @@ namespace FlaxEditor
Render2D.FillRectangle(rect, style.ForegroundGrey); Render2D.FillRectangle(rect, style.ForegroundGrey);
Render2D.DrawRectangle(rect, style.Foreground); Render2D.DrawRectangle(rect, style.Foreground);
} }
Render2D.PopTransform();
Render2D.PopTransform();
Render2D.PopTransform();
if (!_mouseMovesWidget && uiControl != null) if (!_mouseMovesWidget && uiControl != null)
{ {
// Collect widget // Collect widget
rect.Location = position - halfSize;
_widgets.Add(new Widget _widgets.Add(new Widget
{ {
UIControl = uiControl, UIControl = uiControl,

View File

@@ -754,10 +754,6 @@ namespace FlaxEditor.Modules
// Delete asset by using content pool // Delete asset by using content pool
FlaxEngine.Content.DeleteAsset(path); FlaxEngine.Content.DeleteAsset(path);
} }
else if (item is ScriptItem)
{
FlaxEngine.Content.DeleteScript(path);
}
else if (deletedByUser) else if (deletedByUser)
{ {
// Delete file // Delete file
@@ -905,7 +901,7 @@ namespace FlaxEditor.Modules
{ {
// Item doesn't exist anymore // Item doesn't exist anymore
Editor.Log(string.Format($"Content item \'{child.Path}\' has been removed")); Editor.Log(string.Format($"Content item \'{child.Path}\' has been removed"));
Delete(child); Delete(child, false);
i--; i--;
} }
else if (canHaveAssets && child is AssetItem childAsset) else if (canHaveAssets && child is AssetItem childAsset)
@@ -1192,7 +1188,6 @@ namespace FlaxEditor.Modules
Proxy.Add(new SettingsProxy(typeof(AndroidPlatformSettings), Editor.Instance.Icons.AndroidSettings128)); Proxy.Add(new SettingsProxy(typeof(AndroidPlatformSettings), Editor.Instance.Icons.AndroidSettings128));
Proxy.Add(new SettingsProxy(typeof(MacPlatformSettings), Editor.Instance.Icons.AppleSettings128)); Proxy.Add(new SettingsProxy(typeof(MacPlatformSettings), Editor.Instance.Icons.AppleSettings128));
Proxy.Add(new SettingsProxy(typeof(iOSPlatformSettings), Editor.Instance.Icons.AppleSettings128)); Proxy.Add(new SettingsProxy(typeof(iOSPlatformSettings), Editor.Instance.Icons.AppleSettings128));
Proxy.Add(new SettingsProxy(typeof(WebPlatformSettings), Editor.Instance.Icons.WebSettings128));
var typePS4PlatformSettings = TypeUtils.GetManagedType(GameSettings.PS4PlatformSettingsTypename); var typePS4PlatformSettings = TypeUtils.GetManagedType(GameSettings.PS4PlatformSettingsTypename);
if (typePS4PlatformSettings != null) if (typePS4PlatformSettings != null)

View File

@@ -325,7 +325,7 @@ namespace FlaxEditor.Modules.SourceCodeEditing
var codeEditor = options.SourceCode.SourceCodeEditor; var codeEditor = options.SourceCode.SourceCodeEditor;
if (codeEditor != "None") if (codeEditor != "None")
{ {
foreach (var e in _editors) foreach (var e in Editor.Instance.CodeEditing.Editors)
{ {
if (string.Equals(codeEditor, e.Name, StringComparison.OrdinalIgnoreCase)) if (string.Equals(codeEditor, e.Name, StringComparison.OrdinalIgnoreCase))
{ {
@@ -334,10 +334,7 @@ namespace FlaxEditor.Modules.SourceCodeEditing
} }
} }
} }
if (editor == null && _editors.Count != 0) Editor.Instance.CodeEditing.SelectedEditor = editor;
editor = _editors[0];
SelectedEditor = editor;
} }
/// <summary> /// <summary>

View File

@@ -41,9 +41,9 @@ namespace FlaxEditor.Modules.SourceCodeEditing
var vsCode = codeEditing.GetInBuildEditor(CodeEditorTypes.VSCode); var vsCode = codeEditing.GetInBuildEditor(CodeEditorTypes.VSCode);
var rider = codeEditing.GetInBuildEditor(CodeEditorTypes.Rider); var rider = codeEditing.GetInBuildEditor(CodeEditorTypes.Rider);
#if PLATFORM_WINDOWS #if PLATFORM_WINDOW
// Favor the newest Visual Studio // Favor the newest Visual Studio
for (int i = (int)CodeEditorTypes.VS2026; i >= (int)CodeEditorTypes.VS2008; i--) for (int i = (int)CodeEditorTypes.VS2019; i >= (int)CodeEditorTypes.VS2008; i--)
{ {
var visualStudio = codeEditing.GetInBuildEditor((CodeEditorTypes)i); var visualStudio = codeEditing.GetInBuildEditor((CodeEditorTypes)i);
if (visualStudio != null) if (visualStudio != null)
@@ -74,7 +74,7 @@ namespace FlaxEditor.Modules.SourceCodeEditing
public string Name => "Default"; public string Name => "Default";
/// <inheritdoc /> /// <inheritdoc />
public string GenerateProjectCustomArgs => _currentEditor?.GenerateProjectCustomArgs; public string GenerateProjectCustomArgs => null;
/// <inheritdoc /> /// <inheritdoc />
public void OpenSolution() public void OpenSolution()

View File

@@ -22,14 +22,71 @@ namespace FlaxEditor.Modules.SourceCodeEditing
public InBuildSourceCodeEditor(CodeEditorTypes type) public InBuildSourceCodeEditor(CodeEditorTypes type)
{ {
Type = type; Type = type;
Name = CodeEditingManager.GetName(type); switch (type)
{
case CodeEditorTypes.Custom:
Name = "Custom";
break;
case CodeEditorTypes.SystemDefault:
Name = "System Default";
break;
case CodeEditorTypes.VS2008:
Name = "Visual Studio 2008";
break;
case CodeEditorTypes.VS2010:
Name = "Visual Studio 2010";
break;
case CodeEditorTypes.VS2012:
Name = "Visual Studio 2012";
break;
case CodeEditorTypes.VS2013:
Name = "Visual Studio 2013";
break;
case CodeEditorTypes.VS2015:
Name = "Visual Studio 2015";
break;
case CodeEditorTypes.VS2017:
Name = "Visual Studio 2017";
break;
case CodeEditorTypes.VS2019:
Name = "Visual Studio 2019";
break;
case CodeEditorTypes.VS2022:
Name = "Visual Studio 2022";
break;
case CodeEditorTypes.VS2026:
Name = "Visual Studio 2026";
break;
case CodeEditorTypes.VSCode:
Name = "Visual Studio Code";
break;
case CodeEditorTypes.VSCodeInsiders:
Name = "Visual Studio Code - Insiders";
break;
case CodeEditorTypes.Rider:
Name = "Rider";
break;
default: throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
} }
/// <inheritdoc /> /// <inheritdoc />
public string Name { get; set; } public string Name { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public string GenerateProjectCustomArgs => CodeEditingManager.GetGenerateProjectCustomArgs(Type); public string GenerateProjectCustomArgs
{
get
{
switch (Type)
{
case CodeEditorTypes.VSCodeInsiders:
case CodeEditorTypes.VSCode: return "-vscode -vs2022";
case CodeEditorTypes.Rider: return "-vs2022";
default: return null;
}
}
}
/// <inheritdoc /> /// <inheritdoc />
public void OpenSolution() public void OpenSolution()

View File

@@ -481,8 +481,6 @@ namespace FlaxEditor.Modules
/// <inheritdoc /> /// <inheritdoc />
public override void OnInit() public override void OnInit()
{ {
if (Editor.IsHeadlessMode)
return;
Editor.Windows.MainWindowClosing += OnMainWindowClosing; Editor.Windows.MainWindowClosing += OnMainWindowClosing;
var mainWindow = Editor.Windows.MainWindow.GUI; var mainWindow = Editor.Windows.MainWindow.GUI;

View File

@@ -758,39 +758,36 @@ namespace FlaxEditor.Modules
_windowsLayoutPath = StringUtils.CombinePaths(Globals.ProjectCacheFolder, "WindowsLayout.xml"); _windowsLayoutPath = StringUtils.CombinePaths(Globals.ProjectCacheFolder, "WindowsLayout.xml");
if (!Editor.IsHeadlessMode) // Create main window
var settings = CreateWindowSettings.Default;
settings.Title = "Flax Editor";
settings.Size = Platform.DesktopSize * 0.75f;
settings.MinimumSize = new Float2(200, 150);
settings.StartPosition = WindowStartPosition.CenterScreen;
settings.ShowAfterFirstPaint = true;
if (Utilities.Utils.UseCustomWindowDecorations(isMainWindow: true))
{ {
// Create main window
var settings = CreateWindowSettings.Default;
settings.Title = "Flax Editor";
settings.Size = Platform.DesktopSize * 0.75f;
settings.MinimumSize = new Float2(200, 150);
settings.StartPosition = WindowStartPosition.CenterScreen;
settings.ShowAfterFirstPaint = true;
if (Utilities.Utils.UseCustomWindowDecorations(isMainWindow: true))
{
settings.HasBorder = false;
#if PLATFORM_WINDOWS && !PLATFORM_SDL
// Skip OS sizing frame and implement it using LeftButtonHit
settings.HasSizingFrame = false;
#endif
}
#if PLATFORM_LINUX && !PLATFORM_SDL
settings.HasBorder = false; settings.HasBorder = false;
#if PLATFORM_WINDOWS && !PLATFORM_SDL
// Skip OS sizing frame and implement it using LeftButtonHit
settings.HasSizingFrame = false;
#endif #endif
MainWindow = Platform.CreateWindow(ref settings);
if (MainWindow == null)
{
Editor.LogError("Failed to create editor main window!");
return;
}
UpdateWindowTitle();
// Link for main window events
MainWindow.Closing += MainWindow_OnClosing;
MainWindow.Closed += MainWindow_OnClosed;
} }
#if PLATFORM_LINUX && !PLATFORM_SDL
settings.HasBorder = false;
#endif
MainWindow = Platform.CreateWindow(ref settings);
if (MainWindow == null)
{
Editor.LogError("Failed to create editor main window!");
return;
}
UpdateWindowTitle();
// Link for main window events
MainWindow.Closing += MainWindow_OnClosing;
MainWindow.Closed += MainWindow_OnClosed;
// Create default editor windows // Create default editor windows
ContentWin = new ContentWindow(Editor); ContentWin = new ContentWindow(Editor);

Some files were not shown because too many files have changed in this diff Show More