91 Commits

Author SHA1 Message Date
a38cc4d5cb Fix cloning SDL repository
Some checks are pending
Build Android / Game (Android, Release ARM64) (push) Waiting to run
Build iOS / Game (iOS, Release ARM64) (push) Waiting to run
Build Linux / Editor (Linux, Development x64) (push) Waiting to run
Build Linux / Game (Linux, Release x64) (push) Waiting to run
Build macOS / Editor (Mac, Development ARM64) (push) Waiting to run
Build macOS / Game (Mac, Release ARM64) (push) Waiting to run
Build Windows / Editor (Windows, Development x64) (push) Waiting to run
Build Windows / Game (Windows, Release x64) (push) Waiting to run
Cooker / Cook (Mac) (push) Waiting to run
Tests / Tests (Linux) (push) Waiting to run
Tests / Tests (Windows) (push) Waiting to run
2025-01-28 22:41:45 +02:00
1528d458d9 Fix text input not working on X11 2025-01-28 22:08:17 +02:00
9e937776ac Apply patches to rapidjson 2025-01-28 22:08:16 +02:00
a8aebdd01f Update rapidjson to latest version
Commit d621dc9e9c77f81e5c8a35b8dcc16dcd63351321 in Tencent/rapidjson
2025-01-28 22:08:16 +02:00
998ed87029 Fix button latching on Windows after drag and drop operation 2025-01-28 22:08:16 +02:00
279b3f8d9a Implement new window dragging system 2025-01-28 22:08:15 +02:00
738a506b6d Fix mouse resetting issues after ending relative mode 2025-01-28 22:08:15 +02:00
0ddecdda1f Fix frame stutter when window is focused 2025-01-28 22:08:14 +02:00
94a22907e2 Fix error when docking to sides of tabbed panel 2025-01-28 22:08:14 +02:00
d22a0aad0c Cleanup Linux SDL implementation 2025-01-28 22:08:14 +02:00
9e035f3818 Support compiling third party library C files as C code 2025-01-28 22:08:13 +02:00
99a810458a Implement Wayland protocols module and file generation 2025-01-28 22:08:13 +02:00
2806578126 Fix mouse warping after ending relative mode 2025-01-28 22:08:13 +02:00
882e9a6623 Add git fetch method for dependencies 2025-01-28 22:08:12 +02:00
14c156e351 Fix window ShowInTaskbar setting 2025-01-28 22:08:12 +02:00
cd2151332e Fix various issues with child window positioning 2025-01-28 22:08:12 +02:00
53bbca3779 Add Window.IsAlwaysOnTop property 2025-01-28 22:08:11 +02:00
51f4ac467e Use SDL locale 2025-01-28 22:08:11 +02:00
81427a7f9e Allow window with single tab to be dragged from tab area 2025-01-28 22:08:10 +02:00
faadfb28b3 Fix ValueBox mouse position resetting after releasing the button 2025-01-28 22:08:10 +02:00
6bfe0bed35 Fix SDL build process on Linux 2025-01-28 22:08:10 +02:00
6e4d5b853f Update SDL to 3.2.0 2025-01-28 22:08:09 +02:00
0ebe23b482 _sdl binary 2025-01-28 22:08:09 +02:00
abbde5861a Update SDL3 binaries 2025-01-28 22:08:08 +02:00
b78d4349a7 _lfsconfig 2025-01-28 22:08:08 +02:00
3c1d3234b8 Force cursor to center of Game Window when tab handle is clicked 2025-01-28 22:08:07 +02:00
Chandler Cox
79baaae8e7 Fix rotation using SDL 2025-01-28 22:08:07 +02:00
79289662ed Fix Linux compilation without SDL 2025-01-28 22:08:07 +02:00
89a2985ad8 Fix compilation 2025-01-28 22:08:06 +02:00
1f0a521a87 Update SDL3 2025-01-28 22:08:06 +02:00
8a0e43c38c Fix compilation issues 2025-01-28 22:08:06 +02:00
ac9022f585 Fix windows not being hidden initially 2025-01-28 22:08:05 +02:00
314dbbbeaf Fix parent window position handling with popup/tooltip windows 2025-01-28 22:08:05 +02:00
f13e09910d Fix compilation errors in other platforms 2025-01-28 22:08:04 +02:00
67b9511afe Fix CI for Linux 2025-01-28 22:08:04 +02:00
510c477468 Prevent building with SDL in unsupported platforms 2025-01-28 22:08:04 +02:00
697fcc18ab Fallback to X11 message box implementation when SDL fails 2025-01-28 22:08:03 +02:00
89ff08b3f2 Fix popup and context menus not working on Wayland 2025-01-28 22:08:03 +02:00
9417585cd9 Hide warnings for unsupported SDL operations on Wayland 2025-01-28 22:08:03 +02:00
f794bb5455 Log a warning for not implemented Wayland functionality 2025-01-28 22:08:02 +02:00
bb7a5326cd Fix compilation in Linux 2025-01-28 22:08:02 +02:00
a998b2a44e Enable warning sound in question dialogs 2025-01-28 22:08:02 +02:00
a69eb4296f Enable modern Windows dialog boxes 2025-01-28 22:08:01 +02:00
727af5a5b9 Implement relative mouse mode (raw input) for SDL platform 2025-01-28 22:08:01 +02:00
d545dd8219 Add flag for Window types 2025-01-28 22:08:00 +02:00
29e385ab4b Enable native windowing system settings with SDL platform 2025-01-28 22:08:00 +02:00
5c63e30b84 Add command-line switches to force X11 and Wayland SDL drivers 2025-01-28 22:08:00 +02:00
5187c677f1 Implement SDL platform, windowing and input handling 2025-01-28 22:07:59 +02:00
1d43314efd Refactor application window class name 2025-01-28 22:07:59 +02:00
91ef8c69db Move Window related enums to separate header file 2025-01-28 22:07:59 +02:00
f24251af82 Refactor Windows drag and drop implementation 2025-01-28 22:07:58 +02:00
ed6e0138e6 Refactor ScreenUtilities 2025-01-28 22:07:58 +02:00
4362cdb396 Add more helper methods for managing Git repos 2025-01-28 22:07:57 +02:00
8146680b53 Fix centered window location on X11 2025-01-28 22:07:57 +02:00
27aa2cfa1f Fix initial position of Tooltips 2025-01-28 22:07:57 +02:00
Wojtek Figat
1475075b00 Merge branch 'GoaLitiuM-dotnet_refasm_version_fix' 2025-01-27 20:29:16 +01:00
Wojtek Figat
702564366d Merge branch 'dotnet_refasm_version_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-dotnet_refasm_version_fix 2025-01-27 20:29:12 +01:00
Wojtek Figat
e2fd3891d1 Fix regression in curve keyframes editing
#3179
2025-01-27 20:19:35 +01:00
f54e961f11 Update .NET compilation instructions for Arch 2025-01-27 20:35:56 +02:00
Wojtek Figat
aabd70fbe7 Fix code project files generation to properly handle path slashes and ignore binary modules without exports
#3086
2025-01-27 19:35:27 +01:00
428ebf7fd7 Fix .NET runtime and SDK compilation issues with newer runtime 2025-01-27 20:06:06 +02:00
Wojtek Figat
72f16d738f Merge branch 'Tryibion-draw-anchors' 2025-01-27 12:41:01 +01:00
Wojtek Figat
475818554d Fix error in editor when sliding value 2025-01-27 12:40:55 +01:00
Wojtek Figat
8ebb3a3215 Merge branch 'draw-anchors' of https://github.com/Tryibion/FlaxEngine into Tryibion-draw-anchors 2025-01-27 12:12:24 +01:00
Wojtek Figat
2085a0bf25 Merge branch 'amir9480-fix_issue_3083' 2025-01-27 11:58:46 +01:00
Wojtek Figat
d829461def Merge branch 'fix_issue_3083' of https://github.com/amir9480/FlaxEngine into amir9480-fix_issue_3083 2025-01-27 11:58:13 +01:00
Wojtek Figat
2d169fdcd8 Merge branch 'Tryibion-particle-rotate-shape' 2025-01-27 11:43:04 +01:00
Wojtek Figat
53ba5968fd Fix missing default value usage on GPU particle shape rotation and simplify CPU code
#3104
2025-01-27 11:42:59 +01:00
Wojtek Figat
cc735a1b6a Merge branch 'particle-rotate-shape' of https://github.com/Tryibion/FlaxEngine into Tryibion-particle-rotate-shape 2025-01-27 11:35:26 +01:00
Wojtek Figat
970af7bdc8 Attempt to fix recent Github CD failing 2025-01-27 11:35:10 +01:00
Wojtek Figat
2ff6a6dd9a Merge branch 'Tryibion-clamp-anchors' 2025-01-26 22:05:40 +01:00
Wojtek Figat
ae3149c9c0 Merge branch 'clamp-anchors' of https://github.com/Tryibion/FlaxEngine into Tryibion-clamp-anchors 2025-01-26 22:05:36 +01:00
Wojtek Figat
1a1bd56802 Merge branch 'GoaLitiuM-sln_folder_fix' 2025-01-26 22:03:11 +01:00
Wojtek Figat
25b566b348 Merge branch 'sln_folder_fix' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-sln_folder_fix 2025-01-26 22:02:58 +01:00
Wojtek Figat
4fb95a704a Merge branch 'Tryibion-file-path-drag-dop' 2025-01-26 21:59:04 +01:00
Wojtek Figat
5f09ef4c1f Merge branch 'file-path-drag-dop' of https://github.com/Tryibion/FlaxEngine into Tryibion-file-path-drag-dop 2025-01-26 21:58:34 +01:00
Wojtek Figat
7bc099c32c Merge branch 'Tryibion-content-item-text-scale' 2025-01-25 11:09:36 +01:00
Wojtek Figat
9a59d0c5ed Merge branch 'content-item-text-scale' of https://github.com/Tryibion/FlaxEngine into Tryibion-content-item-text-scale 2025-01-25 10:05:54 +01:00
Wojtek Figat
275ca296fa Fix editor orthographic viewport in top or bottom view
#3169
2025-01-25 00:38:51 +01:00
Wojtek Figat
57af076c8d Merge branch 'Tryibion-is-active-null-check' 2025-01-24 23:51:48 +01:00
Chandler Cox
f905c49f0b Change content item text scale with content view scale. 2025-01-24 13:02:05 -06:00
Chandler Cox
c72fac335f Check for null in Actor node IsActive. 2025-01-23 21:28:09 -06:00
Chandler Cox
030befdcaa Rename dropped method. 2025-01-22 21:47:28 -06:00
Chandler Cox
3a591577ad Add drag drop to FilePathEditor 2025-01-22 21:46:21 -06:00
Chandler Cox
8f9eaddbe5 Add anchor and pivot drawing for UI Gizmo. 2025-01-20 21:08:47 -06:00
Amir Alizadeh
ec11a79f55 Add raycast support to the ContainerControl 2025-01-19 23:55:56 +03:30
Amir Alizadeh
55fd198102 Add raycast-first priority to the UIEditorGizmo 2025-01-19 23:55:23 +03:30
Chandler Cox
425699c4b0 Clamp control anchors betwen 0 and 1. 2025-01-19 13:51:50 -06:00
af3badaeef Fix Visual Studio solution nested project names on Unix systems 2025-01-14 19:08:09 +02:00
Chandler Cox
873491eca2 Fix CPU particle code. 2024-12-12 21:07:00 -06:00
Chandler Cox
3ba1ebb847 Add rotate position shape as particle module. 2024-12-12 20:41:11 -06:00
22 changed files with 309 additions and 59 deletions

View File

@@ -7,6 +7,7 @@ on:
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: false
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=10 -c lfs.transfer.maxretries=2'
jobs:
@@ -20,7 +21,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git lfs pull
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -53,7 +54,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git lfs pull
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -83,7 +84,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git lfs pull
GIT_TRACE=1 GIT_TRANSFER_TRACE=1 git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Install dependencies
run: |
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
@@ -114,7 +115,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git lfs pull
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Install dependencies
run: |
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
@@ -147,7 +148,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git lfs pull
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET
@@ -175,7 +176,7 @@ jobs:
- name: Checkout LFS
run: |
git lfs version
git lfs pull
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
- name: Setup Vulkan
uses: ./.github/actions/vulkan
- name: Setup .NET

View File

@@ -31,7 +31,7 @@ Follow the instructions below to compile and run the engine from source.
* Install Visual Studio 2022 or newer
* Install Windows 8.1 SDK or newer (via Visual Studio Installer)
* Install Microsoft Visual C++ 2015 v140 toolset or newer (via Visual Studio Installer)
* Install .NET 8 SDK for **Windows x64** (via Visual Studio Installer or [from web](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install .NET 8 or 9 SDK for **Windows x64** (via Visual Studio Installer or [from web](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install Git with LFS
* Clone repo (with LFS)
* Run **GenerateProjectFiles.bat**
@@ -44,8 +44,9 @@ Follow the instructions below to compile and run the engine from source.
## Linux
* Install Visual Studio Code
* Install .NET 8 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install .NET 8 or 9 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Ubuntu: `sudo apt 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`
* Arch: `sudo pacman -S spirv-tools vulkan-headers vulkan-tools vulkan-validation-layers`
@@ -67,12 +68,12 @@ Follow the instructions below to compile and run the engine from source.
## Mac
* Install XCode
* Install .NET 8 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install .NET 8 or 9 SDK ([https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0))
* Install Vulkan SDK ([https://vulkan.lunarg.com/](https://vulkan.lunarg.com/))
* Clone repo (with LFS)
* Run `GenerateProjectFiles.command`
* Open workspace with XCode or Visual Studio Code
* Build and run (configuration `Editor.Mac.Development`)
* Build and run (configuration `Editor.Mac.Development`)
#### Troubleshooting

View File

@@ -750,7 +750,8 @@ namespace FlaxEditor.Content
// Draw short name
Render2D.PushClip(ref textRect);
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, 0.95f);
var scale = 0.95f * view.ViewScale;
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, scale);
Render2D.PopClip();
if (IsBeingCut)

View File

@@ -883,7 +883,7 @@ namespace FlaxEditor.CustomEditors
/// </summary>
protected virtual void ClearToken()
{
ParentEditor.ClearToken();
ParentEditor?.ClearToken();
}
}
}

View File

@@ -4,6 +4,7 @@ using System;
using System.Linq;
using FlaxEditor.Content;
using FlaxEditor.GUI;
using FlaxEditor.GUI.Drag;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
@@ -156,6 +157,17 @@ namespace FlaxEditor.CustomEditors.Editors
private Rectangle DropdownRect => new Rectangle(Width - DropdownIconSize - DropdownIconMargin, DropdownIconMargin, DropdownIconSize, DropdownIconSize);
public Action ShowPicker;
public Action<ContentItem> OnAssetDropped;
private DragItems _dragItems;
private DragHandlers _dragHandlers;
private bool _hasValidDragOver;
private Func<ContentItem, bool> _validate;
public void SetValidationMethod(Func<ContentItem, bool> validate)
{
_validate = validate;
}
public override void Draw()
{
@@ -164,6 +176,14 @@ namespace FlaxEditor.CustomEditors.Editors
var style = FlaxEngine.GUI.Style.Current;
var dropdownRect = DropdownRect;
Render2D.DrawSprite(style.ArrowDown, dropdownRect, Enabled ? (DropdownRect.Contains(PointFromWindow(RootWindow.MousePosition)) ? style.BorderSelected : style.Foreground) : style.ForegroundDisabled);
// Check if drag is over
if (IsDragOver && _hasValidDragOver)
{
var bounds = new Rectangle(Float2.Zero, Size);
Render2D.FillRectangle(bounds, style.Selection);
Render2D.DrawRectangle(bounds, style.SelectionBorder);
}
}
public override bool OnMouseDown(Float2 location, MouseButton button)
@@ -207,6 +227,68 @@ namespace FlaxEditor.CustomEditors.Editors
return result;
}
}
private DragDropEffect DragEffect => _hasValidDragOver ? DragDropEffect.Move : DragDropEffect.None;
/// <inheritdoc />
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
{
base.OnDragEnter(ref location, data);
// Ensure to have valid drag helpers (uses lazy init)
if (_dragItems == null)
_dragItems = new DragItems(ValidateDragAsset);
if (_dragHandlers == null)
{
_dragHandlers = new DragHandlers
{
_dragItems,
};
}
_hasValidDragOver = _dragHandlers.OnDragEnter(data) != DragDropEffect.None;
return DragEffect;
}
private bool ValidateDragAsset(ContentItem contentItem)
{
// Load or get asset
return _validate?.Invoke(contentItem) ?? false;
}
/// <inheritdoc />
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
{
base.OnDragMove(ref location, data);
return DragEffect;
}
/// <inheritdoc />
public override void OnDragLeave()
{
_hasValidDragOver = false;
_dragHandlers.OnDragLeave();
base.OnDragLeave();
}
/// <inheritdoc />
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
{
var result = DragEffect;
base.OnDragDrop(ref location, data);
if (_dragItems.HasValidDrag)
{
OnAssetDropped(_dragItems.Objects[0]);
}
return result;
}
}
private TextBoxWithPicker _textBox;
@@ -221,13 +303,21 @@ namespace FlaxEditor.CustomEditors.Editors
{
if (HasDifferentTypes)
return;
_validator = new AssetPickerValidator(ScriptType.Null);
_textBox = layout.Custom<TextBoxWithPicker>().CustomControl;
_textBox.ShowPicker = OnShowPicker;
_textBox.OnAssetDropped = OnItemDropped;
_textBox.EditEnd += OnEditEnd;
_validator = new AssetPickerValidator(ScriptType.Null);
_textBox.SetValidationMethod(_validator.IsValid);
AssetRefEditor.ApplyAssetReferenceAttribute(Values, out _, _validator);
}
private void OnItemDropped(ContentItem item)
{
SetPickerPath(item);
}
private void OnShowPicker()
{
if (_validator.AssetType != ScriptType.Null)

View File

@@ -641,7 +641,68 @@ namespace FlaxEditor
DrawControlWidget(uiControl, ref eu, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, -1), CursorType.SizeNS);
DrawControlWidget(uiControl, ref eb, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, 1), CursorType.SizeNS);
// TODO: draw anchors
// Draw pivot
var pivotSize = 8.0f;
if (viewScale < 0.7f)
pivotSize *= viewScale;
var pivotX = Mathf.Remap(control.Pivot.X, 0, 1, bounds.Location.X, bounds.Location.X + bounds.Width);
var pivotY = Mathf.Remap(control.Pivot.Y, 0, 1, bounds.Location.Y, bounds.Location.Y + bounds.Height);
var pivotLoc = control.PointToParent(this, new Float2(pivotX, pivotY));
var pivotRect = new Rectangle(pivotLoc - pivotSize * 0.5f, new Float2(pivotSize));
var pivotColor = options.UIPivotColor;
Render2D.FillRectangle(pivotRect, pivotColor);
// Draw anchors
var controlParent = control.Parent;
if (controlParent != null)
{
var parentBounds = controlParent.EditorBounds;
var anchorMin = control.AnchorMin;
var anchorMax = control.AnchorMax;
var newMinX = Mathf.Remap(anchorMin.X, 0, 1, parentBounds.UpperLeft.X, parentBounds.UpperRight.X);
var newMinY = Mathf.Remap(anchorMin.Y, 0, 1, parentBounds.UpperLeft.Y, parentBounds.LowerLeft.Y);
var newMaxX = Mathf.Remap(anchorMax.X, 0, 1, parentBounds.UpperLeft.X, parentBounds.UpperRight.X);
var newMaxY = Mathf.Remap(anchorMax.Y, 0, 1, parentBounds.UpperLeft.Y, parentBounds.LowerLeft.Y);
var anchorUpperLeft = controlParent.PointToParent(this, new Float2(newMinX, newMinY));
var anchorUpperRight = controlParent.PointToParent(this, new Float2(newMaxX, newMinY));
var anchorLowerLeft = controlParent.PointToParent(this, new Float2(newMinX, newMaxY));
var anchorLowerRight = controlParent.PointToParent(this, new Float2(newMaxX, newMaxY));
var anchorRectSize = 8.0f;
if (viewScale < 0.7f)
anchorRectSize *= viewScale;
// Make anchor rects and rotate if parent is rotated.
var parentRotation = controlParent.Rotation * Mathf.DegreesToRadians;
var rect1Axis = new Float2(-1, -1);
var rect1 = new Rectangle(anchorUpperLeft +
new Float2(anchorRectSize * rect1Axis.X * Mathf.Cos(parentRotation) - anchorRectSize * rect1Axis.Y * Mathf.Sin(parentRotation),
anchorRectSize * rect1Axis.Y * Mathf.Cos(parentRotation) + anchorRectSize * rect1Axis.X * Mathf.Sin(parentRotation)) - anchorRectSize * 0.5f, new Float2(anchorRectSize));
var rect2Axis = new Float2(1, -1);
var rect2 = new Rectangle(anchorUpperRight +
new Float2(anchorRectSize * rect2Axis.X * Mathf.Cos(parentRotation) - anchorRectSize * rect2Axis.Y * Mathf.Sin(parentRotation),
anchorRectSize * rect2Axis.Y * Mathf.Cos(parentRotation) + anchorRectSize * rect2Axis.X * Mathf.Sin(parentRotation)) - anchorRectSize * 0.5f, new Float2(anchorRectSize));
var rect3Axis = new Float2(-1, 1);
var rect3 = new Rectangle(anchorLowerLeft +
new Float2(anchorRectSize * rect3Axis.X * Mathf.Cos(parentRotation) - anchorRectSize * rect3Axis.Y * Mathf.Sin(parentRotation),
anchorRectSize * rect3Axis.Y * Mathf.Cos(parentRotation) + anchorRectSize * rect3Axis.X * Mathf.Sin(parentRotation)) - anchorRectSize * 0.5f, new Float2(anchorRectSize));
var rect4Axis = new Float2(1, 1);
var rect4 = new Rectangle(anchorLowerRight +
new Float2(anchorRectSize * rect4Axis.X * Mathf.Cos(parentRotation) - anchorRectSize * rect4Axis.Y * Mathf.Sin(parentRotation),
anchorRectSize * rect4Axis.Y * Mathf.Cos(parentRotation) + anchorRectSize * rect4Axis.X * Mathf.Sin(parentRotation)) - anchorRectSize * 0.5f, new Float2(anchorRectSize));
var rectColor = options.UIAnchorColor;
Render2D.DrawLine(anchorUpperLeft, anchorUpperRight, rectColor);
Render2D.DrawLine(anchorUpperRight, anchorLowerRight, rectColor);
Render2D.DrawLine(anchorLowerRight, anchorLowerLeft, rectColor);
Render2D.DrawLine(anchorLowerLeft, anchorUpperLeft, rectColor);
Render2D.FillRectangle(rect1, rectColor);
Render2D.FillRectangle(rect2, rectColor);
Render2D.FillRectangle(rect3, rectColor);
Render2D.FillRectangle(rect4, rectColor);
}
}
}
@@ -651,8 +712,7 @@ namespace FlaxEditor
var control = uiControl.Control;
var rotation = control.Rotation;
var rotationInRadians = rotation * Mathf.DegreesToRadians;
var rect = new Rectangle(
(pos +
var rect = new Rectangle((pos +
new Float2(resizeAxis.X * Mathf.Cos(rotationInRadians) - resizeAxis.Y * Mathf.Sin(rotationInRadians),
resizeAxis.Y * Mathf.Cos(rotationInRadians) + resizeAxis.X * Mathf.Sin(rotationInRadians)) * 10 * scale) - size * 0.5f,
size);
@@ -714,16 +774,15 @@ namespace FlaxEditor
private bool RayCastControl(ref Float2 location, out Control hit)
{
#if false
// Raycast only controls with content (eg. skips transparent panels)
return RayCastChildren(ref location, out hit);
#else
// Find any control under mouse (hierarchical)
hit = GetChildAtRecursive(location);
// First, raycast only controls with content (eg. skips transparent panels)
RayCastChildren(ref location, out hit);
// If raycast failed, then find any control under mouse (hierarchical)
hit = hit ?? GetChildAtRecursive(location);
if (hit is View || hit is CanvasContainer)
hit = null;
return hit != null;
#endif
}
private UIControlNode FindUIControlNode(Control control)

View File

@@ -39,6 +39,20 @@ namespace FlaxEditor.Options
[EditorDisplay("UI Gizmo", "UI Control Outline Size"), EditorOrder(103), Tooltip("The size of the selection outline for UI controls.")]
public float UISelectionOutlineSize { get; set; } = 2.0f;
/// <summary>
/// Gets or sets the pivot color for the UI Gizmo.
/// </summary>
[DefaultValue(typeof(Color), "0.0,0.5725,0.8,0.5")]
[EditorDisplay("UI Gizmo", "Pivot Color"), EditorOrder(103), Tooltip("The color of the pivot for the UI Gizmo.")]
public Color UIPivotColor { get; set; } = new Color(0.0f, 0.5725f, 0.8f, 0.5f);
/// <summary>
/// Gets or sets the anchor color for the UI Gizmo.
/// </summary>
[DefaultValue(typeof(Color), "0.8392,0.8471,0.8706,0.5")]
[EditorDisplay("UI Gizmo", "Anchor Color"), EditorOrder(103), Tooltip("The color of the anchors for the UI Gizmo.")]
public Color UIAnchorColor { get; set; } = new Color(0.8392f, 0.8471f, 0.8706f, 0.5f);
/// <summary>
/// Gets or sets the transform gizmo size.
/// </summary>

View File

@@ -215,10 +215,10 @@ namespace FlaxEditor.SceneGraph
public override bool CanDuplicate => (_actor.HideFlags & HideFlags.HideInHierarchy) == 0;
/// <inheritdoc />
public override bool IsActive => _actor.IsActive;
public override bool IsActive => _actor?.IsActive ?? false;
/// <inheritdoc />
public override bool IsActiveInHierarchy => _actor.IsActiveInHierarchy;
public override bool IsActiveInHierarchy => _actor?.IsActiveInHierarchy ?? false;
/// <inheritdoc />
public override int OrderInParent

View File

@@ -924,6 +924,25 @@ namespace FlaxEditor.Surface.Archetypes
(int)ModuleType.Initialize,
},
},
new NodeArchetype
{
TypeID = 216,
Create = CreateParticleModuleNode,
Title = "Rotate Position Shape",
Description = "Rotate the shape.",
Flags = DefaultModuleFlags,
Size = new Float2(200, 1 * Surface.Constants.LayoutOffsetY),
DefaultValues = new object[]
{
true,
(int)ModuleType.Initialize,
Quaternion.Identity,
},
Elements = new []
{
NodeElementArchetype.Factory.Input(-0.5f, "Rotation", true, typeof(Quaternion), 0, 2),
}
},
GetParticleAttribute(ModuleType.Initialize, 250, "Set Position", "Sets the particle position", typeof(Float3), Float3.Zero),
GetParticleAttribute(ModuleType.Initialize, 251, "Set Lifetime", "Sets the particle lifetime (in seconds)", typeof(float), 10.0f),
GetParticleAttribute(ModuleType.Initialize, 252, "Set Age", "Sets the particle age (in seconds)", typeof(float), 0.0f),

View File

@@ -135,6 +135,8 @@ namespace FlaxEditor.Viewport.Cameras
float a = Mathf.Saturate(progress);
a = a * a * a;
var targetTransform = Transform.Lerp(_startMove, _endMove, a);
if (progress >= 1.0f)
targetTransform = _endMove; // Be precise
targetTransform.Scale = Vector3.Zero;
Viewport.ViewPosition = targetTransform.Translation;
Viewport.ViewOrientation = targetTransform.Orientation;

View File

@@ -233,13 +233,11 @@ namespace FlaxEditor.Viewport
{
if (Mathf.Abs(_movementSpeed - _maxMovementSpeed) < Mathf.Epsilon || Mathf.Abs(_movementSpeed - _minMovementSpeed) < Mathf.Epsilon)
return "{0:0.##}";
if (_movementSpeed < 10.0f)
return "{0:0.00}";
else if (_movementSpeed < 100.0f)
if (_movementSpeed < 100.0f)
return "{0:0.0}";
else
return "{0:#}";
return "{0:#}";
}
}
@@ -290,11 +288,6 @@ namespace FlaxEditor.Viewport
/// </summary>
public Float2 MousePositionDelta => _mouseDelta;
/// <summary>
/// Camera's pitch angle clamp range (in degrees).
/// </summary>
public Float2 CamPitchAngles = new Float2(-88, 88);
/// <summary>
/// Gets the view transform.
/// </summary>
@@ -330,7 +323,7 @@ namespace FlaxEditor.Viewport
get => Float3.Forward * ViewOrientation;
set
{
var right = Float3.Cross(value, Float3.Up);
var right = Mathf.Abs(Float3.Dot(value, Float3.Up)) < 1.0f - Mathf.Epsilon ? Float3.Cross(value, Float3.Up) : Float3.Forward;
var up = Float3.Cross(right, value);
ViewOrientation = Quaternion.LookRotation(value, up);
}
@@ -380,7 +373,11 @@ namespace FlaxEditor.Viewport
public float Pitch
{
get => _pitch;
set => _pitch = Mathf.Clamp(value, CamPitchAngles.X, CamPitchAngles.Y);
set
{
var pitchLimit = _isOrtho ? new Float2(-90, 90) : new Float2(-88, 88);
_pitch = Mathf.Clamp(value, pitchLimit.X, pitchLimit.Y);
}
}
/// <summary>
@@ -1160,8 +1157,7 @@ namespace FlaxEditor.Viewport
/// <param name="orientation">The orientation.</param>
protected void OrientViewport(Quaternion orientation)
{
var quat = orientation;
OrientViewport(ref quat);
OrientViewport(ref orientation);
}
/// <summary>
@@ -1372,7 +1368,7 @@ namespace FlaxEditor.Viewport
{
var direction = ViewDirection;
var target = position + direction;
var right = Float3.Normalize(Float3.Cross(Float3.Up, direction));
var right = Mathf.Abs(Float3.Dot(direction, Float3.Up)) < 1.0f - Mathf.Epsilon ? Float3.Normalize(Float3.Cross(Float3.Up, direction)) : Float3.Forward;
var up = Float3.Normalize(Float3.Cross(direction, right));
Matrix.LookAt(ref position, ref target, ref up, out result);
}

View File

@@ -476,9 +476,9 @@ void Spline::GetKeyframes(MArray* data)
Platform::MemoryCopy(MCore::Array::GetAddress(data), Curve.GetKeyframes().Get(), sizeof(Keyframe) * Curve.GetKeyframes().Count());
}
void Spline::SetKeyframes(MArray* data)
void Spline::SetKeyframes(MArray* data, int32 keySize)
{
Curve = Span<byte>((const byte*)MCore::Array::GetAddress(data), MCore::Array::GetLength(data));
Curve = Span<byte>(MCore::Array::GetAddress<byte>(data), keySize * MCore::Array::GetLength(data));
UpdateSpline();
}

View File

@@ -372,7 +372,7 @@ private:
// Internal bindings
#if !COMPILE_WITHOUT_CSHARP
API_FUNCTION(NoProxy) void GetKeyframes(MArray* data);
API_FUNCTION(NoProxy) void SetKeyframes(MArray* data);
API_FUNCTION(NoProxy) void SetKeyframes(MArray* data, int32 keySize);
#endif
public:

View File

@@ -34,7 +34,7 @@ namespace FlaxEngine
if (value == null)
value = Utils.GetEmptyArray<BezierCurve<Transform>.Keyframe>();
_keyframes = null;
Internal_SetKeyframes(__unmanagedPtr, value);
Internal_SetKeyframes(__unmanagedPtr, value, System.Runtime.CompilerServices.Unsafe.SizeOf<BezierCurve<Transform>.Keyframe>());
}
}

View File

@@ -1150,6 +1150,47 @@ void ParticleEmitterGraphCPUExecutor::ProcessModule(ParticleEmitterGraphCPUNode*
// Not supported
break;
}
// Rotate Position Shape
case 216:
{
PARTICLE_EMITTER_MODULE("Rotate Position Shape");
auto& positionAttr = context.Data->Buffer->Layout->Attributes[node->Attributes[0]];
byte* positionPtr = start + positionAttr.Offset;
auto quatBox = node->GetBox(0);
#define INPUTS_FETCH() \
const Quaternion quat = (Quaternion)GetValue(quatBox, 2);
#define LOGIC() \
Quaternion nq = Quaternion::Invert(quat); \
Float3 v3 = *((Float3*)positionPtr); \
Quaternion q = Quaternion(v3.X, v3.Y, v3.Z, 0.0f); \
Quaternion rq = quat * (q * nq); \
*(Float3*)positionPtr = Float3(rq.X, rq.Y, rq.Z); \
positionPtr += stride;
if (node->UsePerParticleDataResolve())
{
for (int32 particleIndex = particlesStart; particleIndex < particlesEnd; particleIndex++)
{
context.ParticleIndex = particleIndex;
INPUTS_FETCH();
LOGIC();
}
}
else
{
INPUTS_FETCH();
for (int32 particleIndex = particlesStart; particleIndex < particlesEnd; particleIndex++)
{
LOGIC();
}
}
#undef INPUTS_FETCH
#undef LOGIC
break;
}
// Helper macros for collision modules to share the code
#define COLLISION_BEGIN() \

View File

@@ -632,6 +632,20 @@ void ParticleEmitterGPUGenerator::ProcessModule(Node* node)
), position.Value, param.ShaderName, wsPos);
break;
}
// Rotate position shape
case 216:
{
auto positionAttr = AccessParticleAttribute(node, nodeGpu->Attributes[0], AccessMode::Write);
const Value quaternion = GetValue(node->GetBox(0), 2).Cast(VariantType::Quaternion);
_writer.Write(
TEXT(
" {{\n"
" // Rotate position shape\n"
" {0} = QuatRotateVector({1}, {0});\n"
" }}\n"
), positionAttr.Value, quaternion.Value);
break;
}
// Helper macros for collision modules to share the code
#define COLLISION_BEGIN() \

View File

@@ -858,6 +858,14 @@ namespace FlaxEngine.GUI
}
}
/// <inheritdoc />
public override bool ContainsPoint(ref Float2 location, bool precise = false)
{
if (precise && this.GetType() == typeof(ContainerControl) && BackgroundColor.A <= 0.0f) // Go through transparency
return false;
return base.ContainsPoint(ref location, precise);
}
/// <inheritdoc />
public override void PerformLayout(bool force = false)
{

View File

@@ -50,7 +50,7 @@ namespace FlaxEngine.GUI
/// <summary>
/// Gets or sets the normalized position in the parent control that the upper left corner is anchored to (range 0-1).
/// </summary>
[Serialize, HideInEditor]
[Serialize, HideInEditor, Limit(0, 1, 0.01f)]
public Float2 AnchorMin
{
get => _anchorMin;
@@ -69,7 +69,7 @@ namespace FlaxEngine.GUI
/// <summary>
/// Gets or sets the normalized position in the parent control that the bottom right corner is anchored to (range 0-1).
/// </summary>
[Serialize, HideInEditor]
[Serialize, HideInEditor, Limit(0, 1, 0.01f)]
public Float2 AnchorMax
{
get => _anchorMax;

View File

@@ -301,7 +301,7 @@ namespace Flax.Build
else
project.Path = targets[0].CustomExternalProjectFilePath;
if (project.WorkspaceRootPath.StartsWith(rootProject.ProjectFolderPath))
project.GroupName = Utilities.MakePathRelativeTo(project.WorkspaceRootPath, rootProject.ProjectFolderPath);
project.GroupName = Utilities.NormalizePath(Utilities.MakePathRelativeTo(project.WorkspaceRootPath, rootProject.ProjectFolderPath));
else if (projectInfo != Globals.Project)
project.GroupName = projectInfo.Name;
project.SourceDirectories = new List<string>
@@ -349,7 +349,10 @@ namespace Flax.Build
var referenceBinaryModules = referenceModules.Keys.GroupBy(x => x.BinaryModuleName).ToArray();
foreach (var binaryModule in referenceBinaryModules)
{
project.Defines.Add(binaryModule.Key.ToUpperInvariant() + "_API=");
var binaryModuleName = binaryModule.Key;
if (string.IsNullOrEmpty(binaryModuleName))
continue;
project.Defines.Add(binaryModuleName.ToUpperInvariant() + "_API=");
}
}
catch

View File

@@ -409,7 +409,7 @@ namespace Flax.Build
var referencedBuild = buildData.FinReferenceBuildModule(dependencyModule.BinaryModuleName);
if (referencedBuild != null && !string.IsNullOrEmpty(referencedBuild.ManagedPath))
{
// Reference binary module build build for referenced target
// Reference binary module build for referenced target
fileReferences.Add(referencedBuild.ManagedPath);
}
}

View File

@@ -88,7 +88,7 @@ namespace Flax.Deps.Dependencies
Path.Combine(root, "include", "SDL3"),
};
CloneGitRepoFast(root, "https://github.com/libsdl-org/SDL");
CloneGitRepo(root, "https://github.com/libsdl-org/SDL");
GitFetch(root);
GitResetToCommit(root, "535d80badefc83c5c527ec5748f2a20d6a9310fe"); // 3.2.0

View File

@@ -356,13 +356,13 @@ namespace Flax.Build.Projects.VisualStudio
if (project.SourceDirectories != null && project.SourceDirectories.Count == 1)
{
var subFolder = Utilities.MakePathRelativeTo(Path.GetDirectoryName(project.SourceDirectories[0]), project.WorkspaceRootPath);
if (subFolder.StartsWith("Source\\"))
subFolder = subFolder.Substring(7);
var subFolder = Utilities.NormalizePath(Utilities.MakePathRelativeTo(Path.GetDirectoryName(project.SourceDirectories[0]), project.WorkspaceRootPath));
if (subFolder.StartsWith("Source/"))
subFolder = subFolder.Substring("Source/".Length);
if (subFolder.Length != 0)
{
if (folder.Length != 0)
folder += '\\';
folder += '/';
folder += subFolder;
}
}
@@ -370,12 +370,12 @@ namespace Flax.Build.Projects.VisualStudio
if (string.IsNullOrEmpty(folder))
continue;
var folderParents = folder.Split('\\');
var folderParents = folder.Split('/');
for (int i = 0; i < folderParents.Length; i++)
{
var folderPath = folderParents[0];
for (int j = 1; j <= i; j++)
folderPath += '\\' + folderParents[j];
folderPath += '/' + folderParents[j];
if (folderNames.Contains(folderPath))
{
@@ -397,7 +397,7 @@ namespace Flax.Build.Projects.VisualStudio
{
var folderGuid = folderIds[folder].ToString("B").ToUpperInvariant();
var typeGuid = ProjectTypeGuids.ToOption(ProjectTypeGuids.SolutionFolder);
var lastSplit = folder.LastIndexOf('\\');
var lastSplit = folder.LastIndexOf('/');
var name = lastSplit != -1 ? folder.Substring(lastSplit + 1) : folder;
vcSolutionFileContent.AppendLine(string.Format("Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\"", typeGuid, name, folder, folderGuid));
@@ -573,7 +573,7 @@ namespace Flax.Build.Projects.VisualStudio
// Write nested folders hierarchy
foreach (var folder in folderNames)
{
var lastSplit = folder.LastIndexOf('\\');
var lastSplit = folder.LastIndexOf('/');
if (lastSplit != -1)
{
var folderGuid = folderIds[folder].ToString("B").ToUpperInvariant();
@@ -615,8 +615,9 @@ namespace Flax.Build.Projects.VisualStudio
{
var profiles = new Dictionary<string, string>();
var profile = new StringBuilder();
var editorPath = Utilities.NormalizePath(Path.Combine(Globals.EngineRoot, Platform.GetEditorBinaryDirectory(), $"Development/FlaxEditor{Utilities.GetPlatformExecutableExt()}")).Replace('\\', '/');
var workspacePath = Utilities.NormalizePath(solutionDirectory).Replace('\\', '/');
var configuration = "Development";
var editorPath = Utilities.NormalizePath(Path.Combine(Globals.EngineRoot, Platform.GetEditorBinaryDirectory(), configuration, $"FlaxEditor{Utilities.GetPlatformExecutableExt()}"));
var workspacePath = Utilities.NormalizePath(solutionDirectory);
foreach (var project in projects)
{
if (project.Type == TargetType.DotNetCore)