Merge remote-tracking branch 'origin/1.7' into 1.8
# Conflicts: # Flax.flaxproj
This commit is contained in:
2
.github/workflows/build_android.yml
vendored
2
.github/workflows/build_android.yml
vendored
@@ -33,4 +33,4 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
|
||||
|
||||
2
.github/workflows/build_ios.yml
vendored
2
.github/workflows/build_ios.yml
vendored
@@ -33,4 +33,4 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -dotnet=7 -arch=ARM64 -platform=iOS -configuration=Release -buildtargets=FlaxGame
|
||||
|
||||
4
.github/workflows/build_linux.yml
vendored
4
.github/workflows/build_linux.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxEditor
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxEditor
|
||||
|
||||
# Game
|
||||
game-linux:
|
||||
@@ -64,4 +64,4 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Linux -configuration=Release -buildtargets=FlaxGame
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Linux -configuration=Release -buildtargets=FlaxGame
|
||||
|
||||
4
.github/workflows/build_mac.yml
vendored
4
.github/workflows/build_mac.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Mac -configuration=Development -buildtargets=FlaxEditor
|
||||
|
||||
# Game
|
||||
game-mac:
|
||||
@@ -55,4 +55,4 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -arch=x64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
|
||||
./Development/Scripts/Mac/CallBuildTool.sh -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Mac -configuration=Release -buildtargets=FlaxGame
|
||||
|
||||
4
.github/workflows/build_windows.yml
vendored
4
.github/workflows/build_windows.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
|
||||
|
||||
# Game
|
||||
game-windows:
|
||||
@@ -55,4 +55,4 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=7 -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
|
||||
|
||||
10
.github/workflows/tests.yml
vendored
10
.github/workflows/tests.yml
vendored
@@ -34,8 +34,8 @@ jobs:
|
||||
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: Build
|
||||
run: |
|
||||
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
|
||||
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=7
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
|
||||
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||
- name: Test
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
dotnet test -f net7.0 Binaries/Tests/FlaxEngine.CSharp.dll
|
||||
- name: Test UseLargeWorlds
|
||||
run: |
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
|
||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=7 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
|
||||
${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
|
||||
|
||||
# Tests on Windows
|
||||
@@ -72,8 +72,8 @@ jobs:
|
||||
git lfs pull
|
||||
- name: Build
|
||||
run: |
|
||||
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
|
||||
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs -dotnet=7
|
||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -dotnet=7 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
|
||||
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||
- name: Test
|
||||
run: |
|
||||
|
||||
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Constant Burst.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Constant Burst.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Periodic Burst.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Periodic Burst.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Smoke.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Sparks.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Sparks.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Binary file not shown.
@@ -4,7 +4,7 @@
|
||||
"Major": 1,
|
||||
"Minor": 8,
|
||||
"Revision": 0,
|
||||
"Build": 6502
|
||||
"Build": 6503
|
||||
},
|
||||
"Company": "Flax",
|
||||
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",
|
||||
|
||||
@@ -7,7 +7,7 @@ pushd
|
||||
echo Performing the full package...
|
||||
|
||||
rem Run the build tool.
|
||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -deployPlatforms -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -deployPlatforms -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||
if errorlevel 1 goto BuildToolFailed
|
||||
|
||||
popd
|
||||
|
||||
@@ -7,7 +7,7 @@ pushd
|
||||
echo Building and packaging Flax Editor...
|
||||
|
||||
rem Run the build tool.
|
||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployEditor -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||
if errorlevel 1 goto BuildToolFailed
|
||||
|
||||
popd
|
||||
|
||||
@@ -9,4 +9,4 @@ echo Building and packaging Flax Editor...
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
# Run Flax.Build (also pass the arguments)
|
||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployEditor --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployEditor --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
|
||||
@@ -9,4 +9,4 @@ echo Building and packaging Flax Editor...
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
# Run Flax.Build (also pass the arguments)
|
||||
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployEditor --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployEditor --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
|
||||
@@ -7,7 +7,7 @@ pushd
|
||||
echo Building and packaging platforms data...
|
||||
|
||||
rem Run the build tool.
|
||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployPlatforms -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||
call "Development\Scripts\Windows\CallBuildTool.bat" -deploy -deployPlatforms -dotnet=7 -verbose -log -logFile="Cache\Intermediate\PackageLog.txt" %*
|
||||
if errorlevel 1 goto BuildToolFailed
|
||||
|
||||
popd
|
||||
|
||||
@@ -9,4 +9,4 @@ echo Building and packaging platforms data...
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
# Run Flax.Build (also pass the arguments)
|
||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployPlatforms --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --deploy --deployPlatforms --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
|
||||
@@ -9,4 +9,4 @@ echo Building and packaging platforms data...
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
# Run Flax.Build (also pass the arguments)
|
||||
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployPlatforms --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
bash ./Development/Scripts/Linux/CallBuildTool.sh --deploy --deployPlatforms --dotnet=7 --verbose --log --logFile="Cache/Intermediate/PackageLog.txt" "$@"
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
class GameCooker;
|
||||
class PlatformTools;
|
||||
|
||||
#if OFFICIAL_BUILD
|
||||
// Use the fixed .NET SDK version in packaged builds for compatibility (FlaxGame is precompiled with it)
|
||||
#define GAME_BUILD_DOTNET_VER TEXT("-dotnet=7")
|
||||
#else
|
||||
#define GAME_BUILD_DOTNET_VER TEXT("")
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Game building options. Used as flags.
|
||||
/// </summary>
|
||||
|
||||
@@ -188,8 +188,8 @@ bool CompileScriptsStep::Perform(CookingData& data)
|
||||
LOG(Info, "Starting scripts compilation for game...");
|
||||
const String logFile = data.CacheDirectory / TEXT("CompileLog.txt");
|
||||
auto args = String::Format(
|
||||
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5}"),
|
||||
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()));
|
||||
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5} {6}"),
|
||||
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()), GAME_BUILD_DOTNET_VER);
|
||||
#if PLATFORM_WINDOWS
|
||||
if (data.Platform == BuildPlatform::LinuxX64)
|
||||
#elif PLATFORM_LINUX
|
||||
|
||||
@@ -87,7 +87,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
||||
{
|
||||
// Ask Flax.Build to provide .Net SDK location for the current platform
|
||||
String sdks;
|
||||
bool failed = ScriptsBuilder::RunBuildTool(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs"), data.CacheDirectory);
|
||||
bool failed = ScriptsBuilder::RunBuildTool(String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs {}"), GAME_BUILD_DOTNET_VER), data.CacheDirectory);
|
||||
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
||||
int32 idx = sdks.Find(TEXT("DotNetSdk, "), StringSearchCase::CaseSensitive);
|
||||
if (idx != -1)
|
||||
@@ -168,7 +168,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
||||
String sdks;
|
||||
const Char *platformName, *archName;
|
||||
data.GetBuildPlatformName(platformName, archName);
|
||||
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={}"), platformName, archName);
|
||||
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={} {}"), platformName, archName, GAME_BUILD_DOTNET_VER);
|
||||
bool failed = ScriptsBuilder::RunBuildTool(args, data.CacheDirectory);
|
||||
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
||||
Array<String> parts;
|
||||
@@ -269,8 +269,8 @@ bool DeployDataStep::Perform(CookingData& data)
|
||||
LOG(Info, "Optimizing .NET class library size to include only used assemblies");
|
||||
const String logFile = data.CacheDirectory / TEXT("StripDotnetLibs.txt");
|
||||
String args = String::Format(
|
||||
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\""),
|
||||
logFile, data.DataOutputPath);
|
||||
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\" {}"),
|
||||
logFile, data.DataOutputPath, GAME_BUILD_DOTNET_VER);
|
||||
for (const String& define : data.CustomDefines)
|
||||
{
|
||||
args += TEXT(" -D");
|
||||
|
||||
@@ -67,8 +67,8 @@ bool PrecompileAssembliesStep::Perform(CookingData& data)
|
||||
data.GetBuildPlatformName(platform, architecture);
|
||||
const String logFile = data.CacheDirectory / TEXT("AOTLog.txt");
|
||||
String args = String::Format(
|
||||
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\""),
|
||||
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath);
|
||||
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\" {}"),
|
||||
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath, GAME_BUILD_DOTNET_VER);
|
||||
if (!buildSettings.SkipUnusedDotnetLibsPackaging)
|
||||
args += TEXT(" -skipUnusedDotnetLibs=false"); // Run AOT on whole class library (not just used libs)
|
||||
for (const String& define : data.CustomDefines)
|
||||
|
||||
@@ -171,11 +171,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
tree.Select(typeNode);
|
||||
if (addItems)
|
||||
{
|
||||
var items = GenericEditor.GetItemsForType(type, type.IsClass, true);
|
||||
var items = GenericEditor.GetItemsForType(type, type.IsClass, true, true);
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (typed && !typed.IsAssignableFrom(item.Info.ValueType))
|
||||
continue;
|
||||
if (item.Info.DeclaringType.Type == typeof(FlaxEngine.Object))
|
||||
continue; // Skip engine internals
|
||||
var itemPath = typePath + item.Info.Name;
|
||||
var node = new TreeNode
|
||||
{
|
||||
|
||||
@@ -247,8 +247,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="useProperties">True if use type properties.</param>
|
||||
/// <param name="useFields">True if use type fields.</param>
|
||||
/// <param name="usePropertiesWithoutSetter">True if use type properties that have only getter method without setter method (aka read-only).</param>
|
||||
/// <returns>The items.</returns>
|
||||
public static List<ItemInfo> GetItemsForType(ScriptType type, bool useProperties, bool useFields)
|
||||
public static List<ItemInfo> GetItemsForType(ScriptType type, bool useProperties, bool useFields, bool usePropertiesWithoutSetter = false)
|
||||
{
|
||||
var items = new List<ItemInfo>();
|
||||
|
||||
@@ -264,7 +265,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
|
||||
|
||||
// Skip properties without getter or setter
|
||||
if (!p.HasGet || (!p.HasSet && !showInEditor))
|
||||
if (!p.HasGet || (!p.HasSet && !showInEditor && !usePropertiesWithoutSetter))
|
||||
continue;
|
||||
|
||||
// Skip hidden fields, handle special attributes
|
||||
|
||||
@@ -111,7 +111,8 @@ namespace FlaxEditor.Gizmo
|
||||
if (isSelected)
|
||||
{
|
||||
GetSelectedObjectsBounds(out var selectionBounds, out _);
|
||||
ray.Position = ray.GetPoint(selectionBounds.Size.Y * 0.5f);
|
||||
var offset = Mathf.Max(selectionBounds.Size.Y * 0.5f, 1.0f);
|
||||
ray.Position = ray.GetPoint(offset);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -288,6 +288,9 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
}
|
||||
}
|
||||
SetValue(2, ids);
|
||||
|
||||
// Force refresh UI
|
||||
ResizeAuto();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -371,7 +371,10 @@ namespace FlaxEditor.Windows.Assets
|
||||
private void OnTreeSelectedChanged(List<TreeNode> before, List<TreeNode> after)
|
||||
{
|
||||
if (after.Count != 0)
|
||||
((SkeletonPropertiesProxy)Values[0]).Window._preview.ShowDebugDraw = true;
|
||||
{
|
||||
var proxy = (SkeletonPropertiesProxy)Values[0];
|
||||
proxy.Window._preview.ShowDebugDraw = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTreeNodeCopyName(ContextMenuButton b)
|
||||
@@ -1045,6 +1048,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
{
|
||||
Proxy = new SkeletonPropertiesProxy();
|
||||
Presenter.Select(Proxy);
|
||||
// Draw highlight on selected node
|
||||
window._preview.CustomDebugDraw += OnDebugDraw;
|
||||
}
|
||||
|
||||
@@ -1146,6 +1150,15 @@ namespace FlaxEditor.Windows.Assets
|
||||
_tabs.AddTab(new RetargetTab(this));
|
||||
_tabs.AddTab(new ImportTab(this));
|
||||
|
||||
// Automatically show nodes when switching to skeleton page
|
||||
_tabs.SelectedTabChanged += (tabs) =>
|
||||
{
|
||||
if (tabs.SelectedTab is SkeletonTab)
|
||||
{
|
||||
_preview.ShowNodes = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Highlight actor (used to highlight selected material slot, see UpdateEffectsOnAsset)
|
||||
_highlightActor = new AnimatedModel
|
||||
{
|
||||
|
||||
@@ -386,6 +386,7 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
_viewport.Bounds = new Rectangle(Width * (1 - scaleWidth) / 2, 0, Width * scaleWidth, Height);
|
||||
}
|
||||
_viewport.SyncBackbufferSize();
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
|
||||
@@ -391,6 +391,25 @@ namespace FlaxEditor.Windows
|
||||
}
|
||||
|
||||
Editor.Log("Plugin project has been cloned.");
|
||||
|
||||
try
|
||||
{
|
||||
// Start git submodule clone
|
||||
var settings = new CreateProcessSettings
|
||||
{
|
||||
FileName = "git",
|
||||
WorkingDirectory = clonePath,
|
||||
Arguments = "submodule update --init",
|
||||
ShellExecute = false,
|
||||
LogOutput = true,
|
||||
};
|
||||
Platform.CreateProcess(ref settings);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Editor.LogError($"Failed Git submodule process. {e}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Find project config file. Could be different then what the user named the folder.
|
||||
var files = Directory.GetFiles(clonePath);
|
||||
|
||||
@@ -114,14 +114,19 @@ void Behavior::UpdateAsync()
|
||||
|
||||
void Behavior::StartLogic()
|
||||
{
|
||||
if (_result == BehaviorUpdateResult::Running)
|
||||
return;
|
||||
PROFILE_CPU();
|
||||
|
||||
// Ensure to have tree loaded on begin play
|
||||
// Ensure to have tree loaded on play
|
||||
CHECK(Tree && !Tree->WaitForLoaded());
|
||||
BehaviorTree* tree = Tree.Get();
|
||||
CHECK(tree->Graph.Root);
|
||||
|
||||
// Setup state
|
||||
_result = BehaviorUpdateResult::Running;
|
||||
_accumulatedTime = 0.0f;
|
||||
_totalTime = 0;
|
||||
|
||||
// Init knowledge
|
||||
_knowledge.InitMemory(tree);
|
||||
@@ -135,6 +140,7 @@ void Behavior::StopLogic(BehaviorUpdateResult result)
|
||||
_accumulatedTime = 0.0f;
|
||||
_totalTime = 0;
|
||||
_result = result;
|
||||
_knowledge.FreeMemory();
|
||||
}
|
||||
|
||||
void Behavior::ResetLogic()
|
||||
@@ -170,7 +176,11 @@ void Behavior::OnDisable()
|
||||
|
||||
bool Behavior::GetNodeDebugRelevancy(const BehaviorTreeNode* node, const Behavior* behavior)
|
||||
{
|
||||
return node && behavior && node->_executionIndex != -1 && behavior->_knowledge.RelevantNodes.Get(node->_executionIndex);
|
||||
return node &&
|
||||
behavior &&
|
||||
node->_executionIndex >= 0 &&
|
||||
node->_executionIndex < behavior->_knowledge.RelevantNodes.Count() &&
|
||||
behavior->_knowledge.RelevantNodes.Get(node->_executionIndex);
|
||||
}
|
||||
|
||||
String Behavior::GetNodeDebugInfo(const BehaviorTreeNode* node, Behavior* behavior)
|
||||
@@ -179,7 +189,7 @@ String Behavior::GetNodeDebugInfo(const BehaviorTreeNode* node, Behavior* behavi
|
||||
return String::Empty;
|
||||
BehaviorUpdateContext context;
|
||||
Platform::MemoryClear(&context, sizeof(context));
|
||||
if (behavior && node->_executionIndex != -1 && behavior->_knowledge.RelevantNodes.Get(node->_executionIndex))
|
||||
if (GetNodeDebugRelevancy(node, behavior))
|
||||
{
|
||||
// Pass behavior and knowledge data only for relevant nodes to properly access it
|
||||
context.Behavior = behavior;
|
||||
|
||||
@@ -83,7 +83,7 @@ bool AccessVariant(Variant& instance, const StringAnsiView& member, Variant& val
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
else if (typeName.HasChars())
|
||||
{
|
||||
LOG(Warning, "Missing scripting type \'{0}\'", String(typeName));
|
||||
}
|
||||
|
||||
@@ -1342,7 +1342,12 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
|
||||
{
|
||||
const bool xAxis = Math::IsZero(v0.X) && Math::IsZero(v1.X);
|
||||
const bool yAxis = Math::IsZero(v0.Y) && Math::IsZero(v1.Y);
|
||||
if (xAxis || yAxis)
|
||||
if (xAxis && yAxis)
|
||||
{
|
||||
// Single animation
|
||||
value = SampleAnimation(node, loop, data.Length, startTimePos, bucket.TimePosition, newTimePos, aAnim, aData.W);
|
||||
}
|
||||
else if (xAxis || yAxis)
|
||||
{
|
||||
if (yAxis)
|
||||
{
|
||||
|
||||
@@ -323,26 +323,29 @@ bool BinaryAsset::SaveToAsset(const StringView& path, AssetInitData& data, bool
|
||||
{
|
||||
// Ensure path is in a valid format
|
||||
String pathNorm(path);
|
||||
FileSystem::NormalizePath(pathNorm);
|
||||
ContentStorageManager::FormatPath(pathNorm);
|
||||
const StringView filePath = pathNorm;
|
||||
|
||||
// Find target storage container and the asset
|
||||
auto storage = ContentStorageManager::TryGetStorage(pathNorm);
|
||||
auto asset = Content::GetAsset(pathNorm);
|
||||
auto storage = ContentStorageManager::TryGetStorage(filePath);
|
||||
auto asset = Content::GetAsset(filePath);
|
||||
auto binaryAsset = dynamic_cast<BinaryAsset*>(asset);
|
||||
if (asset && !binaryAsset)
|
||||
{
|
||||
LOG(Warning, "Cannot write to the non-binary asset location.");
|
||||
return true;
|
||||
}
|
||||
if (!binaryAsset && !storage && FileSystem::FileExists(filePath))
|
||||
{
|
||||
// Force-resolve storage (asset at that path could be not yet loaded into registry)
|
||||
storage = ContentStorageManager::GetStorage(filePath);
|
||||
}
|
||||
|
||||
// Check if can perform write operation to the asset container
|
||||
if (storage)
|
||||
if (storage && !storage->AllowDataModifications())
|
||||
{
|
||||
if (!storage->AllowDataModifications())
|
||||
{
|
||||
LOG(Warning, "Cannot write to the asset storage container.");
|
||||
return true;
|
||||
}
|
||||
LOG(Warning, "Cannot write to the asset storage container.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize data container
|
||||
@@ -352,6 +355,11 @@ bool BinaryAsset::SaveToAsset(const StringView& path, AssetInitData& data, bool
|
||||
// Use the same asset ID
|
||||
data.Header.ID = binaryAsset->GetID();
|
||||
}
|
||||
else if (storage && storage->GetEntriesCount())
|
||||
{
|
||||
// Use the same file ID
|
||||
data.Header.ID = storage->GetEntry(0).ID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Randomize ID
|
||||
@@ -373,8 +381,8 @@ bool BinaryAsset::SaveToAsset(const StringView& path, AssetInitData& data, bool
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(pathNorm.HasChars());
|
||||
result = FlaxStorage::Create(pathNorm, data, silentMode);
|
||||
ASSERT(filePath.HasChars());
|
||||
result = FlaxStorage::Create(filePath, data, silentMode);
|
||||
}
|
||||
if (binaryAsset)
|
||||
binaryAsset->_isSaving = false;
|
||||
|
||||
@@ -54,8 +54,7 @@ namespace
|
||||
// Assets
|
||||
CriticalSection AssetsLocker;
|
||||
Dictionary<Guid, Asset*> Assets(2048);
|
||||
CriticalSection LoadCallAssetsLocker;
|
||||
Array<Guid> LoadCallAssets(64);
|
||||
Array<Guid> LoadCallAssets(PLATFORM_THREADS_LIMIT);
|
||||
CriticalSection LoadedAssetsToInvokeLocker;
|
||||
Array<Asset*> LoadedAssetsToInvoke(64);
|
||||
Array<Asset*> ToUnload;
|
||||
@@ -449,18 +448,19 @@ Asset* Content::LoadAsync(const StringView& path, const ScriptingTypeHandle& typ
|
||||
{
|
||||
// Ensure path is in a valid format
|
||||
String pathNorm(path);
|
||||
StringUtils::PathRemoveRelativeParts(pathNorm);
|
||||
ContentStorageManager::FormatPath(pathNorm);
|
||||
const StringView filePath = pathNorm;
|
||||
|
||||
#if USE_EDITOR
|
||||
if (!FileSystem::FileExists(pathNorm))
|
||||
if (!FileSystem::FileExists(filePath))
|
||||
{
|
||||
LOG(Error, "Missing file \'{0}\'", pathNorm);
|
||||
LOG(Error, "Missing file \'{0}\'", filePath);
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
AssetInfo assetInfo;
|
||||
if (GetAssetInfo(pathNorm, assetInfo))
|
||||
if (GetAssetInfo(filePath, assetInfo))
|
||||
{
|
||||
return LoadAsync(assetInfo.ID, type);
|
||||
}
|
||||
@@ -910,9 +910,13 @@ Asset* Content::LoadAsync(const Guid& id, const ScriptingTypeHandle& type)
|
||||
return nullptr;
|
||||
|
||||
// Check if asset has been already loaded
|
||||
Asset* result = GetAsset(id);
|
||||
Asset* result = nullptr;
|
||||
AssetsLocker.Lock();
|
||||
Assets.TryGet(id, result);
|
||||
if (result)
|
||||
{
|
||||
AssetsLocker.Unlock();
|
||||
|
||||
// Validate type
|
||||
if (IsAssetTypeIdInvalid(type, result->GetTypeHandle()) && !result->Is(type))
|
||||
{
|
||||
@@ -923,57 +927,41 @@ Asset* Content::LoadAsync(const Guid& id, const ScriptingTypeHandle& type)
|
||||
}
|
||||
|
||||
// Check if that asset is during loading
|
||||
LoadCallAssetsLocker.Lock();
|
||||
if (LoadCallAssets.Contains(id))
|
||||
{
|
||||
LoadCallAssetsLocker.Unlock();
|
||||
AssetsLocker.Unlock();
|
||||
|
||||
// Wait for load end
|
||||
// TODO: dont use active waiting and prevent deadlocks if running on a main thread
|
||||
//while (!Engine::ShouldExit())
|
||||
while (true)
|
||||
// Wait for loading end by other thread
|
||||
bool contains = true;
|
||||
while (contains)
|
||||
{
|
||||
LoadCallAssetsLocker.Lock();
|
||||
const bool contains = LoadCallAssets.Contains(id);
|
||||
LoadCallAssetsLocker.Unlock();
|
||||
if (!contains)
|
||||
return GetAsset(id);
|
||||
Platform::Sleep(1);
|
||||
AssetsLocker.Lock();
|
||||
contains = LoadCallAssets.Contains(id);
|
||||
AssetsLocker.Unlock();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Mark asset as loading
|
||||
LoadCallAssets.Add(id);
|
||||
LoadCallAssetsLocker.Unlock();
|
||||
Assets.TryGet(id, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Load asset
|
||||
AssetInfo assetInfo;
|
||||
result = load(id, type, assetInfo);
|
||||
// Mark asset as loading and release lock so other threads can load other assets
|
||||
LoadCallAssets.Add(id);
|
||||
AssetsLocker.Unlock();
|
||||
|
||||
// End loading
|
||||
LoadCallAssetsLocker.Lock();
|
||||
LoadCallAssets.Remove(id);
|
||||
LoadCallAssetsLocker.Unlock();
|
||||
#define LOAD_FAILED() AssetsLocker.Lock(); LoadCallAssets.Remove(id); AssetsLocker.Unlock(); return nullptr
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Asset* Content::load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo& assetInfo)
|
||||
{
|
||||
// Get cached asset info (from registry)
|
||||
AssetInfo assetInfo;
|
||||
if (!GetAssetInfo(id, assetInfo))
|
||||
{
|
||||
LOG(Warning, "Invalid or missing asset ({0}, {1}).", id, type.ToString());
|
||||
return nullptr;
|
||||
LOAD_FAILED();
|
||||
}
|
||||
|
||||
#if ASSETS_LOADING_EXTRA_VERIFICATION
|
||||
if (!FileSystem::FileExists(assetInfo.Path))
|
||||
{
|
||||
LOG(Error, "Cannot find file '{0}'", assetInfo.Path);
|
||||
return nullptr;
|
||||
LOAD_FAILED();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -982,28 +970,27 @@ Asset* Content::load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo&
|
||||
if (factory == nullptr)
|
||||
{
|
||||
LOG(Error, "Cannot find asset factory. Info: {0}", assetInfo.ToString());
|
||||
return nullptr;
|
||||
LOAD_FAILED();
|
||||
}
|
||||
|
||||
// Create asset object
|
||||
auto result = factory->New(assetInfo);
|
||||
result = factory->New(assetInfo);
|
||||
if (result == nullptr)
|
||||
{
|
||||
LOG(Error, "Cannot create asset object. Info: {0}", assetInfo.ToString());
|
||||
return nullptr;
|
||||
LOAD_FAILED();
|
||||
}
|
||||
|
||||
ASSERT(result->GetID() == id);
|
||||
#if ASSETS_LOADING_EXTRA_VERIFICATION
|
||||
if (IsAssetTypeIdInvalid(type, result->GetTypeHandle()) && !result->Is(type))
|
||||
{
|
||||
LOG(Error, "Different loaded asset type! Asset: '{0}'. Expected type: {1}", assetInfo.ToString(), type.ToString());
|
||||
LOG(Warning, "Different loaded asset type! Asset: '{0}'. Expected type: {1}", assetInfo.ToString(), type.ToString());
|
||||
result->DeleteObject();
|
||||
return nullptr;
|
||||
LOAD_FAILED();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Register asset
|
||||
ASSERT(result->GetID() == id);
|
||||
AssetsLocker.Lock();
|
||||
#if ASSETS_LOADING_EXTRA_VERIFICATION
|
||||
ASSERT(!Assets.ContainsKey(id));
|
||||
@@ -1011,11 +998,14 @@ Asset* Content::load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo&
|
||||
Assets.Add(id, result);
|
||||
|
||||
// Start asset loading
|
||||
// TODO: refactor this to create asset loading task-chain before AssetsLocker.Lock() to allow better parallelization
|
||||
result->startLoading();
|
||||
|
||||
// Remove from the loading queue and release lock
|
||||
LoadCallAssets.Remove(id);
|
||||
AssetsLocker.Unlock();
|
||||
|
||||
#undef LOAD_FAILED
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -366,7 +366,6 @@ private:
|
||||
static void onAssetLoaded(Asset* asset);
|
||||
static void onAssetUnload(Asset* asset);
|
||||
static void onAssetChangeId(Asset* asset, const Guid& oldId, const Guid& newId);
|
||||
static Asset* load(const Guid& id, const ScriptingTypeHandle& type, AssetInfo& assetInfo);
|
||||
|
||||
private:
|
||||
static void deleteFileSafety(const StringView& path, const Guid& id);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Platform/FileSystem.h"
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Threading/TaskGraph.h"
|
||||
@@ -185,6 +186,16 @@ void ContentStorageManager::EnsureUnlocked()
|
||||
Locker.Unlock();
|
||||
}
|
||||
|
||||
void ContentStorageManager::FormatPath(String& path)
|
||||
{
|
||||
StringUtils::PathRemoveRelativeParts(path);
|
||||
if (FileSystem::IsRelative(path))
|
||||
{
|
||||
// Convert local-project paths into absolute format which is used by Content Storage system
|
||||
path = Globals::ProjectFolder / path;
|
||||
}
|
||||
}
|
||||
|
||||
bool ContentStorageManager::IsFlaxStoragePath(const String& path)
|
||||
{
|
||||
auto extension = FileSystem::GetExtension(path).ToLower();
|
||||
|
||||
@@ -75,6 +75,9 @@ public:
|
||||
/// </summary>
|
||||
static void EnsureUnlocked();
|
||||
|
||||
// Formats path into valid format used by the storage system (normalized and absolute).
|
||||
static void FormatPath(String& path);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Determines whether the specified path can be a binary asset file (based on it's extension).
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
#include "Engine/Core/Collections/Sorting.h"
|
||||
#include "Engine/Debug/DebugLog.h"
|
||||
#include "Engine/Level/Level.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Level/Actors/Camera.h"
|
||||
#include "Engine/Level/Actors/PostFxVolume.h"
|
||||
#include "Engine/Renderer/Renderer.h"
|
||||
#include "Engine/Render2D/Render2D.h"
|
||||
#include "Engine/Engine/Engine.h"
|
||||
#include "Engine/Level/Actors/PostFxVolume.h"
|
||||
#include "Engine/Profiler/Profiler.h"
|
||||
#include "Engine/Renderer/RenderList.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
@@ -202,15 +203,21 @@ void SceneRenderTask::CollectPostFxVolumes(RenderContext& renderContext)
|
||||
{
|
||||
Level::CollectPostFxVolumes(renderContext);
|
||||
}
|
||||
if (EnumHasAllFlags(ActorsSource , ActorsSources::CustomActors))
|
||||
if (EnumHasAllFlags(ActorsSource, ActorsSources::CustomActors))
|
||||
{
|
||||
for (Actor* a : CustomActors)
|
||||
{
|
||||
auto* postFxVolume = dynamic_cast<PostFxVolume*>(a);
|
||||
if (postFxVolume && a->GetIsActive())
|
||||
{
|
||||
postFxVolume->Collect(renderContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (EnumHasAllFlags(ActorsSource, ActorsSources::CustomScenes))
|
||||
{
|
||||
for (Scene* scene : CustomScenes)
|
||||
{
|
||||
if (scene && scene->IsActiveInHierarchy())
|
||||
scene->Rendering.CollectPostFxVolumes(renderContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,6 +289,14 @@ void SceneRenderTask::OnCollectDrawCalls(RenderContextBatch& renderContextBatch,
|
||||
ASSERT_LOW_LAYER(_customActorsScene);
|
||||
_customActorsScene->Draw(renderContextBatch, (SceneRendering::DrawCategory)category);
|
||||
}
|
||||
if (EnumHasAllFlags(ActorsSource, ActorsSources::CustomScenes))
|
||||
{
|
||||
for (Scene* scene : CustomScenes)
|
||||
{
|
||||
if (scene && scene->IsActiveInHierarchy())
|
||||
scene->Rendering.Draw(renderContextBatch, (SceneRendering::DrawCategory)category);
|
||||
}
|
||||
}
|
||||
if (EnumHasAllFlags(ActorsSource, ActorsSources::Scenes))
|
||||
{
|
||||
Level::DrawActors(renderContextBatch, category);
|
||||
|
||||
@@ -21,6 +21,7 @@ class PostProcessEffect;
|
||||
struct RenderContext;
|
||||
class Camera;
|
||||
class Actor;
|
||||
class Scene;
|
||||
|
||||
/// <summary>
|
||||
/// Allows to perform custom rendering using graphics pipeline.
|
||||
@@ -174,6 +175,11 @@ API_ENUM(Attributes="Flags") enum class ActorsSources
|
||||
/// </summary>
|
||||
CustomActors = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The scenes from the custom collection.
|
||||
/// </summary>
|
||||
CustomScenes = 4,
|
||||
|
||||
/// <summary>
|
||||
/// The actors from the loaded scenes and custom collection.
|
||||
/// </summary>
|
||||
@@ -267,9 +273,14 @@ public:
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// The custom set of actors to render.
|
||||
/// The custom set of actors to render. Used when ActorsSources::CustomActors flag is active.
|
||||
/// </summary>
|
||||
Array<Actor*> CustomActors;
|
||||
API_FIELD() Array<Actor*> CustomActors;
|
||||
|
||||
/// <summary>
|
||||
/// The custom set of scenes to render. Used when ActorsSources::CustomScenes flag is active.
|
||||
/// </summary>
|
||||
API_FIELD() Array<Scene*> CustomScenes;
|
||||
|
||||
/// <summary>
|
||||
/// Adds the custom actor to the rendering.
|
||||
|
||||
@@ -172,6 +172,28 @@ void AnimatedModel::GetNodeTransformation(const StringView& nodeName, Matrix& no
|
||||
GetNodeTransformation(SkinnedModel ? SkinnedModel->FindNode(nodeName) : -1, nodeTransformation, worldSpace);
|
||||
}
|
||||
|
||||
void AnimatedModel::SetNodeTransformation(int32 nodeIndex, const Matrix& nodeTransformation, bool worldSpace)
|
||||
{
|
||||
if (GraphInstance.NodesPose.IsEmpty())
|
||||
const_cast<AnimatedModel*>(this)->PreInitSkinningData(); // Ensure to have valid nodes pose to return
|
||||
CHECK(nodeIndex >= 0 && nodeIndex < GraphInstance.NodesPose.Count());
|
||||
GraphInstance.NodesPose[nodeIndex] = nodeTransformation;
|
||||
if (worldSpace)
|
||||
{
|
||||
Matrix world;
|
||||
_transform.GetWorld(world);
|
||||
Matrix invWorld;
|
||||
Matrix::Invert(world, invWorld);
|
||||
GraphInstance.NodesPose[nodeIndex] = GraphInstance.NodesPose[nodeIndex] * invWorld;
|
||||
}
|
||||
OnAnimationUpdated();
|
||||
}
|
||||
|
||||
void AnimatedModel::SetNodeTransformation(const StringView& nodeName, const Matrix& nodeTransformation, bool worldSpace)
|
||||
{
|
||||
SetNodeTransformation(SkinnedModel ? SkinnedModel->FindNode(nodeName) : -1, nodeTransformation, worldSpace);
|
||||
}
|
||||
|
||||
int32 AnimatedModel::FindClosestNode(const Vector3& location, bool worldSpace) const
|
||||
{
|
||||
if (GraphInstance.NodesPose.IsEmpty())
|
||||
|
||||
@@ -229,6 +229,22 @@ public:
|
||||
/// <param name="worldSpace">True if convert matrices into world-space, otherwise returned values will be in local-space of the actor.</param>
|
||||
API_FUNCTION() void GetNodeTransformation(const StringView& nodeName, API_PARAM(Out) Matrix& nodeTransformation, bool worldSpace = false) const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the node final transformation. If multiple nodes are to be set within a frame, do not use set worldSpace to true, and do the conversion yourself to avoid recalculation of inv matrices.
|
||||
/// </summary>
|
||||
/// <param name="nodeIndex">The index of the skinned model skeleton node.</param>
|
||||
/// <param name="nodeTransformation">The final node transformation matrix.</param>
|
||||
/// <param name="worldSpace">True if convert matrices from world-space, otherwise values will be in local-space of the actor.</param>
|
||||
API_FUNCTION() void SetNodeTransformation(int32 nodeIndex, const Matrix& nodeTransformation, bool worldSpace = false);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the node final transformation. If multiple nodes are to be set within a frame, do not use set worldSpace to true, and do the conversion yourself to avoid recalculation of inv matrices.
|
||||
/// </summary>
|
||||
/// <param name="nodeName">The name of the skinned model skeleton node.</param>
|
||||
/// <param name="nodeTransformation">The final node transformation matrix.</param>
|
||||
/// <param name="worldSpace">True if convert matrices from world-space, otherwise values will be in local-space of the actor.</param>
|
||||
API_FUNCTION() void SetNodeTransformation(const StringView& nodeName, const Matrix& nodeTransformation, bool worldSpace = false);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the closest node to a given location.
|
||||
/// </summary>
|
||||
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
/// </summary>
|
||||
Win32CriticalSection()
|
||||
{
|
||||
Windows::InitializeCriticalSectionEx(&_criticalSection, 100, 0x01000000);
|
||||
Windows::InitializeCriticalSectionEx(&_criticalSection, 4000, 0x01000000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1812,7 +1812,7 @@ void* GetStaticMethodPointer(const String& methodName)
|
||||
PROFILE_CPU();
|
||||
const int rc = get_function_pointer(NativeInteropTypeName, FLAX_CORECLR_STRING(methodName).Get(), UNMANAGEDCALLERSONLY_METHOD, nullptr, nullptr, &fun);
|
||||
if (rc != 0)
|
||||
LOG(Fatal, "Failed to get unmanaged function pointer for method {0}: 0x{1:x}", methodName.Get(), (unsigned int)rc);
|
||||
LOG(Fatal, "Failed to get unmanaged function pointer for method '{0}': 0x{1:x}", methodName, (unsigned int)rc);
|
||||
CachedFunctions.Add(methodName, fun);
|
||||
return fun;
|
||||
}
|
||||
@@ -2211,7 +2211,7 @@ void* GetStaticMethodPointer(const String& methodName)
|
||||
{
|
||||
const unsigned short errorCode = mono_error_get_error_code(&error);
|
||||
const char* errorMessage = mono_error_get_message(&error);
|
||||
LOG(Fatal, "mono_method_get_unmanaged_callers_only_ftnptr failed with error code 0x{0:x}, {1}", errorCode, String(errorMessage));
|
||||
LOG(Fatal, "Failed to get unmanaged function pointer for method '{0}': 0x{1:x}, {2}", methodName, errorCode, String(errorMessage));
|
||||
}
|
||||
mono_error_cleanup(&error);
|
||||
|
||||
|
||||
@@ -180,6 +180,8 @@ namespace FlaxEngine
|
||||
|
||||
private static void OnLocalizationChanged()
|
||||
{
|
||||
// iOS uses globalization-invariant mode so ignore it
|
||||
#if !PLATFORM_IOS
|
||||
var currentThread = Thread.CurrentThread;
|
||||
var language = Localization.CurrentLanguage;
|
||||
if (language != null)
|
||||
@@ -187,6 +189,7 @@ namespace FlaxEngine
|
||||
var culture = Localization.CurrentCulture;
|
||||
if (culture != null)
|
||||
currentThread.CurrentCulture = culture;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace FlaxEngine.Utilities
|
||||
where T : new()
|
||||
{
|
||||
var json = Json.JsonSerializer.Serialize(instance);
|
||||
return Json.JsonSerializer.Deserialize<T>(json);
|
||||
return (T)Json.JsonSerializer.Deserialize(json, instance.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
2
Source/ThirdParty/nethost/nethost.Build.cs
vendored
2
Source/ThirdParty/nethost/nethost.Build.cs
vendored
@@ -32,7 +32,7 @@ public class nethost : ThirdPartyModule
|
||||
// Get .NET SDK runtime host
|
||||
var dotnetSdk = DotNetSdk.Instance;
|
||||
if (!dotnetSdk.IsValid)
|
||||
throw new Exception($"Missing NET SDK {DotNetSdk.MinimumVersion}.");
|
||||
throw new DotNetSdk.MissingException();
|
||||
if (!dotnetSdk.GetHostRuntime(options.Platform.Target, options.Architecture, out var hostRuntime))
|
||||
{
|
||||
if (options.Target.IsPreBuilt)
|
||||
|
||||
@@ -145,6 +145,20 @@ namespace Flax.Build.Bindings
|
||||
return $"(void*){result}";
|
||||
}
|
||||
|
||||
|
||||
private static void GenerateCppAddFileReference(BuildData buildData, ApiTypeInfo caller, TypeInfo typeInfo, ApiTypeInfo apiType)
|
||||
{
|
||||
CppReferencesFiles.Add(apiType?.File);
|
||||
if (typeInfo.GenericArgs != null)
|
||||
{
|
||||
for (int i = 0; i < typeInfo.GenericArgs.Count; i++)
|
||||
{
|
||||
var g = typeInfo.GenericArgs[i];
|
||||
GenerateCppAddFileReference(buildData, caller, g, FindApiTypeInfo(buildData, g, caller));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GenerateCppWrapperNativeToVariant(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller, string value)
|
||||
{
|
||||
if (typeInfo.Type == "Variant")
|
||||
@@ -640,15 +654,7 @@ namespace Flax.Build.Bindings
|
||||
|
||||
// Register any API types usage
|
||||
apiType = FindApiTypeInfo(buildData, typeInfo, caller);
|
||||
CppReferencesFiles.Add(apiType?.File);
|
||||
if (typeInfo.GenericArgs != null)
|
||||
{
|
||||
for (int i = 0; i < typeInfo.GenericArgs.Count; i++)
|
||||
{
|
||||
var t = FindApiTypeInfo(buildData, typeInfo.GenericArgs[i], caller);
|
||||
CppReferencesFiles.Add(t?.File);
|
||||
}
|
||||
}
|
||||
GenerateCppAddFileReference(buildData, caller, typeInfo, apiType);
|
||||
|
||||
// Use dynamic array as wrapper container for fixed-size native arrays
|
||||
if (typeInfo.IsArray)
|
||||
@@ -1795,15 +1801,7 @@ namespace Flax.Build.Bindings
|
||||
return true;
|
||||
|
||||
// Add includes to properly compile bindings (eg. SoftObjectReference<class Texture>)
|
||||
CppReferencesFiles.Add(apiTypeInfo?.File);
|
||||
if (typeInfo.GenericArgs != null)
|
||||
{
|
||||
for (int i = 0; i < typeInfo.GenericArgs.Count; i++)
|
||||
{
|
||||
var t = FindApiTypeInfo(buildData, typeInfo.GenericArgs[i], caller);
|
||||
CppReferencesFiles.Add(t?.File);
|
||||
}
|
||||
}
|
||||
GenerateCppAddFileReference(buildData, caller, typeInfo, apiTypeInfo);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Flax.Build
|
||||
#if USE_NETCORE
|
||||
var dotnetSdk = DotNetSdk.Instance;
|
||||
if (!dotnetSdk.IsValid)
|
||||
throw new Exception("Cannot compile C# without .NET SDK");
|
||||
throw new DotNetSdk.MissingException();
|
||||
string dotnetPath = "dotnet", referenceAnalyzers;
|
||||
string[] runtimeVersionNameParts = dotnetSdk.RuntimeVersionName.Split('.');
|
||||
string runtimeVersionShort = runtimeVersionNameParts[0] + '.' + runtimeVersionNameParts[1];
|
||||
|
||||
@@ -106,6 +106,20 @@ namespace Flax.Build
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exception when .NET SDK is missing.
|
||||
/// </summary>
|
||||
public sealed class MissingException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Init with a proper message.
|
||||
/// </summary>
|
||||
public MissingException()
|
||||
: base(string.IsNullOrEmpty(Configuration.Dotnet) ? $"Missing .NET SDK {MinimumVersion} (or higher)." : $"Missing .NET SDK {Configuration.Dotnet}.")
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<KeyValuePair<TargetPlatform, TargetArchitecture>, HostRuntime> _hostRuntimes = new();
|
||||
|
||||
/// <summary>
|
||||
@@ -223,7 +237,7 @@ namespace Flax.Build
|
||||
// We need to support two paths here:
|
||||
// 1. We are running an x64 binary and we are running on an arm64 host machine
|
||||
// 2. We are running an Arm64 binary and we are targeting an x64 host machine
|
||||
if (Flax.Build.Platforms.MacPlatform.GetProcessIsTranslated() || isRunningOnArm64Targetx64)
|
||||
if (Flax.Build.Platforms.MacPlatform.GetProcessIsTranslated() || isRunningOnArm64Targetx64)
|
||||
{
|
||||
rid = "osx-x64";
|
||||
dotnetPath = Path.Combine(dotnetPath, "x64");
|
||||
@@ -246,10 +260,9 @@ namespace Flax.Build
|
||||
Log.Warning($"Missing .NET SDK ({dotnetPath})");
|
||||
return;
|
||||
}
|
||||
if (dotnetSdkVersions == null)
|
||||
dotnetSdkVersions = GetVersions(Path.Combine(dotnetPath, "sdk"));
|
||||
if (dotnetRuntimeVersions == null)
|
||||
dotnetRuntimeVersions = GetVersions(Path.Combine(dotnetPath, "shared", "Microsoft.NETCore.App"));
|
||||
|
||||
dotnetSdkVersions = MergeVersions(dotnetSdkVersions, GetVersions(Path.Combine(dotnetPath, "sdk")));
|
||||
dotnetRuntimeVersions = MergeVersions(dotnetRuntimeVersions, GetVersions(Path.Combine(dotnetPath, "shared", "Microsoft.NETCore.App")));
|
||||
|
||||
dotnetSdkVersions = dotnetSdkVersions.Where(x => IsValidVersion(Path.Combine(dotnetPath, "sdk", x)));
|
||||
dotnetRuntimeVersions = dotnetRuntimeVersions.Where(x => IsValidVersion(Path.Combine(dotnetPath, "shared", "Microsoft.NETCore.App", x)));
|
||||
@@ -260,18 +273,23 @@ namespace Flax.Build
|
||||
Log.Verbose($"Found the following .NET SDK versions: {string.Join(", ", dotnetSdkVersions)}");
|
||||
Log.Verbose($"Found the following .NET runtime versions: {string.Join(", ", dotnetRuntimeVersions)}");
|
||||
|
||||
string dotnetSdkVersion = dotnetSdkVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major);
|
||||
string dotnetRuntimeVersion = dotnetRuntimeVersions.FirstOrDefault(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major);
|
||||
var dotnetSdkVersion = GetVersion(dotnetSdkVersions);
|
||||
var dotnetRuntimeVersion = GetVersion(dotnetRuntimeVersions);
|
||||
var minVer = string.IsNullOrEmpty(Configuration.Dotnet) ? MinimumVersion.ToString() : Configuration.Dotnet;
|
||||
if (string.IsNullOrEmpty(dotnetSdkVersion))
|
||||
dotnetSdkVersion = dotnetPath;
|
||||
if (dotnetSdkVersion == null && dotnetSdkVersions.Count() > 0)
|
||||
{
|
||||
Log.Warning($"Unsupported .NET SDK {dotnetSdkVersions.First()} version found. Minimum version required is .NET {MinimumVersion}.");
|
||||
if (dotnetSdkVersions.Any())
|
||||
Log.Warning($"Unsupported .NET SDK versions found: {string.Join(", ", dotnetSdkVersions)}. Minimum version required is .NET {minVer}.");
|
||||
else
|
||||
Log.Warning($"Missing .NET SDK. Minimum version required is .NET {minVer}.");
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(dotnetSdkVersion) || string.IsNullOrEmpty(dotnetRuntimeVersion))
|
||||
if (string.IsNullOrEmpty(dotnetRuntimeVersion))
|
||||
{
|
||||
Log.Warning("Missing .NET SDK");
|
||||
if (dotnetRuntimeVersions.Any())
|
||||
Log.Warning($"Unsupported .NET runtime versions found: {string.Join(", ", dotnetRuntimeVersions)}. Minimum version required is .NET {minVer}.");
|
||||
else
|
||||
Log.Warning($"Missing .NET runtime. Minimum version required is .NET {minVer}.");
|
||||
return;
|
||||
}
|
||||
RootPath = dotnetPath;
|
||||
@@ -434,7 +452,7 @@ namespace Flax.Build
|
||||
exists = Directory.Exists(path);
|
||||
|
||||
if (exists)
|
||||
_hostRuntimes[new KeyValuePair<TargetPlatform, TargetArchitecture>(platform, arch)] = new HostRuntime(platform, path);
|
||||
_hostRuntimes[new KeyValuePair<TargetPlatform, TargetArchitecture>(platform, arch)] = new HostRuntime(platform, Utilities.NormalizePath(path));
|
||||
return exists;
|
||||
}
|
||||
|
||||
@@ -445,6 +463,18 @@ namespace Flax.Build
|
||||
return Path.Combine(root, version);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> MergeVersions(IEnumerable<string> a, IEnumerable<string> b)
|
||||
{
|
||||
if (a == null || !a.Any())
|
||||
return b;
|
||||
if (b == null || !b.Any())
|
||||
return a;
|
||||
var result = new HashSet<string>();
|
||||
result.AddRange(a);
|
||||
result.AddRange(b);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Version ParseVersion(string version)
|
||||
{
|
||||
// Give precedence to final releases over release candidate / beta releases
|
||||
@@ -456,6 +486,8 @@ namespace Flax.Build
|
||||
}
|
||||
if (!Version.TryParse(version, out var ver))
|
||||
return null;
|
||||
if (ver.Build == -1)
|
||||
return new Version(ver.Major, ver.Minor);
|
||||
return new Version(ver.Major, ver.Minor, ver.Build, rev);
|
||||
}
|
||||
|
||||
@@ -466,9 +498,42 @@ namespace Flax.Build
|
||||
|
||||
private static string GetVersion(IEnumerable<string> versions)
|
||||
{
|
||||
return versions.OrderByDescending(ParseVersion)
|
||||
.Where(x => ParseVersion(x).Major >= MinimumVersion.Major && ParseVersion(x).Major <= MaximumVersion.Major)
|
||||
.FirstOrDefault();
|
||||
Version dotnetVer = null;
|
||||
int dotnetVerNum = -1;
|
||||
if (!string.IsNullOrEmpty(Configuration.Dotnet))
|
||||
{
|
||||
dotnetVer = ParseVersion(Configuration.Dotnet);
|
||||
if (int.TryParse(Configuration.Dotnet, out var tmp) && tmp >= MinimumVersion.Major)
|
||||
dotnetVerNum = tmp;
|
||||
}
|
||||
var sorted = versions.OrderByDescending(ParseVersion);
|
||||
foreach (var version in sorted)
|
||||
{
|
||||
var v = ParseVersion(version);
|
||||
|
||||
// Filter by version specified in command line
|
||||
if (dotnetVer != null)
|
||||
{
|
||||
if (dotnetVer.Major != v.Major)
|
||||
continue;
|
||||
if (dotnetVer.Minor != v.Minor)
|
||||
continue;
|
||||
if (dotnetVer.Revision != -1 && dotnetVer.Revision != v.Revision)
|
||||
continue;
|
||||
if (dotnetVer.Build != -1 && dotnetVer.Build != v.Build)
|
||||
continue;
|
||||
}
|
||||
else if (dotnetVerNum != -1)
|
||||
{
|
||||
if (dotnetVerNum != v.Major)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Filter by min/max versions supported by Flax.Build
|
||||
if (v.Major >= MinimumVersion.Major && v.Major <= MaximumVersion.Major)
|
||||
return version;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool IsValidVersion(string versionPath)
|
||||
|
||||
@@ -225,10 +225,24 @@ namespace Flax.Build
|
||||
[CommandLine("compiler", "<name>", "Overrides the compiler to use for building. Eg. v140 overrides the toolset when building for Windows.")]
|
||||
public static string Compiler = null;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the dotnet SDK version to use for the build. Eg. set to '7' to use .NET 7 even if .NET 8 is installed.
|
||||
/// </summary>
|
||||
[CommandLine("dotnet", "<ver>", "Specifies the dotnet SDK version to use for the build. Eg. set to '7' to use .NET 7 even if .NET 8 is installed.")]
|
||||
public static string Dotnet = null;
|
||||
|
||||
/// <summary>
|
||||
/// Custom configuration defines provided via command line for the build tool.
|
||||
/// </summary>
|
||||
public static List<string> CustomDefines = new List<string>();
|
||||
|
||||
internal static void PassArgs(ref string cmdLine)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Compiler))
|
||||
cmdLine += " -compiler=" + Compiler;
|
||||
if (!string.IsNullOrEmpty(Dotnet))
|
||||
cmdLine += " -dotnet=" + Dotnet;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -17,8 +17,7 @@ namespace Flax.Deploy
|
||||
var flaxBuildTool = Path.Combine(Globals.EngineRoot, buildPlatform == TargetPlatform.Windows ? "Binaries/Tools/Flax.Build.exe" : "Binaries/Tools/Flax.Build");
|
||||
var format = "-build -buildtargets={0} -log -logfile= -platform={1} -arch={2} -configuration={3}";
|
||||
var cmdLine = string.Format(format, target, platform, architecture, configuration);
|
||||
if (!string.IsNullOrEmpty(Configuration.Compiler))
|
||||
cmdLine += " -compiler=" + Configuration.Compiler;
|
||||
Configuration.PassArgs(ref cmdLine);
|
||||
|
||||
Log.Info($"Building {target} for {platform} {architecture} {configuration}...");
|
||||
int result = Utilities.Run(flaxBuildTool, cmdLine, null, root);
|
||||
|
||||
@@ -82,7 +82,10 @@ namespace Flax.Build
|
||||
{
|
||||
var engineProject = EngineTarget.EngineProject;
|
||||
if (engineProject != null && engineProject.Configuration != null && engineProject.Configuration.Count != 0)
|
||||
{
|
||||
CommandLine.Configure(typeof(EngineConfiguration), engineProject.Configuration);
|
||||
CommandLine.Configure(typeof(Configuration), engineProject.Configuration);
|
||||
}
|
||||
CommandLine.Configure(typeof(EngineConfiguration));
|
||||
}
|
||||
|
||||
@@ -90,7 +93,6 @@ namespace Flax.Build
|
||||
if (Configuration.Mutex)
|
||||
{
|
||||
singleInstanceMutex = new Mutex(true, "Flax.Build", out var oneInstanceMutexCreated);
|
||||
|
||||
if (!oneInstanceMutexCreated)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -172,8 +172,7 @@ namespace Flax.Build.Projects.VisualStudio
|
||||
configuration.Configuration,
|
||||
configuration.Platform,
|
||||
target.Name);
|
||||
if (!string.IsNullOrEmpty(Configuration.Compiler))
|
||||
cmdLine += " -compiler=" + Configuration.Compiler;
|
||||
Configuration.PassArgs(ref cmdLine);
|
||||
|
||||
vcProjectFileContent.AppendLine(string.Format(" <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='{0}'\">", configuration.Name));
|
||||
if (platform is IVisualStudioProjectCustomizer customizer)
|
||||
|
||||
@@ -731,8 +731,7 @@ namespace Flax.Build.Projects.VisualStudio
|
||||
configuration.Configuration,
|
||||
configuration.Platform,
|
||||
configuration.Target);
|
||||
if (!string.IsNullOrEmpty(Configuration.Compiler))
|
||||
cmdLine += " -compiler=" + Configuration.Compiler;
|
||||
Configuration.PassArgs(ref cmdLine);
|
||||
|
||||
str.AppendLine(string.Format(" <Exec Command=\"{0} {1}\" Condition=\"'$(Configuration)|$(Platform)'=='{2}'\"/>", cmdLine, extraArgs, configuration.Name));
|
||||
}
|
||||
|
||||
@@ -201,6 +201,8 @@ namespace Flax.Build.Projects.VisualStudioCode
|
||||
json.AddUnnamedField(string.Format("-buildTargets={0}", target.Name));
|
||||
if (!string.IsNullOrEmpty(Configuration.Compiler))
|
||||
json.AddUnnamedField(string.Format("-compiler={0}", Configuration.Compiler));
|
||||
if (!string.IsNullOrEmpty(Configuration.Dotnet))
|
||||
json.AddUnnamedField(string.Format("-dotnet={0}", Configuration.Dotnet));
|
||||
}
|
||||
json.EndArray();
|
||||
|
||||
@@ -228,6 +230,8 @@ namespace Flax.Build.Projects.VisualStudioCode
|
||||
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
|
||||
if (!string.IsNullOrEmpty(Configuration.Compiler))
|
||||
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
|
||||
if (!string.IsNullOrEmpty(Configuration.Dotnet))
|
||||
json.AddUnnamedField(string.Format("-dotnet={0}", Configuration.Dotnet));
|
||||
}
|
||||
json.EndArray();
|
||||
|
||||
@@ -255,6 +259,8 @@ namespace Flax.Build.Projects.VisualStudioCode
|
||||
json.AddUnnamedField(string.Format("--buildTargets={0}", target.Name));
|
||||
if (!string.IsNullOrEmpty(Configuration.Compiler))
|
||||
json.AddUnnamedField(string.Format("--compiler={0}", Configuration.Compiler));
|
||||
if (!string.IsNullOrEmpty(Configuration.Dotnet))
|
||||
json.AddUnnamedField(string.Format("-dotnet={0}", Configuration.Dotnet));
|
||||
}
|
||||
json.EndArray();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user