Merge remote-tracking branch 'origin/master' into sdl_platform

# Conflicts:
#	Source/Editor/Windows/GameWindow.cs
This commit is contained in:
2025-10-18 02:19:30 +03:00
14 changed files with 60 additions and 44 deletions

View File

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

View File

@@ -412,7 +412,7 @@ namespace FlaxEditor.Surface.ContextMenu
{ {
group.UnlockChildrenRecursive(); group.UnlockChildrenRecursive();
// TODO: Improve filtering to be based on boxes with the most common things instead of first box // TODO: Improve filtering to be based on boxes with the most common things instead of first box
if (_contextSensitiveSearchEnabled && _selectedBoxes[0] != null) if (_contextSensitiveSearchEnabled && _selectedBoxes.Count > 0 && _selectedBoxes[0] != null)
UpdateFilters(); UpdateFilters();
else else
SortGroups(); SortGroups();
@@ -424,7 +424,7 @@ namespace FlaxEditor.Surface.ContextMenu
OnSearchFilterChanged(); OnSearchFilterChanged();
} }
} }
else if (_contextSensitiveSearchEnabled) else if (_contextSensitiveSearchEnabled && _selectedBoxes.Count > 0)
{ {
// TODO: Filtering could be improved here as well // TODO: Filtering could be improved here as well
group.EvaluateVisibilityWithBox(_selectedBoxes[0]); group.EvaluateVisibilityWithBox(_selectedBoxes[0]);
@@ -462,7 +462,7 @@ namespace FlaxEditor.Surface.ContextMenu
Parent = group Parent = group
}; };
} }
if (_contextSensitiveSearchEnabled) if (_contextSensitiveSearchEnabled && _selectedBoxes.Count > 0)
group.EvaluateVisibilityWithBox(_selectedBoxes[0]); group.EvaluateVisibilityWithBox(_selectedBoxes[0]);
group.SortChildren(); group.SortChildren();
if (ShowExpanded) if (ShowExpanded)
@@ -476,7 +476,7 @@ namespace FlaxEditor.Surface.ContextMenu
if (!isLayoutLocked) if (!isLayoutLocked)
{ {
if (_contextSensitiveSearchEnabled && _selectedBoxes[0] != null) if (_contextSensitiveSearchEnabled && _selectedBoxes.Count != 0 && _selectedBoxes[0] != null)
UpdateFilters(); UpdateFilters();
else else
SortGroups(); SortGroups();

View File

@@ -257,16 +257,23 @@ namespace FlaxEditor.Viewport
/// </summary> /// </summary>
public void SaveActiveUIScalingOption() public void SaveActiveUIScalingOption()
{ {
var defaultKey = $"{Prefab.ID}:DefaultViewportScalingIndex"; if (!Prefab)
return;
var id = Prefab.ID;
var defaultKey = $"{id}:DefaultViewportScalingIndex";
Editor.Instance.ProjectCache.SetCustomData(defaultKey, _defaultScaleActiveIndex.ToString()); Editor.Instance.ProjectCache.SetCustomData(defaultKey, _defaultScaleActiveIndex.ToString());
var customKey = $"{Prefab.ID}:CustomViewportScalingIndex"; var customKey = $"{id}:CustomViewportScalingIndex";
Editor.Instance.ProjectCache.SetCustomData(customKey, _customScaleActiveIndex.ToString()); Editor.Instance.ProjectCache.SetCustomData(customKey, _customScaleActiveIndex.ToString());
} }
private void LoadCustomUIScalingOption() private void LoadCustomUIScalingOption()
{ {
if (!Prefab)
return;
var id = Prefab.ID;
Prefab.WaitForLoaded(); Prefab.WaitForLoaded();
var defaultKey = $"{Prefab.ID}:DefaultViewportScalingIndex";
var defaultKey = $"{id}:DefaultViewportScalingIndex";
if (Editor.Instance.ProjectCache.TryGetCustomData(defaultKey, out string defaultData)) if (Editor.Instance.ProjectCache.TryGetCustomData(defaultKey, out string defaultData))
{ {
if (int.TryParse(defaultData, out var index)) if (int.TryParse(defaultData, out var index))
@@ -286,7 +293,7 @@ namespace FlaxEditor.Viewport
} }
} }
var customKey = $"{Prefab.ID}:CustomViewportScalingIndex"; var customKey = $"{id}:CustomViewportScalingIndex";
if (Editor.Instance.ProjectCache.TryGetCustomData(customKey, out string data)) if (Editor.Instance.ProjectCache.TryGetCustomData(customKey, out string data))
{ {
if (int.TryParse(data, out var index)) if (int.TryParse(data, out var index))

View File

@@ -889,12 +889,12 @@ namespace FlaxEditor.Windows
if (!_cursorVisible) if (!_cursorVisible)
Screen.CursorVisible = true; Screen.CursorVisible = true;
Screen.CursorLock = CursorLockMode.None; Screen.CursorLock = CursorLockMode.None;
}
if (Editor.IsPlayMode && IsDocked && IsSelected && RootWindow.FocusedControl == null) if (Editor.IsPlayMode && IsDocked && IsSelected && RootWindow.FocusedControl == null)
{ {
// Game UI cleared focus so regain it to maintain UI navigation just like game window does // Game UI cleared focus so regain it to maintain UI navigation just like game window does
FlaxEngine.Scripting.InvokeOnUpdate(Focus); FlaxEngine.Scripting.InvokeOnUpdate(Focus);
}
} }
} }

View File

@@ -192,6 +192,7 @@ void GPUContextVulkan::AddImageBarrier(VkImage image, VkImageLayout srcLayout, V
void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayout dstLayout) void GPUContextVulkan::AddImageBarrier(GPUTextureViewVulkan* handle, VkImageLayout dstLayout)
{ {
ASSERT(handle->Owner);
auto& state = handle->Owner->State; auto& state = handle->Owner->State;
const auto subresourceIndex = handle->SubresourceIndex; const auto subresourceIndex = handle->SubresourceIndex;
if (subresourceIndex == -1) if (subresourceIndex == -1)
@@ -516,7 +517,7 @@ void GPUContextVulkan::UpdateDescriptorSets(const SpirvShaderDescriptorInfo& des
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
{ {
auto handle = (GPUTextureViewVulkan*)handles[slot]; auto handle = (GPUTextureViewVulkan*)handles[slot];
if (!handle) if (!handle || !handle->Owner)
{ {
const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType); const auto dummy = _device->HelperResources.GetDummyTexture(descriptor.ResourceType);
switch (descriptor.ResourceType) switch (descriptor.ResourceType)

View File

@@ -5,6 +5,7 @@
#include "Engine/Physics/Physics.h" #include "Engine/Physics/Physics.h"
#include "Engine/Physics/PhysicsBackend.h" #include "Engine/Physics/PhysicsBackend.h"
#include "Engine/Physics/PhysicsScene.h" #include "Engine/Physics/PhysicsScene.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Engine/Time.h" #include "Engine/Engine/Time.h"
#define CC_MIN_SIZE 0.001f #define CC_MIN_SIZE 0.001f
@@ -178,6 +179,7 @@ CharacterController::CollisionFlags CharacterController::SimpleMove(const Vector
CharacterController::CollisionFlags CharacterController::Move(const Vector3& displacement) CharacterController::CollisionFlags CharacterController::Move(const Vector3& displacement)
{ {
PROFILE_CPU();
CollisionFlags result = CollisionFlags::None; CollisionFlags result = CollisionFlags::None;
if (_controller && !_isUpdatingTransform) if (_controller && !_isUpdatingTransform)
{ {
@@ -377,7 +379,10 @@ void CharacterController::AddMovement(const Vector3& translation, const Quaterni
displacement += GetPhysicsScene()->GetGravity() * deltaTime; displacement += GetPhysicsScene()->GetGravity() * deltaTime;
} }
Move(displacement); if (!displacement.IsZero())
{
Move(displacement);
}
if (!rotation.IsIdentity()) if (!rotation.IsIdentity())
{ {

View File

@@ -32,6 +32,7 @@ public:
} }
public: public:
using JsonWriter::Key;
// [JsonWriter] // [JsonWriter]
void Key(const char* str, int32 length) override void Key(const char* str, int32 length) override

View File

@@ -390,7 +390,7 @@ public class Slider : ContainerControl
} }
// Draw thumb // Draw thumb
var thumbColorV = _isSliding ? ThumbColorSelected : (_mouseOverThumb ? ThumbColorHighlighted : ThumbColor); var thumbColorV = _isSliding ? ThumbColorSelected : (_mouseOverThumb || IsNavFocused ? ThumbColorHighlighted : ThumbColor);
if (ThumbBrush != null) if (ThumbBrush != null)
ThumbBrush.Draw(_thumbRect, thumbColorV); ThumbBrush.Draw(_thumbRect, thumbColorV);
else else

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -52,6 +52,7 @@ namespace Flax.Deps.Dependencies
var version = "1.24.3"; var version = "1.24.3";
var configuration = "Release"; var configuration = "Release";
var dstIncludePath = Path.Combine(options.ThirdPartyFolder, "OpenAL"); var dstIncludePath = Path.Combine(options.ThirdPartyFolder, "OpenAL");
var noSSL = true; // OpenAL Soft website has broken certs
foreach (var platform in options.Platforms) foreach (var platform in options.Platforms)
{ {
@@ -87,7 +88,7 @@ namespace Flax.Deps.Dependencies
// Get the binaries // Get the binaries
var packagePath = Path.Combine(root, "package.zip"); var packagePath = Path.Combine(root, "package.zip");
if (!File.Exists(packagePath)) if (!File.Exists(packagePath))
Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-binaries/openal-soft-" + version + "-bin.zip", packagePath); Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-binaries/openal-soft-" + version + "-bin.zip", packagePath, noSSL);
using (ZipArchive archive = ZipFile.Open(packagePath, ZipArchiveMode.Read)) using (ZipArchive archive = ZipFile.Open(packagePath, ZipArchiveMode.Read))
{ {
if (!Directory.Exists(root)) if (!Directory.Exists(root))
@@ -135,7 +136,7 @@ namespace Flax.Deps.Dependencies
// Get the source // Get the source
var packagePath = Path.Combine(root, "package.zip"); var packagePath = Path.Combine(root, "package.zip");
File.Delete(packagePath); File.Delete(packagePath);
Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath); Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath, noSSL);
Utilities.Run("tar", "xjf " + packagePath.Replace('\\', '/'), null, root, Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("tar", "xjf " + packagePath.Replace('\\', '/'), null, root, Utilities.RunOptions.ConsoleLogOutput);
// Use separate build directory // Use separate build directory
@@ -166,7 +167,7 @@ namespace Flax.Deps.Dependencies
// Get the source // Get the source
var packagePath = Path.Combine(root, "package.zip"); var packagePath = Path.Combine(root, "package.zip");
File.Delete(packagePath); File.Delete(packagePath);
Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath); Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath, noSSL);
if (Platform.BuildTargetPlatform == TargetPlatform.Windows) if (Platform.BuildTargetPlatform == TargetPlatform.Windows)
{ {
var sevenZip = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "7-Zip", "7z.exe"); var sevenZip = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "7-Zip", "7z.exe");
@@ -206,7 +207,7 @@ namespace Flax.Deps.Dependencies
// Get the source // Get the source
var packagePath = Path.Combine(root, "package.zip"); var packagePath = Path.Combine(root, "package.zip");
File.Delete(packagePath); File.Delete(packagePath);
Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath); Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath, noSSL);
Utilities.Run("tar", "xjf " + packagePath.Replace('\\', '/'), null, root, Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("tar", "xjf " + packagePath.Replace('\\', '/'), null, root, Utilities.RunOptions.ConsoleLogOutput);
// Use separate build directory // Use separate build directory
@@ -241,7 +242,7 @@ namespace Flax.Deps.Dependencies
var packagePath = Path.Combine(root, "package.zip"); var packagePath = Path.Combine(root, "package.zip");
if (!File.Exists(packagePath)) if (!File.Exists(packagePath))
{ {
Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath); Downloader.DownloadFileFromUrlToPath("https://openal-soft.org/openal-releases/openal-soft-" + version + ".tar.bz2", packagePath, noSSL);
Utilities.Run("tar", "xjf " + packagePath.Replace('\\', '/'), null, root, Utilities.RunOptions.ConsoleLogOutput); Utilities.Run("tar", "xjf " + packagePath.Replace('\\', '/'), null, root, Utilities.RunOptions.ConsoleLogOutput);
} }

View File

@@ -14,20 +14,20 @@ namespace Flax.Deps
/// </summary> /// </summary>
static class Downloader static class Downloader
{ {
private static bool IgnoreSSL = false; private static bool NoSSL = false;
private const string GoogleDriveDomain = "drive.google.com"; private const string GoogleDriveDomain = "drive.google.com";
private const string GoogleDriveDomain2 = "https://drive.google.com"; private const string GoogleDriveDomain2 = "https://drive.google.com";
// Normal example: FileDownloader.DownloadFileFromURLToPath( "http://example.com/file/download/link", @"C:\file.txt" ); // Normal example: FileDownloader.DownloadFileFromURLToPath( "http://example.com/file/download/link", @"C:\file.txt" );
// Drive example: FileDownloader.DownloadFileFromURLToPath( "http://drive.google.com/file/d/FILEID/view?usp=sharing", @"C:\file.txt" ); // Drive example: FileDownloader.DownloadFileFromURLToPath( "http://drive.google.com/file/d/FILEID/view?usp=sharing", @"C:\file.txt" );
public static FileInfo DownloadFileFromUrlToPath(string url, string path) public static FileInfo DownloadFileFromUrlToPath(string url, string path, bool noSSL = false)
{ {
Log.Info(string.Format("Downloading {0} to {1}", url, path)); Log.Info(string.Format("Downloading {0} to {1}", url, path));
if (File.Exists(path)) if (File.Exists(path))
File.Delete(path); File.Delete(path);
if (url.StartsWith(GoogleDriveDomain) || url.StartsWith(GoogleDriveDomain2)) if (url.StartsWith(GoogleDriveDomain) || url.StartsWith(GoogleDriveDomain2))
return DownloadGoogleDriveFileFromUrlToPath(url, path); return DownloadGoogleDriveFileFromUrlToPath(url, path, noSSL);
return DownloadFileFromUrlToPath(url, path, null); return DownloadFileFromUrlToPath(url, path, null, noSSL);
} }
private static FileInfo DownloadFileFromUrlToPathRaw(string url, string path, HttpClient httpClient) private static FileInfo DownloadFileFromUrlToPathRaw(string url, string path, HttpClient httpClient)
@@ -49,16 +49,14 @@ namespace Flax.Deps
return new FileInfo(path); return new FileInfo(path);
} }
private static FileInfo DownloadFileFromUrlToPath(string url, string path, HttpClient httpClient) private static FileInfo DownloadFileFromUrlToPath(string url, string path, HttpClient httpClient, bool noSSL)
{ {
try try
{ {
if (httpClient == null) if (httpClient == null)
{ {
using (httpClient = GetHttpClient()) using (httpClient = GetHttpClient(noSSL))
{
return DownloadFileFromUrlToPathRaw(url, path, httpClient); return DownloadFileFromUrlToPathRaw(url, path, httpClient);
}
} }
return DownloadFileFromUrlToPathRaw(url, path, httpClient); return DownloadFileFromUrlToPathRaw(url, path, httpClient);
} }
@@ -126,12 +124,12 @@ namespace Flax.Deps
// Downloading large files from Google Drive prompts a warning screen and // Downloading large files from Google Drive prompts a warning screen and
// requires manual confirmation. Consider that case and try to confirm the download automatically // requires manual confirmation. Consider that case and try to confirm the download automatically
// if warning prompt occurs // if warning prompt occurs
private static FileInfo DownloadGoogleDriveFileFromUrlToPath(string url, string path) private static FileInfo DownloadGoogleDriveFileFromUrlToPath(string url, string path, bool noSSL)
{ {
// You can comment the statement below if the provided url is guaranteed to be in the following format: // You can comment the statement below if the provided url is guaranteed to be in the following format:
// https://drive.google.com/uc?id=FILEID&export=download // https://drive.google.com/uc?id=FILEID&export=download
url = GetGoogleDriveDownloadLinkFromUrl(url); url = GetGoogleDriveDownloadLinkFromUrl(url);
using (var httpClient = GetHttpClient()) using (var httpClient = GetHttpClient(noSSL))
{ {
FileInfo downloadedFile; FileInfo downloadedFile;
@@ -139,7 +137,7 @@ namespace Flax.Deps
// but works in the second attempt // but works in the second attempt
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
downloadedFile = DownloadFileFromUrlToPath(url, path, httpClient); downloadedFile = DownloadFileFromUrlToPath(url, path, httpClient, noSSL);
if (downloadedFile == null) if (downloadedFile == null)
return null; return null;
@@ -172,7 +170,7 @@ namespace Flax.Deps
url = "https://drive.google.com" + content.Substring(linkIndex, linkEnd - linkIndex).Replace("&amp;", "&"); url = "https://drive.google.com" + content.Substring(linkIndex, linkEnd - linkIndex).Replace("&amp;", "&");
} }
downloadedFile = DownloadFileFromUrlToPath(url, path, httpClient); downloadedFile = DownloadFileFromUrlToPath(url, path, httpClient, noSSL);
return downloadedFile; return downloadedFile;
} }
} }
@@ -211,11 +209,10 @@ namespace Flax.Deps
return string.Format("https://drive.google.com/uc?id={0}&export=download", url.Substring(index, closingIndex - index)); return string.Format("https://drive.google.com/uc?id={0}&export=download", url.Substring(index, closingIndex - index));
} }
private static HttpClient GetHttpClient() private static HttpClient GetHttpClient(bool noSSL)
{ {
if (IgnoreSSL) if (noSSL || NoSSL)
{ {
Log.Warning("Accessing HTTP with SSL certificate validation disabled!");
var handler = new HttpClientHandler(); var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true; handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true;

View File

@@ -342,6 +342,8 @@ namespace Flax.Build.Projects.VisualStudioCode
json.BeginArray("args"); json.BeginArray("args");
{ {
if (configuration.Platform == TargetPlatform.Linux || configuration.Platform == TargetPlatform.Mac)
json.AddUnnamedField("-std");
json.AddUnnamedField("-project"); json.AddUnnamedField("-project");
json.AddUnnamedField(buildToolWorkspace); json.AddUnnamedField(buildToolWorkspace);
json.AddUnnamedField("-skipCompile"); json.AddUnnamedField("-skipCompile");
@@ -395,6 +397,8 @@ namespace Flax.Build.Projects.VisualStudioCode
json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", editorFolder, configuration.ConfigurationName, "FlaxEditor")); json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", editorFolder, configuration.ConfigurationName, "FlaxEditor"));
json.BeginArray("args"); json.BeginArray("args");
{ {
if (configuration.Platform == TargetPlatform.Linux || configuration.Platform == TargetPlatform.Mac)
json.AddUnnamedField("-std");
json.AddUnnamedField("-project"); json.AddUnnamedField("-project");
json.AddUnnamedField(buildToolWorkspace); json.AddUnnamedField(buildToolWorkspace);
json.AddUnnamedField("-skipCompile"); json.AddUnnamedField("-skipCompile");