2 Commits

Author SHA1 Message Date
c6bc90a82a _lagdriver fixes
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
2025-09-12 13:52:55 +03:00
43b576d961 Add support for Visual Studio 2026 and v145 MSVC toolset
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
2025-09-10 20:05:28 +03:00
978 changed files with 13094 additions and 95170 deletions

View File

@@ -1,42 +0,0 @@
name: Bug Report
description: File a bug report.
title: "[Bug]: "
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report! Please attach any minimal reproduction projects!
- type: textarea
id: description-area
attributes:
label: Description
description: Please provide a description of the bug and what you expected to happen.
validations:
required: true
- type: textarea
id: steps-area
attributes:
label: Steps to reproduce
description: Please provide reproduction steps if possible.
validations:
required: true
- type: dropdown
id: version
attributes:
label: Version
description: What version of Flax are you running?
options:
- '1.8'
- '1.9'
- '1.10'
- '1.11'
- master branch
default: 3
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant logs
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell

View File

@@ -1,22 +0,0 @@
name: Feature Request
description: File a feature request.
title: "[Request]: "
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out a feature request!
- type: textarea
id: description-area
attributes:
label: Description
description: Please provide a description of the feature!
validations:
required: true
- type: textarea
id: benefits-area
attributes:
label: Benefits
description: Please provide what benefits this feature would provide to the engine!
validations:
required: true

View File

@@ -19,7 +19,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 9.0.x
dotnet-version: 8.0.x
- name: Setup .NET Workload
run: |
dotnet workload install ios
@@ -33,4 +33,4 @@ jobs:
git lfs pull
- name: Build
run: |
./Development/Scripts/Mac/CallBuildTool.sh -build -log -dotnet=9 -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame
./Development/Scripts/Mac/CallBuildTool.sh -build -log -dotnet=8 -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame

View File

@@ -16,8 +16,7 @@ jobs:
uses: actions/checkout@v3
- name: Install dependencies
run: |
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 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
uses: ./.github/actions/vulkan
- name: Setup .NET

View File

@@ -87,8 +87,7 @@ jobs:
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Install dependencies
run: |
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
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -119,8 +118,7 @@ jobs:
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Install dependencies
run: |
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
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET

View File

@@ -28,8 +28,7 @@ jobs:
git lfs pull
- name: Install dependencies
run: |
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 libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
- name: Build
run: |
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8

View File

@@ -1,4 +1,4 @@
# Redirect to our own Git LFS server
[lfs]
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
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.

View File

@@ -6,7 +6,6 @@
@3
#include "./Flax/Common.hlsl"
#include "./Flax/Stencil.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
@7
@@ -15,13 +14,10 @@ META_CB_BEGIN(0, Data)
float4x4 WorldMatrix;
float4x4 InvWorld;
float4x4 SvPositionToWorld;
float3 Padding0;
uint RenderLayersMask;
@1META_CB_END
// Use depth buffer for per-pixel decal layering
Texture2D DepthBuffer : register(t0);
Texture2D<uint2> StencilBuffer : register(t1);
// Material shader resources
@2
@@ -204,14 +200,6 @@ void PS_Decal(
#endif
)
{
// Stencil masking
uint stencilObjectLayer = STENCIL_BUFFER_OBJECT_LAYER(STENCIL_BUFFER_LOAD(StencilBuffer, SvPosition.xy));
if ((RenderLayersMask & (1 << stencilObjectLayer)) == 0)
{
clip(-1);
return;
}
float2 screenUV = SvPosition.xy * ScreenSize.zw;
SvPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;

View File

@@ -4,8 +4,8 @@
#define MAX_LOCAL_LIGHTS 4
@1// Forward Shading: Includes
#include "./Flax/LightingCommon.hlsl"
#include "./Flax/ReflectionsCommon.hlsl"
#if USE_REFLECTIONS
#include "./Flax/ReflectionsCommon.hlsl"
#define MATERIAL_REFLECTIONS_SSR 1
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
#include "./Flax/SSR.hlsl"
@@ -14,13 +14,11 @@
#include "./Flax/Lighting.hlsl"
#include "./Flax/ShadowsSampling.hlsl"
#include "./Flax/ExponentialHeightFog.hlsl"
#include "./Flax/VolumetricFog.hlsl"
@2// Forward Shading: Constants
LightData DirectionalLight;
LightData SkyLight;
EnvProbeData EnvironmentProbe;
ProbeData EnvironmentProbe;
ExponentialHeightFogData ExponentialHeightFog;
VolumetricFogData VolumetricFog;
float3 Dummy2;
uint LocalLightsCount;
LightData LocalLights[MAX_LOCAL_LIGHTS];
@@ -29,15 +27,12 @@ TextureCube EnvProbe : register(t__SRV__);
TextureCube SkyLightTexture : register(t__SRV__);
Buffer<float4> ShadowsBuffer : register(t__SRV__);
Texture2D<float> ShadowMap : register(t__SRV__);
Texture3D VolumetricFogTexture : register(t__SRV__);
Texture2D PreIntegratedGF : register(t__SRV__);
@4// Forward Shading: Utilities
// Public accessors for lighting data, use them as data binding might change but those methods will remain.
LightData GetDirectionalLight() { return DirectionalLight; }
LightData GetSkyLight() { return SkyLight; }
EnvProbeData GetEnvironmentProbe() { return EnvironmentProbe; }
ProbeData GetEnvironmentProbe() { return EnvironmentProbe; }
ExponentialHeightFogData GetExponentialHeightFog() { return ExponentialHeightFog; }
VolumetricFogData GetVolumetricFog() { return VolumetricFog; }
uint GetLocalLightsCount() { return LocalLightsCount; }
LightData GetLocalLight(uint i) { return LocalLights[i]; }
@5// Forward Shading: Shaders
@@ -112,8 +107,7 @@ void PS_Forward(
// Calculate reflections
#if USE_REFLECTIONS
float4 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness);
reflections.rgb *= reflections.a;
float3 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness).rgb;
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
// Screen Space Reflections
@@ -121,7 +115,7 @@ void PS_Forward(
Texture2D sceneColorTexture = MATERIAL_REFLECTIONS_SSR_COLOR;
float2 screenUV = materialInput.SvPosition.xy * ScreenSize.zw;
float stepSize = ScreenSize.z; // 1 / screenWidth
float maxSamples = 50;
float maxSamples = 48;
float worldAntiSelfOcclusionBias = 0.1f;
float brdfBias = 0.82f;
float drawDistance = 5000.0f;
@@ -129,7 +123,7 @@ void PS_Forward(
if (hit.z > 0)
{
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
reflections.rgb = lerp(reflections.rgb, screenColor, hit.z);
reflections = lerp(reflections, screenColor, hit.z);
}
// Fallback to software tracing if possible
@@ -141,37 +135,23 @@ void PS_Forward(
if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas))
{
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
reflections.rgb = lerp(surfaceAtlas, float4(screenColor, 1), hit.z);
reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z);
}
}
#endif
#endif
light.rgb += reflections.rgb * GetReflectionSpecularLighting(PreIntegratedGF, ViewPos, gBuffer);
light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a;
#endif
// Add lighting
output.rgb += light.rgb;
// Add lighting (apply ambient occlusion)
output.rgb += light.rgb * gBuffer.AO;
#endif
#if USE_FOG && MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
// Calculate exponential height fog
#if DIRECTX && FEATURE_LEVEL < FEATURE_LEVEL_SM6
// TODO: fix D3D11/D3D10 bug with incorrect distance
float fogSceneDistance = distance(materialInput.WorldPosition, ViewPos);
#else
float fogSceneDistance = gBuffer.ViewPos.z;
#endif
float fogSkipDistance = max(ExponentialHeightFog.VolumetricFogMaxDistance - 100, 0);
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, fogSkipDistance, fogSceneDistance);
if (ExponentialHeightFog.VolumetricFogMaxDistance > 0)
{
// Sample volumetric fog and mix it in
float2 screenUV = materialInput.SvPosition.xy * ScreenSize.zw;
float4 volumetricFog = SampleVolumetricFog(VolumetricFogTexture, VolumetricFog, materialInput.WorldPosition - ViewPos, screenUV, TemporalAAJitter);
fog = CombineVolumetricFog(fog, volumetricFog);
}
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0, gBuffer.ViewPos.z);
// Apply fog to the output color
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE

View File

@@ -21,7 +21,7 @@ float4 ViewInfo;
float4 ScreenSize;
float4 ViewSize;
float3 ViewPadding0;
float ScaledTimeParam;
float UnscaledTimeParam;
@1META_CB_END
// Shader resources
@@ -38,7 +38,6 @@ struct VertexOutput
#endif
float4 ClipExtents : TEXCOORD3;
float2 ClipOrigin : TEXCOORD4;
float2 CustomData : TEXCOORD5; // x-per-geometry type, y-features mask
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
@@ -56,7 +55,6 @@ struct PixelInput
#endif
float4 ClipExtents : TEXCOORD3;
float2 ClipOrigin : TEXCOORD4;
float2 CustomData : TEXCOORD5; // x-per-geometry type, y-features mask
#if USE_CUSTOM_VERTEX_INTERPOLATORS
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
#endif
@@ -69,7 +67,6 @@ struct MaterialInput
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoord;
float2 CustomData; // x-per-geometry type, y-features mask
#if USE_VERTEX_COLOR
half4 VertexColor;
#endif
@@ -87,7 +84,6 @@ MaterialInput GetMaterialInput(Render2DVertex input, VertexOutput output)
MaterialInput result;
result.WorldPosition = output.WorldPosition;
result.TexCoord = output.TexCoord;
result.CustomData = input.CustomDataAndClipOrigin.xy;
#if USE_VERTEX_COLOR
result.VertexColor = output.VertexColor;
#endif
@@ -107,7 +103,6 @@ MaterialInput GetMaterialInput(PixelInput input)
MaterialInput result;
result.WorldPosition = input.WorldPosition;
result.TexCoord = input.TexCoord;
result.CustomData = input.CustomData;
#if USE_VERTEX_COLOR
result.VertexColor = input.VertexColor;
#endif
@@ -234,7 +229,6 @@ VertexOutput VS_GUI(Render2DVertex input)
#if USE_VERTEX_COLOR
output.VertexColor = input.Color;
#endif
output.CustomData = input.CustomDataAndClipOrigin.xy;
output.ClipOrigin = input.CustomDataAndClipOrigin.zw;
output.ClipExtents = input.ClipExtents;

View File

@@ -645,7 +645,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
materialInput.TBN = output.TBN;
materialInput.TwoSidedSign = 1;
materialInput.SvPosition = output.Position;
materialInput.PreSkinnedPosition = position;
materialInput.PreSkinnedPosition = Position;
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
materialInput.InstanceOrigin = output.InstanceOrigin;
materialInput.InstanceParams = output.InstanceParams;

View File

@@ -20,7 +20,7 @@ float4 ScreenSize;
float4 TemporalAAJitter;
float4x4 InverseViewProjectionMatrix;
float3 ViewPadding0;
float ScaledTimeParam;
float UnscaledTimeParam;
@1META_CB_END
// Shader resources

View File

@@ -8,7 +8,6 @@
#include "./Flax/Common.hlsl"
#include "./Flax/MaterialCommon.hlsl"
#include "./Flax/GBufferCommon.hlsl"
#include "./Flax/VolumetricFog.hlsl"
@7
// Primary constant buffer (with additional material parameters)
@@ -22,7 +21,6 @@ float Dummy0;
float VolumetricFogMaxDistance;
int ParticleStride;
int ParticleIndex;
float4 GridSliceParameters;
@1META_CB_END
// Particles attributes buffer
@@ -204,19 +202,19 @@ Material GetMaterialPS(MaterialInput input)
META_PS(true, FEATURE_LEVEL_SM5)
void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out float4 VBufferB : SV_Target1)
{
// Reproject grid position back to the screen and world space
uint3 gridCoordinate = uint3(input.Vertex.Position.xy, input.LayerIndex);
float3 cellOffset = 0.5f;
float2 volumeUV = (gridCoordinate.xy + cellOffset.xy) / GridSize.xy;
float sceneDepth = GetDepthFromSlice(GridSliceParameters, gridCoordinate.z + cellOffset.z) / ViewFar;
float zSlice = gridCoordinate.z + cellOffset.z;
float sceneDepth = (zSlice / GridSize.z) * VolumetricFogMaxDistance / ViewFar;
float deviceDepth = (ViewInfo.w / sceneDepth) + ViewInfo.z;
float4 clipPos = float4(volumeUV * float2(2.0, -2.0) + float2(-1.0, 1.0), deviceDepth, 1.0);
float4 wsPos = mul(clipPos, InverseViewProjectionMatrix);
wsPos.xyz /= wsPos.w;
float3 positionWS = wsPos.xyz / wsPos.w;
// Get material parameters
MaterialInput materialInput = (MaterialInput)0;
materialInput.WorldPosition = wsPos.xyz;
materialInput.WorldPosition = positionWS;
materialInput.TexCoord = input.Vertex.TexCoord;
materialInput.ParticleIndex = ParticleIndex;
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
@@ -227,10 +225,9 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
Material material = GetMaterialPS(materialInput);
// Compute fog properties
material.Opacity *= material.Mask;
float3 albedo = material.Color;
float extinction = material.Opacity * 0.001f;
float3 emission = material.Emissive * material.Opacity;
float extinction = material.Opacity * material.Mask * 0.001f;
float3 emission = material.Emissive;
float3 scattering = albedo * extinction;
float absorption = max(0.0f, extinction - Luminance(scattering));

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

@@ -2,12 +2,12 @@
"Name": "Flax",
"Version": {
"Major": 1,
"Minor": 12,
"Minor": 11,
"Revision": 0,
"Build": 6905
"Build": 6800
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
"Copyright": "Copyright (c) 2012-2025 Wojciech Figat. All rights reserved.",
"GameTarget": "FlaxGame",
"EditorTarget": "FlaxEditor",
"Configuration": {

View File

@@ -188,7 +188,7 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_CASE_STATEMENT_ON_SAME_LINE/@EntryValue">ALWAYS</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_CASE_STATEMENT_STYLE/@EntryValue">ON_SINGLE_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>

19
ISSUE_TEMPLATE.md Normal file
View File

@@ -0,0 +1,19 @@
<!-- Please search existing issues for potential duplicates before filing yours:
https://github.com/flaxengine/FlaxEngine/issues?q=is%3Aissue
-->
**Issue description:**
<!-- What happened, and what was expected. -->
<!-- Log file, can be found in the project directory's `Logs` folder (optional) -->
**Steps to reproduce:**
<!-- Enter minimal reproduction steps if available. -->
**Minimal reproduction project:**
<!-- Recommended as it greatly speeds up debugging. Drag and drop a zip archive to upload it. -->
**Flax version:**
<!-- Specify version number. -->

View File

@@ -49,7 +49,7 @@ Follow the instructions below to compile and run the engine from source.
* Fedora: `sudo dnf install dotnet-sdk-8.0`
* Arch: `sudo pacman -S dotnet-sdk-8.0 dotnet-runtime-8.0 dotnet-targeting-pack-8.0 dotnet-host`
* Install Vulkan SDK ([https://vulkan.lunarg.com/](https://vulkan.lunarg.com/))
* Ubuntu: `sudo apt install vulkan-sdk` (deprecated, follow official docs)
* Ubuntu: `sudo apt install vulkan-sdk`
* Fedora: `sudo dnf install vulkan-headers vulkan-tools vulkan-validation-layers`
* Arch: `sudo pacman -S vulkan-headers vulkan-tools vulkan-validation-layers`
* Install Git with LFS
@@ -60,7 +60,7 @@ Follow the instructions below to compile and run the engine from source.
* Ubuntu: `sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev zlib1g-dev`
* Fedora: `sudo dnf install libX11-devel libXcursor-devel libXinerama-devel ghc-zlib-devel`
* Arch: `sudo pacman -S base-devel libx11 libxcursor libxinerama zlib`
* Install Clang compiler (version 14 or later):
* Install Clang compiler (version 6 or later):
* Ubuntu: `sudo apt-get install clang lldb lld`
* Fedora: `sudo dnf install clang llvm lldb lld`
* Arch: `sudo pacman -S clang lldb lld`

View File

@@ -117,8 +117,7 @@ namespace FlaxEditor.Content.Create
private static bool IsValid(Type type)
{
var controlTypes = Editor.Instance.CodeEditing.Controls.Get();
return (type.IsPublic || type.IsNestedPublic) && !type.IsAbstract && !type.IsGenericType && controlTypes.Contains(new ScriptType(type));
return (type.IsPublic || type.IsNestedPublic) && !type.IsAbstract && !type.IsGenericType;
}
}

View File

@@ -187,11 +187,6 @@ namespace FlaxEditor.Content.Import
// Glossiness, metalness, ambient occlusion, displacement, height, cavity or specular
_settings.Settings.Type = TextureFormatType.GrayScale;
}
else if (_settings.Settings.Type == TextureFormatType.ColorRGB)
{
// Blind guess that common color texture is sRGB
_settings.Settings.sRGB = true;
}
// Try to restore target asset texture import options (useful for fast reimport)
Editor.TryRestoreImportOptions(ref _settings.Settings, ResultUrl);

View File

@@ -281,13 +281,6 @@ namespace FlaxEditor.Content
private void CacheData()
{
if (!_asset)
{
_parameters = Utils.GetEmptyArray<ScriptMemberInfo>();
_methods = Utils.GetEmptyArray<ScriptMemberInfo>();
_attributes = Utils.GetEmptyArray<Attribute>();
return;
}
if (_parameters != null)
return;
if (_asset.WaitForLoaded())
@@ -351,13 +344,13 @@ namespace FlaxEditor.Content
}
/// <inheritdoc />
public string Name => _asset ? Path.GetFileNameWithoutExtension(_asset.Path) : null;
public string Name => Path.GetFileNameWithoutExtension(_asset.Path);
/// <inheritdoc />
public string Namespace => string.Empty;
/// <inheritdoc />
public string TypeName => _asset ? JsonSerializer.GetStringID(_asset.ID) : null;
public string TypeName => JsonSerializer.GetStringID(_asset.ID);
/// <inheritdoc />
public bool IsPublic => true;

View File

@@ -130,11 +130,6 @@ namespace FlaxEditor.Content
eyeAdaptation.Mode = EyeAdaptationMode.None;
eyeAdaptation.OverrideFlags |= EyeAdaptationSettingsOverride.Mode;
preview.PostFxVolume.EyeAdaptation = eyeAdaptation;
var antiAliasing = preview.PostFxVolume.AntiAliasing;
antiAliasing.Mode = AntialiasingMode.FastApproximateAntialiasing;
antiAliasing.OverrideFlags |= AntiAliasingSettingsOverride.Mode;
preview.PostFxVolume.AntiAliasing = antiAliasing;
}
}
}

View File

@@ -141,11 +141,6 @@ API_ENUM() enum class BuildPlatform
/// </summary>
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
WindowsARM64 = 15,
/// <summary>
/// Web
/// </summary>
Web = 16,
};
/// <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.
/// </summary>
MonoAOTStatic,
/// <summary>
/// Target platform doesn't support .NET or it has been disabled.
/// </summary>
NoDotnet,
};
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);

View File

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

View File

@@ -106,7 +106,6 @@ namespace FlaxEditor
case BuildPlatform.MacOSARM64:
case BuildPlatform.MacOSx64: return PlatformType.Mac;
case BuildPlatform.iOSARM64: return PlatformType.iOS;
case BuildPlatform.Web: return PlatformType.Web;
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));
return result;
}
void AndroidPlatformTools::OnBuildStarted(CookingData& data)
{
// Adjust the cooking output folder to be located inside the Gradle assets directory
@@ -412,6 +411,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
return true;
}
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
return false;
}

View File

@@ -15,32 +15,26 @@
#include "Editor/ProjectInfo.h"
#include "Editor/Utilities/EditorUtilities.h"
String GetGDK()
GDKPlatformTools::GDKPlatformTools()
{
String gdk;
Platform::GetEnvironmentVariable(TEXT("GameDKLatest"), gdk);
if (gdk.IsEmpty() || !FileSystem::DirectoryExists(gdk))
// Find GDK
Platform::GetEnvironmentVariable(TEXT("GameDKLatest"), _gdkPath);
if (_gdkPath.IsEmpty() || !FileSystem::DirectoryExists(_gdkPath))
{
gdk.Clear();
Platform::GetEnvironmentVariable(TEXT("GRDKLatest"), gdk);
if (gdk.IsEmpty() || !FileSystem::DirectoryExists(gdk))
_gdkPath.Clear();
Platform::GetEnvironmentVariable(TEXT("GRDKLatest"), _gdkPath);
if (_gdkPath.IsEmpty() || !FileSystem::DirectoryExists(_gdkPath))
{
gdk.Clear();
_gdkPath.Clear();
}
else
{
if (gdk.EndsWith(TEXT("GRDK\\")))
gdk.Remove(gdk.Length() - 6);
else if (gdk.EndsWith(TEXT("GRDK")))
gdk.Remove(gdk.Length() - 5);
if (_gdkPath.EndsWith(TEXT("GRDK\\")))
_gdkPath.Remove(_gdkPath.Length() - 6);
else if (_gdkPath.EndsWith(TEXT("GRDK")))
_gdkPath.Remove(_gdkPath.Length() - 5);
}
}
return gdk;
}
GDKPlatformTools::GDKPlatformTools()
{
_gdkPath = GetGDK();
}
DotNetAOTModes GDKPlatformTools::UseAOT() const
@@ -127,7 +121,7 @@ bool GDKPlatformTools::OnPostProcess(CookingData& data, GDKPlatformSettings* pla
validName.Add('\0');
sb.Append(TEXT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
sb.Append(TEXT("<Game configVersion=\"1\">\n"));
sb.Append(TEXT("<Game configVersion=\"0\">\n"));
sb.AppendFormat(TEXT(" <Identity Name=\"{0}\" Publisher=\"{1}\" Version=\"{2}\"/>\n"),
validName.Get(),
platformSettings->PublisherName.HasChars() ? platformSettings->PublisherName : TEXT("CN=") + gameSettings->CompanyName,

View File

@@ -1,157 +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/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 "Editor/Cooker/GameCooker.h"
IMPLEMENT_SETTINGS_GETTER(WebPlatformSettings, WebPlatform);
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::NoDotnet;
}
PixelFormat WebPlatformTools::GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format)
{
// TODO: texture compression for Web (eg. ASTC for mobile and BC for others?)
return PixelFormatExtensions::FindUncompressedFormat(format);
}
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 build the 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 (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;
}
// 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;
}
}
// 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");
if (!gameJsText.Contains(filesIncludeBegin))
{
// Insert generated files.js into the main game file after the minimum_runtime_check.js include
String fileJsText;
String fileJs = data.OriginalOutputPath / TEXT("files.js");
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);
CHECK_RETURN(location != -1, true);
location += insertPrefixLocation.Length() + 1;
fileJsText = filesIncludeBegin + TEXT("\n") + fileJsText + TEXT("\n") + filesIncludeEnd + TEXT("\n");
gameJsText.Insert(location, fileJsText);
File::WriteAllText(gameJs, gameJsText, Encoding::UTF8);
}
}
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,27 +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;
bool IsNativeCodeFile(CookingData& data, const String& file) override;
void OnBuildStarted(CookingData& data) override;
bool OnPostProcess(CookingData& data) override;
};
#endif

View File

@@ -10,10 +10,9 @@
#include "Engine/Serialization/JsonTools.h"
#include "Engine/Serialization/JsonWriters.h"
#include "Editor/Cooker/PlatformTools.h"
#include "Engine/Engine/Globals.h"
#include "Editor/Editor.h"
#include "Editor/ProjectInfo.h"
#include "Editor/Utilities/EditorUtilities.h"
#include "Engine/Engine/Globals.h"
#if PLATFORM_MAC
#include <sys/stat.h>
#endif
@@ -128,7 +127,7 @@ bool CompileScriptsStep::DeployBinaries(CookingData& data, const String& path, c
const String dst = dstPath / StringUtils::GetFileName(file);
if (dst == file)
continue;
if (EditorUtilities::CopyFileIfNewer(dst, file))
if (FileSystem::CopyFile(dst, file))
{
data.Error(String::Format(TEXT("Failed to copy file from {0} to {1}."), file, dst));
return true;

View File

@@ -526,7 +526,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
#if PLATFORM_TOOLS_XBOX_SCARLETT
case BuildPlatform::XboxScarlett:
{
options.Platform = PlatformType::XboxScarlett;
const char* platformDefineName = "PLATFORM_XBOX_SCARLETT";
COMPILE_PROFILE(DirectX_SM6, SHADER_FILE_CHUNK_INTERNAL_D3D_SM6_CACHE);
break;
@@ -572,14 +571,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
break;
}
#endif
#if PLATFORM_TOOLS_WEB
case BuildPlatform::Web:
{
const char* platformDefineName = "PLATFORM_WEB";
// TODO: compile shaders for WebGPU
break;
}
#endif
default:
{
@@ -1376,10 +1367,7 @@ bool CookAssetsStep::Perform(CookingData& data)
{
typeName = e.TypeName;
}
if (e.Count == 1)
LOG(Info, "{0}: 1 asset of total size {1}", typeName, Utilities::BytesToText(e.ContentSize));
else
LOG(Info, "{0}: {1:>4} assets of total size {2}", typeName, e.Count, Utilities::BytesToText(e.ContentSize));
LOG(Info, "{0}: {1:>4} assets of total size {2}", typeName, e.Count, Utilities::BytesToText(e.ContentSize));
}
LOG(Info, "");
}

View File

@@ -39,23 +39,17 @@ bool DeployDataStep::Perform(CookingData& data)
}
String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
const DotNetAOTModes aotMode = data.Tools->UseAOT();
const bool usAOT = aotMode != DotNetAOTModes::None && aotMode != DotNetAOTModes::NoDotnet;
const bool usAOT = aotMode != DotNetAOTModes::None;
if (usAOT)
{
// Deploy Dotnet files into intermediate cooking directory for AOT
FileSystem::DeleteDirectory(dstDotnet);
dstDotnet = data.ManagedCodeOutputPath;
}
if (aotMode == DotNetAOTModes::NoDotnet)
{
// No .NET
FileSystem::DeleteDirectory(dstDotnet);
}
else if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
{
// Use system-installed .NET Runtime
FileSystem::DeleteDirectory(dstDotnet);
LOG(Info, "Not using .NET Runtime");
}
else
{
@@ -271,7 +265,7 @@ bool DeployDataStep::Perform(CookingData& data)
}
if (version.IsEmpty())
{
data.Error(String::Format(TEXT("Failed to find supported .NET {} version (min {}) for {} platform."), maxVer, minVer, platformName));
data.Error(String::Format(TEXT("Failed to find supported .NET {} version (min {}) for the current host platform."), maxVer, minVer));
return true;
}
}

View File

@@ -12,9 +12,7 @@
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
{
const DotNetAOTModes aotMode = data.Tools->UseAOT();
if (aotMode == DotNetAOTModes::None ||
aotMode == DotNetAOTModes::NoDotnet ||
EnumHasAllFlags(data.Options, BuildOptions::NoCook))
if (aotMode == DotNetAOTModes::None || EnumHasAllFlags(data.Options, BuildOptions::NoCook))
return;
const auto& buildSettings = *BuildSettings::Get();
@@ -51,8 +49,7 @@ void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
bool PrecompileAssembliesStep::Perform(CookingData& data)
{
const DotNetAOTModes aotMode = data.Tools->UseAOT();
if (aotMode == DotNetAOTModes::None ||
aotMode == DotNetAOTModes::NoDotnet)
if (aotMode == DotNetAOTModes::None)
return false;
const auto& buildSettings = *BuildSettings::Get();
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
@@ -62,7 +59,6 @@ bool PrecompileAssembliesStep::Perform(CookingData& data)
data.StepProgress(infoMsg, 0);
// Override Newtonsoft.Json with AOT-version (one that doesn't use System.Reflection.Emit)
// TODO: remove it since EngineModule does properly reference AOT lib now
EditorUtilities::CopyFileIfNewer(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.dll"), Globals::StartupFolder / TEXT("Source/Platforms/DotNet/AOT/Newtonsoft.Json.dll"));
FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.xml"));
FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.pdb"));

View File

@@ -87,11 +87,8 @@ namespace FlaxEditor.CustomEditors
var targetTypeType = TypeUtils.GetType(targetType);
if (canUseRefPicker)
{
// TODO: add generic way of CustomEditor for ref pickers (use it on AssetRefEditor/GPUTextureEditor/...)
if (typeof(Asset).IsAssignableFrom(targetTypeType))
return new AssetRefEditor();
if (typeof(GPUTexture).IsAssignableFrom(targetTypeType))
return new GPUTextureEditor();
if (typeof(FlaxEngine.Object).IsAssignableFrom(targetTypeType))
return new FlaxObjectRefEditor();
}

View File

@@ -13,8 +13,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
public class AudioSourceEditor : ActorEditor
{
private Label _infoLabel;
private Slider _slider;
private AudioSource.States _slideStartState;
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
@@ -30,13 +28,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
_infoLabel = playbackGroup.Label(string.Empty).Label;
_infoLabel.AutoHeight = true;
// Play back slider
var sliderElement = playbackGroup.CustomContainer<Slider>();
_slider = sliderElement.CustomControl;
_slider.ThumbSize = new Float2(_slider.ThumbSize.X * 0.5f, _slider.ThumbSize.Y);
_slider.SlidingStart += OnSlidingStart;
_slider.SlidingEnd += OnSlidingEnd;
var grid = playbackGroup.UniformGrid();
var gridControl = grid.CustomControl;
gridControl.ClipChildren = false;
@@ -49,38 +40,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
}
}
private void OnSlidingEnd()
{
foreach (var value in Values)
{
if (value is AudioSource audioSource && audioSource.Clip)
{
switch (_slideStartState)
{
case AudioSource.States.Playing:
audioSource.Play();
break;
case AudioSource.States.Paused:
case AudioSource.States.Stopped:
audioSource.Pause();
break;
default: break;
}
}
}
}
private void OnSlidingStart()
{
foreach (var value in Values)
{
if (value is AudioSource audioSource && audioSource.Clip)
{
_slideStartState = audioSource.State;
}
}
}
/// <inheritdoc />
public override void Refresh()
{
@@ -92,29 +51,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
foreach (var value in Values)
{
if (value is AudioSource audioSource && audioSource.Clip)
{
text += $"Time: {audioSource.Time:##0.0}s / {audioSource.Clip.Length:##0.0}s\n";
_slider.Maximum = audioSource.Clip.Length;
_slider.Minimum = 0;
if (_slider.IsSliding)
{
if (audioSource.State != AudioSource.States.Playing)
{
// Play to move slider correctly
audioSource.Play();
audioSource.Time = _slider.Value;
}
else
{
audioSource.Time = _slider.Value;
}
}
else
{
_slider.Value = audioSource.Time;
}
}
}
_infoLabel.Text = text;
}

View File

@@ -1,7 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.CustomEditors.Dedicated
{
@@ -12,7 +11,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
[CustomEditor(typeof(EnvironmentProbe)), DefaultEditor]
public class EnvironmentProbeEditor : ActorEditor
{
private Button _bake;
private FlaxEngine.GUI.Button _bake;
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
@@ -21,12 +20,9 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (Values.HasDifferentTypes == false)
{
var group = layout.Group("Probe");
group.Panel.ItemsMargin = new Margin(Utilities.Constants.UIMargin * 2);
_bake = group.Button("Bake").Button;
layout.Space(10);
_bake = layout.Button("Bake").Button;
_bake.Clicked += BakeButtonClicked;
var view = group.Button("View", "Opens the probe texture viewer");
view.Button.Clicked += OnViewButtonClicked;
}
}
@@ -52,14 +48,5 @@ namespace FlaxEditor.CustomEditors.Dedicated
}
}
}
private void OnViewButtonClicked()
{
foreach (var value in Values)
{
if (value is EnvironmentProbe probe && probe.ProbeAsset)
Editor.Instance.ContentEditing.Open(probe.ProbeAsset);
}
}
}
}

View File

@@ -1,68 +0,0 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEditor.GUI.ContextMenu;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.CustomEditors.Dedicated
{
/// <summary>
/// Basic editor/viewer for <see cref="GPUTexture"/>.
/// </summary>
[CustomEditor(typeof(GPUTexture)), DefaultEditor]
public class GPUTextureEditor : CustomEditor
{
private Image _image;
/// <inheritdoc />
public override DisplayStyle Style => DisplayStyle.Inline;
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
_image = new Image
{
Brush = new GPUTextureBrush(),
Size = new Float2(200, 100),
Parent = layout.ContainerControl,
};
_image.Clicked += OnImageClicked;
}
private void OnImageClicked(Image image, MouseButton button)
{
var texture = Values[0] as GPUTexture;
if (!texture || button != MouseButton.Right)
return;
var menu = new ContextMenu();
menu.AddButton("Save...", () => Screenshot.Capture(Values[0] as GPUTexture));
menu.AddButton("Enlarge", () => _image.Size *= 2);
menu.AddButton("Shrink", () => _image.Size /= 2).Enabled = _image.Height > 32;
var location = image.PointFromScreen(Input.MouseScreenPosition);
menu.Show(image, location);
}
/// <inheritdoc />
public override void Refresh()
{
base.Refresh();
var texture = Values[0] as GPUTexture;
((GPUTextureBrush)_image.Brush).Texture = texture;
if (texture)
{
var desc = texture.Description;
#if BUILD_RELEASE
var name = string.Empty;
#else
var name = texture.Name;
#endif
_image.TooltipText = $"{name}\nType: {texture.ResourceType}\nSize: {desc.Width}x{desc.Height}\nFormat: {desc.Format}\nMemory: {Utilities.Utils.FormatBytesCount(texture.MemoryUsage)}";
}
else
{
_image.TooltipText = "None";
}
}
}
}

View File

@@ -195,7 +195,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
filesCount += files.Length;
foreach (var file in files)
FindNewKeysCpp(file, newKeys, allKeys);
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.hpp", SearchOption.AllDirectories)).ToArray();
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.hpp", SearchOption.AllDirectories)).ToArray();;
filesCount += files.Length;
foreach (var file in files)
FindNewKeysCpp(file, newKeys, allKeys);

View File

@@ -1,38 +0,0 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEngine;
namespace FlaxEditor.CustomEditors.Dedicated
{
/// <summary>
/// Custom editor for <see cref="NavMeshBoundsVolume"/>.
/// </summary>
/// <seealso cref="ActorEditor" />
[CustomEditor(typeof(NavMeshBoundsVolume)), DefaultEditor]
internal class NavMeshBoundsVolumeEditor : ActorEditor
{
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
base.Initialize(layout);
if (Values.HasDifferentTypes == false)
{
var button = layout.Button("Build");
button.Button.Clicked += OnBuildClicked;
}
}
private void OnBuildClicked()
{
foreach (var value in Values)
{
if (value is NavMeshBoundsVolume volume)
{
Navigation.BuildNavMesh(volume.Box, volume.Scene);
Editor.Instance.Scene.MarkSceneEdited(volume.Scene);
}
}
}
}
}

View File

@@ -1,6 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System.Collections.Generic;
using System.Reflection.Emit;
using FlaxEditor.CustomEditors.GUI;
using FlaxEngine;
using FlaxEngine.GUI;

View File

@@ -36,7 +36,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
{
ScriptName = scriptName;
TooltipText = "Create a new script";
DrawHighlights = false;
}
}
@@ -71,7 +70,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var buttonHeight = (textSize.Y < 18) ? 18 : textSize.Y + 4;
_addScriptsButton = new Button
{
TooltipText = "Add new scripts to the actor.",
TooltipText = "Add new scripts to the actor",
AnchorPreset = AnchorPresets.MiddleCenter,
Text = buttonText,
Parent = this,
@@ -115,16 +114,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
cm.TextChanged += text =>
{
if (!IsValidScriptName(text))
{
// Remove NewScriptItems
List<Control> newScriptItems = cm.ItemsPanel.Children.FindAll(c => c is NewScriptItem);
foreach (var item in newScriptItems)
{
cm.ItemsPanel.RemoveChild(item);
}
return;
}
if (!cm.ItemsPanel.Children.Any(x => x.Visible && x is not NewScriptItem))
{
// If there are no visible items, that means the search failed so we can find the create script button or create one if it's the first time
@@ -886,7 +876,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Add drag button to the group
var scriptDrag = new DragImage
{
TooltipText = "Script reference.",
TooltipText = "Script reference",
AutoFocus = true,
IsScrollable = false,
Color = FlaxEngine.GUI.Style.Current.ForegroundGrey,
@@ -909,17 +899,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
settingsButton.Tag = script;
settingsButton.Clicked += OnSettingsButtonClicked;
// 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 = new Margin(scriptDrag.Right - 12, 15, 2, 2);
group.Object(values, editor);
// Remove drop down arrows and containment lines if no objects in the group
if (group.Children.Count == 0)
{
group.Panel.Close();
group.Panel.ArrowImageOpened = null;
group.Panel.ArrowImageClosed = null;
group.Panel.EnableContainmentLines = false;
group.Panel.CanOpenClose = false;
}
// Scripts arrange bar

View File

@@ -1,7 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.CustomEditors.Dedicated
{
@@ -20,9 +19,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (Values.HasDifferentTypes == false)
{
// Add 'Bake' button
var group = layout.Group("Bake");
group.Panel.ItemsMargin = new Margin(Utilities.Constants.UIMargin * 2);
var button = group.Button("Bake");
layout.Space(10);
var button = layout.Button("Bake");
button.Button.Clicked += BakeButtonClicked;
}
}

View File

@@ -123,8 +123,6 @@ namespace FlaxEditor.CustomEditors.Editors
{
base.Refresh();
if (Picker == null)
return;
var differentValues = HasDifferentValues;
Picker.DifferentValues = differentValues;
if (!differentValues)

View File

@@ -71,7 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors
menu.AddButton("Copy", linkedEditor.Copy);
var b = menu.AddButton("Duplicate", () => Editor.Duplicate(Index));
b.Enabled = !Editor._readOnly && Editor._canResize;
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
b = menu.AddButton("Paste", linkedEditor.Paste);
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
@@ -407,7 +407,7 @@ namespace FlaxEditor.CustomEditors.Editors
menu.AddButton("Copy", linkedEditor.Copy);
var b = menu.AddButton("Duplicate", () => Editor.Duplicate(Index));
b.Enabled = !Editor._readOnly && Editor._canResize;
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
var paste = menu.AddButton("Paste", linkedEditor.Paste);
paste.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
@@ -422,8 +422,7 @@ namespace FlaxEditor.CustomEditors.Editors
moveDownButton.Enabled = Index + 1 < Editor.Count;
}
b = menu.AddButton("Remove", OnRemoveClicked);
b.Enabled = !Editor._readOnly && Editor._canResize;
menu.AddButton("Remove", OnRemoveClicked);
menu.Show(panel, location);
}
@@ -450,7 +449,6 @@ namespace FlaxEditor.CustomEditors.Editors
protected bool NotNullItems;
private IntValueBox _sizeBox;
private Label _label;
private Color _background;
private int _elementsCount, _minCount, _maxCount;
private bool _readOnly;
@@ -567,7 +565,7 @@ namespace FlaxEditor.CustomEditors.Editors
Parent = dropPanel,
};
_label = new Label
var label = new Label
{
Text = "Size",
AnchorPreset = AnchorPresets.TopRight,
@@ -593,12 +591,11 @@ namespace FlaxEditor.CustomEditors.Editors
panel.Panel.Offsets = new Margin(7, 7, 0, 0);
panel.Panel.BackgroundColor = _background;
var elementType = ElementType;
var bindingAttr = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public;
bool single = elementType.IsPrimitive ||
elementType.Equals(new ScriptType(typeof(string))) ||
elementType.IsEnum ||
(elementType.GetFields(bindingAttr).Length == 1 && elementType.GetProperties(bindingAttr).Length == 0) ||
(elementType.GetProperties(bindingAttr).Length == 1 && elementType.GetFields(bindingAttr).Length == 0) ||
(elementType.GetFields().Length == 1 && elementType.GetProperties().Length == 0) ||
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
elementType.Equals(new ScriptType(typeof(SettingsBase)));
if (_cachedDropPanels == null)
@@ -652,7 +649,7 @@ namespace FlaxEditor.CustomEditors.Editors
panel.Panel.Size = new Float2(0, 18);
panel.Panel.Margin = new Margin(0, 0, Utilities.Constants.UIMargin, 0);
var removeButton = panel.Button("-", "Remove the last item.");
var removeButton = panel.Button("-", "Remove the last item");
removeButton.Button.Size = new Float2(16, 16);
removeButton.Button.Enabled = size > _minCount;
removeButton.Button.AnchorPreset = AnchorPresets.TopRight;
@@ -663,7 +660,7 @@ namespace FlaxEditor.CustomEditors.Editors
Resize(Count - 1);
};
var addButton = panel.Button("+", "Add a new item.");
var addButton = panel.Button("+", "Add a new item");
addButton.Button.Size = new Float2(16, 16);
addButton.Button.Enabled = (!NotNullItems || size > 0) && size < _maxCount;
addButton.Button.AnchorPreset = AnchorPresets.TopRight;
@@ -674,10 +671,8 @@ namespace FlaxEditor.CustomEditors.Editors
Resize(Count + 1);
};
}
Layout.ContainerControl.SizeChanged += OnLayoutSizeChanged;
}
private void OnSetupContextMenu(ContextMenu menu, DropPanel panel)
{
if (menu.Items.Any(x => x is ContextMenuButton b && b.Text.Equals("Open All", StringComparison.Ordinal)))
@@ -700,24 +695,10 @@ namespace FlaxEditor.CustomEditors.Editors
});
}
private void OnLayoutSizeChanged(Control control)
{
if (Layout.ContainerControl is DropPanel dropPanel)
{
// Hide "Size" text when array editor title overlaps
var headerTextSize = dropPanel.HeaderTextFont.GetFont().MeasureText(dropPanel.HeaderText);
if (headerTextSize.X + DropPanel.DropDownIconSize >= _label.Left)
_label.TextColor = _label.TextColorHighlighted = Color.Transparent;
else
_label.TextColor = _label.TextColorHighlighted = FlaxEngine.GUI.Style.Current.Foreground;
}
}
/// <inheritdoc />
protected override void Deinitialize()
{
_sizeBox = null;
Layout.ContainerControl.SizeChanged -= OnLayoutSizeChanged;
base.Deinitialize();
}

View File

@@ -47,8 +47,6 @@ namespace FlaxEditor.CustomEditors.Editors
return inputEvent;
if (Values[0] is string str)
return str;
if (Values.Type.Type == typeof(InputEvent))
return new InputEvent();
if (Values.Type.Type == typeof(string))
return string.Empty;
return null;

View File

@@ -3,7 +3,6 @@
using System;
using FlaxEditor.GUI;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.Utilities;
namespace FlaxEditor.CustomEditors.Editors
@@ -82,13 +81,9 @@ namespace FlaxEditor.CustomEditors.Editors
private OptionType[] _options;
private ScriptType _type;
private Elements.PropertiesListElement _typeItem;
private ScriptType Type => Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
/// <inheritdoc />
public override bool RevertValueWithChildren => false; // Always revert value for a whole object
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
@@ -103,8 +98,7 @@ namespace FlaxEditor.CustomEditors.Editors
_type = type;
// Type
_typeItem = layout.AddPropertyItem(TypeComboBoxName, "Type of the object value. Use it to change the object.");
var typeEditor = _typeItem.ComboBox();
var typeEditor = layout.ComboBox(TypeComboBoxName, "Type of the object value. Use it to change the object.");
for (int i = 0; i < _options.Length; i++)
{
typeEditor.ComboBox.AddItem(_options[i].Name);
@@ -132,8 +126,6 @@ namespace FlaxEditor.CustomEditors.Editors
// Value
var values = new CustomValueContainer(type, (instance, index) => instance);
if (Values.HasReferenceValue)
values.SetReferenceValue(Values.ReferenceValue);
values.AddRange(Values);
var editor = CustomEditorsUtil.CreateEditor(type);
var style = editor.Style;
@@ -178,12 +170,6 @@ namespace FlaxEditor.CustomEditors.Editors
{
base.Refresh();
// Show prefab diff when reference value type is different
var color = Color.Transparent;
if (Values.HasReferenceValue && CanRevertReferenceValue && Values[0]?.GetType() != Values.ReferenceValue?.GetType())
color = FlaxEngine.GUI.Style.Current.BackgroundSelected;
_typeItem.Labels[0].HighlightStripColor = color;
// Check if type has been modified outside the editor (eg. from code)
if (Type != _type)
{

View File

@@ -104,7 +104,7 @@ namespace FlaxEditor.CustomEditors.Editors
public event Action<TypePickerControl> TypePickerValueChanged;
/// <summary>
/// The custom callback for types validation. Can be used to implement a rule for types to pick.
/// The custom callback for types validation. Cane be used to implement a rule for types to pick.
/// </summary>
public Func<ScriptType, bool> CheckValid;
@@ -353,13 +353,7 @@ namespace FlaxEditor.CustomEditors.Editors
}
if (!string.IsNullOrEmpty(typeReference.CheckMethod))
{
var parentEditor = ParentEditor;
// Find actual parent editor if parent editor is collection editor
while (parentEditor.GetType().IsAssignableTo(typeof(CollectionEditor)))
parentEditor = parentEditor.ParentEditor;
var parentType = parentEditor.Values[0].GetType();
var parentType = ParentEditor.Values[0].GetType();
var method = parentType.GetMethod(typeReference.CheckMethod, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (method != null)
{

View File

@@ -44,8 +44,7 @@ namespace FlaxEditor.CustomEditors.Elements
{
var style = Style.Current;
var settingsButtonSize = Panel.HeaderHeight;
Panel.HeaderTextMargin = Panel.HeaderTextMargin with { Right = settingsButtonSize + Utilities.Constants.UIMargin };
; return new Image
return new Image
{
TooltipText = "Settings",
AutoFocus = true,

View File

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

View File

@@ -268,8 +268,8 @@ bool Editor::CheckProjectUpgrade()
// Check if last version was older
else if (lastVersion.Major < FLAXENGINE_VERSION_MAJOR || (lastVersion.Major == FLAXENGINE_VERSION_MAJOR && lastVersion.Minor < FLAXENGINE_VERSION_MINOR))
{
LOG(Warning, "The project was last opened with an older editor version");
const auto result = MessageBox::Show(TEXT("The project was last opened with an older editor version.\nLoading it may modify existing data, which can result in older editor versions being unable to open it.\n\nDo you want to perform a backup before or cancel the operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Question);
LOG(Warning, "The project was opened with the older editor version last time");
const auto result = MessageBox::Show(TEXT("The project was opened with the older editor version last time. Loading it may modify existing data so older editor version won't open it. Do you want to perform a backup before or cancel operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Question);
if (result == DialogResult::Yes)
{
if (BackupProject())
@@ -291,8 +291,8 @@ bool Editor::CheckProjectUpgrade()
// Check if last version was newer
else if (lastVersion.Major > FLAXENGINE_VERSION_MAJOR || (lastVersion.Major == FLAXENGINE_VERSION_MAJOR && lastVersion.Minor > FLAXENGINE_VERSION_MINOR))
{
LOG(Warning, "The project was last opened with a newer editor version");
const auto result = MessageBox::Show(TEXT("The project was last opened with a newer editor version.\nLoading it may fail and corrupt existing data.\n\nDo you want to perform a backup before loading or cancel the operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Warning);
LOG(Warning, "The project was opened with the newer editor version last time");
const auto result = MessageBox::Show(TEXT("The project was opened with the newer editor version last time. Loading it may fail and corrupt existing data. Do you want to perform a backup before or cancel operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Warning);
if (result == DialogResult::Yes)
{
if (BackupProject())

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