Compare commits

...

34 Commits

Author SHA1 Message Date
mafiesto4 128cad49b9 Bump up version number 2021-08-08 21:46:24 +02:00
mafiesto4 65f9e9d0aa Fix error 2021-08-08 20:58:36 +02:00
mafiesto4 36df9757b1 Add creating Scene Graph nodes for actors inheriting from some shared custom types 2021-08-08 20:58:19 +02:00
mafiesto4 a0e1c7c37e Add support for creating custom BoxVolume type in C# 2021-08-08 20:19:43 +02:00
mafiesto4 847641f655 Fix crash when spawning C# object that inherits from abstract C++ class 2021-08-08 19:10:51 +02:00
mafiesto4 cdca5b4a28 Fix undo for missing actor children and scripts when doing Convert action 2021-08-08 18:38:26 +02:00
mafiesto4 6609425880 Fix creating prefab in Editor from selection in Prefab window 2021-08-08 17:25:18 +02:00
mafiesto4 6ac0d5d3f4 Merge branch 'blep-bugfix_crash_2riderinstall' 2021-08-08 16:40:56 +02:00
mafiesto4 bc46259286 Merge branch 'bugfix_crash_2riderinstall' of git://github.com/blep/FlaxEngine into blep-bugfix_crash_2riderinstall 2021-08-08 16:40:41 +02:00
mafiesto4 50bccd52e7 Fix startup failure on older CPUs that don't support invariant TSC
#580
2021-08-08 16:38:28 +02:00
mafiesto4 84cca1ae98 Fix missing mesh collider vertices transformation for navmesh building 2021-08-08 16:20:48 +02:00
mafiesto4 71cf758ccf Fix crash when cooking collision data for multi-mesh models 2021-08-08 16:18:29 +02:00
mafiesto4 edf98acae2 Undo unwanted change 2021-08-08 16:04:07 +02:00
mafiesto4 a085531fda Add build preset and target names to access for Game Cooker extending 2021-08-08 16:02:48 +02:00
mafiesto4 6b532d2fbc Add CookingData for C# editor to extend the cooking process 2021-08-08 16:01:58 +02:00
Baptiste Lepilleur 7862ff4670 Fixed crash on startup when 2 Rider installations are detected 2021-08-07 21:43:58 +02:00
mafiesto4 bc27890818 Merge branch 'marynate-PR-global-local-crash' 2021-08-07 16:52:48 +02:00
mafiesto4 1c5754beff Merge branch 'PR-global-local-crash' of git://github.com/marynate/FlaxEngine into marynate-PR-global-local-crash 2021-08-07 16:52:39 +02:00
mafiesto4 054def3d13 Fix crash in build tool if there is no valid project to pick 2021-08-07 16:46:39 +02:00
mafiesto4 e6d5d5330e Fix CharacterController minimum size checks to prevent crashes if values are too small 2021-08-07 15:52:49 +02:00
mafiesto4 f430803ecc Merge branch 'thallard-dev' 2021-08-07 15:33:12 +02:00
mafiesto4 fc762fdbdb Merge branch 'dev' of git://github.com/thallard/FlaxEngine into thallard-dev 2021-08-07 15:29:01 +02:00
marynate 6908aa4a8a Catch potential runtime error from locale::global 2021-08-07 14:20:38 +08:00
Erdroy 6c70f2e14f Fix editor crash on startup when Rider 2021.1 is installed 2021-08-06 18:58:19 +02:00
thallard 3bc489a7b5 Replace string variable check by an enum 2021-08-06 15:50:30 +02:00
mafiesto4 d22380c7cf Add warnings when cooking collision with empty mesh data 2021-08-06 15:07:50 +02:00
mafiesto4 c4102ba884 Fix compiling C#-only game scripts without native platform tools installed 2021-08-06 13:17:23 +02:00
thallard baee3a60a6 Added tick when a button is selected 2021-08-06 11:47:50 +02:00
thallard 5e2b4adff3 Removed useless static path thanks to @jb-perrier 2021-08-06 00:21:27 +02:00
thallard 78d668c599 Change enum and variable name 2021-08-06 00:07:44 +02:00
thallard e8b867430f Remplace string variable by enum 2021-08-05 23:38:08 +02:00
thallard 1426b4ca49 Removed useless debug logs 2021-08-05 23:05:27 +02:00
thallard 9682ac4643 Merge branch 'master' of https://github.com/FlaxEngine/FlaxEngine into dev 2021-08-05 22:37:22 +02:00
thallard d95cd24b76 Added functionality to order items by name 2021-08-05 22:24:01 +02:00
32 changed files with 292 additions and 106 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
"Version": {
"Major": 1,
"Minor": 2,
"Build": 6222
"Build": 6223
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.",
@@ -7,7 +7,8 @@
void RegisterGameCookingStart(GameCooker::EventType type)
{
auto platform = ToString(GameCooker::GetCurrentData().Platform);
auto& data = *GameCooker::GetCurrentData();
auto platform = ToString(data.Platform);
if (type == GameCooker::EventType::BuildStarted)
{
EditorAnalytics::SendEvent("Actions", "GameCooker.Start", platform);
+36 -4
View File
@@ -27,6 +27,22 @@ namespace FlaxEditor.Content.GUI
List,
}
/// <summary>
/// The method sort for items.
/// </summary>
public enum SortType
{
/// <summary>
/// The classic alphabetic sort method (A-Z).
/// </summary>
AlphabeticOrder,
/// <summary>
/// The reverse alphabetic sort method (Z-A).
/// </summary>
AlphabeticReverse
}
/// <summary>
/// Main control for <see cref="ContentWindow"/> used to present collection of <see cref="ContentItem"/>.
/// </summary>
@@ -218,8 +234,9 @@ namespace FlaxEditor.Content.GUI
/// Shows the items collection in the view.
/// </summary>
/// <param name="items">The items to show.</param>
/// <param name="sortType">The sort method for items.</param>
/// <param name="additive">If set to <c>true</c> items will be added to the current selection. Otherwise selection will be cleared before.</param>
public void ShowItems(List<ContentItem> items, bool additive = false)
public void ShowItems(List<ContentItem> items, SortType sortType, bool additive = false)
{
if (items == null)
throw new ArgumentNullException();
@@ -249,9 +266,24 @@ namespace FlaxEditor.Content.GUI
items[i].AddReference(this);
}
// Sort items
_children.Sort();
// Sort items depending on sortMethod parameter
_children.Sort(((control, control1) =>
{
if (sortType == SortType.AlphabeticReverse)
{
if (control.CompareTo(control1) > 0)
{
return -1;
}
if (control.CompareTo(control1) == 0)
{
return 0;
}
return 1;
}
return control.CompareTo(control1);
}));
// Unload and perform UI layout
IsLayoutLocked = wasLayoutLocked;
PerformLayout();
+26 -20
View File
@@ -3,11 +3,11 @@
#pragma once
#include "Engine/Core/Log.h"
#include "Engine/Core/Enums.h"
#include "Engine/Core/Types/Guid.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Collections/HashSet.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Core/Types/Guid.h"
#include "Engine/Scripting/ScriptingObject.h"
class GameCooker;
class PlatformTools;
@@ -125,47 +125,60 @@ extern FLAXENGINE_API const Char* ToString(const BuildConfiguration configuratio
/// <summary>
/// Game cooking temporary data.
/// </summary>
struct FLAXENGINE_API CookingData
API_CLASS(Sealed, Namespace="FlaxEditor") class FLAXENGINE_API CookingData : public PersistentScriptingObject
{
DECLARE_SCRIPTING_TYPE(CookingData);
public:
/// <summary>
/// The platform.
/// </summary>
BuildPlatform Platform;
API_FIELD(ReadOnly) BuildPlatform Platform;
/// <summary>
/// The configuration.
/// </summary>
BuildConfiguration Configuration;
API_FIELD(ReadOnly) BuildConfiguration Configuration;
/// <summary>
/// The options.
/// </summary>
BuildOptions Options;
API_FIELD(ReadOnly) BuildOptions Options;
/// <summary>
/// The name of build preset used for cooking (can be used by editor and game plugins).
/// </summary>
API_FIELD(ReadOnly) String Preset;
/// <summary>
/// The name of build preset target used for cooking (can be used by editor and game plugins).
/// </summary>
API_FIELD(ReadOnly) String PresetTarget;
/// <summary>
/// The list of custom defines passed to the build tool when compiling project scripts. Can be used in build scripts for configuration (Configuration.CustomDefines).
/// </summary>
Array<String> CustomDefines;
API_FIELD(ReadOnly) Array<String> CustomDefines;
/// <summary>
/// The original output path (actual OutputPath could be modified by the Platform Tools or a plugin for additional layout customizations or packaging). This path is preserved.
/// </summary>
String OriginalOutputPath;
API_FIELD(ReadOnly) String OriginalOutputPath;
/// <summary>
/// The output path for data files (Content, Mono, etc.).
/// </summary>
String DataOutputPath;
API_FIELD(ReadOnly) String DataOutputPath;
/// <summary>
/// The output path for binaries (native executable and native code libraries).
/// </summary>
String NativeCodeOutputPath;
API_FIELD(ReadOnly) String NativeCodeOutputPath;
/// <summary>
/// The output path for binaries (C# code libraries).
/// </summary>
String ManagedCodeOutputPath;
API_FIELD(ReadOnly) String ManagedCodeOutputPath;
/// <summary>
/// The platform tools.
@@ -248,7 +261,7 @@ public:
/// </summary>
HashSet<Guid> Assets;
struct BinaryModule
struct BinaryModuleInfo
{
String Name;
String NativePath;
@@ -258,17 +271,10 @@ public:
/// <summary>
/// The binary modules used in the build. Valid after scripts compilation step. This list includes game, all plugins modules and engine module.
/// </summary>
Array<BinaryModule, InlinedAllocation<64>> BinaryModules;
Array<BinaryModuleInfo, InlinedAllocation<64>> BinaryModules;
public:
void Init()
{
RootAssets.Clear();
Assets.Clear();
Stats = Statistics();
}
/// <summary>
/// Gets the absolute path to the Platform Data folder that contains the binary files used by the current build configuration.
/// </summary>
+18 -9
View File
@@ -68,7 +68,7 @@ namespace GameCookerImpl
String ProgressMsg;
float ProgressValue;
CookingData Data;
CookingData* Data = nullptr;
Array<GameCooker::BuildStep*> Steps;
Dictionary<BuildPlatform, PlatformTools*> Tools;
@@ -154,6 +154,11 @@ CookingData::Statistics::Statistics()
ContentSizeMB = 0;
}
CookingData::CookingData(const SpawnParams& params)
: PersistentScriptingObject(params)
{
}
String CookingData::GetGameBinariesPath() const
{
const Char* archDir;
@@ -179,7 +184,7 @@ String CookingData::GetGameBinariesPath() const
return String::Empty;
}
return GetPlatformBinariesRoot() / TEXT("Game") / archDir / ToString(Configuration);
return GetPlatformBinariesRoot() / TEXT("Game") / archDir / ::ToString(Configuration);
}
String CookingData::GetPlatformBinariesRoot() const
@@ -239,7 +244,7 @@ public:
GameCookerService GameCookerServiceInstance;
const CookingData& GameCooker::GetCurrentData()
CookingData* GameCooker::GetCurrentData()
{
return Data;
}
@@ -313,7 +318,7 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
return result;
}
void GameCooker::Build(BuildPlatform platform, BuildConfiguration configuration, const StringView& outputPath, BuildOptions options, const Array<String>& customDefines)
void GameCooker::Build(BuildPlatform platform, BuildConfiguration configuration, const StringView& outputPath, BuildOptions options, const Array<String>& customDefines, const StringView& preset, const StringView& presetTarget)
{
if (IsRunning())
{
@@ -331,12 +336,14 @@ void GameCooker::Build(BuildPlatform platform, BuildConfiguration configuration,
CancelFlag = 0;
ProgressMsg.Clear();
ProgressValue = 1.0f;
CookingData& data = Data;
data.Init();
Data = New<CookingData>();
CookingData& data = *Data;
data.Tools = tools;
data.Platform = platform;
data.Configuration = configuration;
data.Options = options;
data.Preset = preset;
data.PresetTarget = presetTarget;
data.CustomDefines = customDefines;
data.OriginalOutputPath = outputPath;
FileSystem::NormalizePath(data.OriginalOutputPath);
@@ -448,7 +455,7 @@ void GameCookerImpl::OnCollectAssets(HashSet<Guid>& assets)
bool GameCookerImpl::Build()
{
CookingData& data = Data;
CookingData& data = *Data;
LOG(Info, "Starting Game Cooker...");
LOG(Info, "Platform: {0}, Configuration: {2}, Options: {1}", ::ToString(data.Platform), (int32)data.Options, ::ToString(data.Configuration));
LOG(Info, "Output Path: {0}", data.OriginalOutputPath);
@@ -472,7 +479,7 @@ bool GameCookerImpl::Build()
CallEvent(GameCooker::EventType::BuildStarted);
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
Steps[stepIndex]->OnBuildStarted(data);
Data.Tools->OnBuildStarted(data);
data.Tools->OnBuildStarted(data);
data.InitProgress(Steps.Count());
// Execute all steps in a sequence
@@ -511,10 +518,12 @@ bool GameCookerImpl::Build()
}
IsRunning = false;
CancelFlag = 0;
Data.Tools->OnBuildEnded(data, failed);
data.Tools->OnBuildEnded(data, failed);
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
Steps[stepIndex]->OnBuildEnded(data, failed);
CallEvent(failed ? GameCooker::EventType::BuildFailed : GameCooker::EventType::BuildDone);
Delete(Data);
Data = nullptr;
return failed;
}
+4 -2
View File
@@ -56,7 +56,7 @@ public:
/// <summary>
/// Gets the current build data. Valid only during active build process.
/// </summary>
static const CookingData& GetCurrentData();
API_PROPERTY() static CookingData* GetCurrentData();
/// <summary>
/// Determines whether game building is running.
@@ -83,7 +83,9 @@ public:
/// <param name="outputPath">The output path (output directory).</param>
/// <param name="options">The build options.</param>
/// <param name="customDefines">The list of custom defines passed to the build tool when compiling project scripts. Can be used in build scripts for configuration (Configuration.CustomDefines).</param>
API_FUNCTION() static void Build(BuildPlatform platform, BuildConfiguration configuration, const StringView& outputPath, BuildOptions options, const Array<String>& customDefines);
/// <param name="preset">The name of build preset used for cooking (can be used by editor and game plugins).</param>
/// <param name="presetTarget">The name of build preset target used for cooking (can be used by editor and game plugins).</param>
API_FUNCTION() static void Build(BuildPlatform platform, BuildConfiguration configuration, const StringView& outputPath, BuildOptions options, const Array<String>& customDefines, const StringView& preset = StringView::Empty, const StringView& presetTarget = StringView::Empty);
/// <summary>
/// Sends a cancel event to the game building service.
+1 -1
View File
@@ -1189,7 +1189,7 @@ namespace FlaxEditor
return true;
}
Windows.GameCookerWin.Build(target);
Windows.GameCookerWin.Build(preset, target);
}
Windows.GameCookerWin.ExitOnBuildQueueEnd();
+15 -2
View File
@@ -1,6 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using FlaxEditor.Actions;
using FlaxEditor.Content;
@@ -49,8 +50,20 @@ namespace FlaxEditor.Modules
/// </remarks>
public void CreatePrefab()
{
// Check selection
var selection = Editor.SceneEditing.Selection;
CreatePrefab(Editor.SceneEditing.Selection);
}
/// <summary>
/// Starts the creating prefab for the selected actor by showing the new item creation dialog in <see cref="ContentWindow"/>.
/// </summary>
/// <remarks>
/// To create prefab manually (from code) use <see cref="PrefabManager.CreatePrefab"/> method.
/// </remarks>
/// <param name="selection">The scene selection to use.</param>
public void CreatePrefab(List<SceneGraphNode> selection)
{
if (selection == null)
selection = Editor.SceneEditing.Selection;
if (selection.Count == 1 && selection[0] is ActorNode actorNode && actorNode.CanCreatePrefab)
{
CreatePrefab(actorNode.Actor);
+21 -27
View File
@@ -216,7 +216,7 @@ namespace FlaxEditor.Modules
}
}
private void OnDirty(IEnumerable<SceneGraphNode> objects)
private void OnDirty(List<SceneGraphNode> objects)
{
var options = Editor.Options.Options;
var isPlayMode = Editor.StateMachine.IsPlayMode;
@@ -236,7 +236,7 @@ namespace FlaxEditor.Modules
{
foreach (var obj in objects)
{
if (obj is ActorNode node && node.Actor.Scene && node.AffectsNavigationWithChildren)
if (obj is ActorNode node && node.Actor && node.Actor.Scene && node.AffectsNavigationWithChildren)
{
var bounds = node.Actor.BoxWithChildren;
Navigation.BuildNavMesh(node.Actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs);
@@ -303,26 +303,28 @@ namespace FlaxEditor.Modules
{
if (!Editor.SceneEditing.HasSthSelected || !(Editor.SceneEditing.Selection[0] is ActorNode))
return;
if (Level.IsAnySceneLoaded == false)
throw new InvalidOperationException("Cannot spawn actor when no scene is loaded.");
var actionList = new IUndoAction[4];
Actor old = ((ActorNode)Editor.SceneEditing.Selection[0]).Actor;
Actor actor = (Actor)FlaxEngine.Object.New(to);
var oldNode = (ActorNode)Editor.SceneEditing.Selection[0];
var old = oldNode.Actor;
var actor = (Actor)FlaxEngine.Object.New(to);
var parent = old.Parent;
var orderInParent = old.OrderInParent;
// Steps:
// - deselect old actor
// - destroy old actor
// - spawn new actor
// - select new actor
SelectionDeleteBegin?.Invoke();
actionList[0] = new SelectionChangeAction(Selection.ToArray(), new SceneGraphNode[0], OnSelectionUndo);
actionList[0].Do();
actionList[1] = new DeleteActorsAction(new List<SceneGraphNode>
{
Editor.Instance.Scene.GetActorNode(old)
});
actionList[1].Do();
actionList[1] = new DeleteActorsAction(oldNode.BuildAllNodes().Where(x => x.CanDelete).ToList());
SelectionDeleteEnd?.Invoke();
@@ -345,17 +347,12 @@ namespace FlaxEditor.Modules
actor.StaticFlags = StaticFlags.None;
// Move children
for (var i = old.ScriptsCount - 1; i >= 0; i--)
{
var script = old.Scripts[i];
script.Actor = actor;
Guid newid = Guid.NewGuid();
FlaxEngine.Object.Internal_ChangeID(FlaxEngine.Object.GetUnmanagedPtr(script), ref newid);
}
for (var i = old.Children.Length - 1; i >= 0; i--)
{
old.Children[i].Parent = actor;
}
var scripts = old.Scripts;
for (var i = scripts.Length - 1; i >= 0; i--)
scripts[i].Actor = actor;
var children = old.Children;
for (var i = children.Length - 1; i >= 0; i--)
children[i].Parent = actor;
var actorNode = Editor.Instance.Scene.GetActorNode(actor);
if (actorNode == null)
@@ -364,16 +361,13 @@ namespace FlaxEditor.Modules
actorNode.PostSpawn();
Editor.Scene.MarkSceneEdited(actor.Scene);
actionList[2] = new DeleteActorsAction(new List<SceneGraphNode>
{
actorNode
}, true);
actionList[1].Do();
actionList[2] = new DeleteActorsAction(actorNode.BuildAllNodes().Where(x => x.CanDelete).ToList(), true);
actionList[3] = new SelectionChangeAction(new SceneGraphNode[0], new SceneGraphNode[] { actorNode }, OnSelectionUndo);
actionList[3].Do();
var actions = new MultiUndoAction(actionList);
Undo.AddAction(actions);
Undo.AddAction(new MultiUndoAction(actionList, "Convert actor"));
SpawnEnd?.Invoke();
+16 -2
View File
@@ -134,7 +134,8 @@ namespace FlaxEditor.SceneGraph
try
{
// Try to pick custom node type for that actor object
if (CustomNodesTypes.TryGetValue(actor.GetType(), out customType))
var type = actor.GetType();
if (CustomNodesTypes.TryGetValue(type, out customType))
{
// Use custom type
_sharedArgsContainer[0] = actor;
@@ -142,8 +143,21 @@ namespace FlaxEditor.SceneGraph
}
else
{
// Check if the actor type inherits from one of the custom types but doesn't provide own node type
foreach (var e in CustomNodesTypes)
{
if (e.Key.IsAssignableFrom(type))
{
// Use custom type
_sharedArgsContainer[0] = actor;
result = (ActorNode)Activator.CreateInstance(e.Value, _sharedArgsContainer);
break;
}
}
// Use default type for actors
result = new ActorNode(actor);
if (result == null)
result = new ActorNode(actor);
}
// Build children
@@ -125,5 +125,33 @@ namespace FlaxEditor.SceneGraph
FillTree(target, result);
}
}
/// <summary>
/// Builds the list made of all nodes in the input scene tree root and child tree. The result collection contains all nodes in the tree.
/// </summary>
/// <param name="node">The node.</param>
/// <returns>The result.</returns>
public static List<SceneGraphNode> BuildAllNodes<T>(this T node)
where T : SceneGraphNode
{
var list = new List<SceneGraphNode>();
BuildAllNodes(node, list);
return list;
}
/// <summary>
/// Builds the list made of all nodes in the input scene tree root and child tree. The result collection contains all nodes in the tree.
/// </summary>
/// <param name="node">The node.</param>
/// <param name="result">The result.</param>
public static void BuildAllNodes<T>(this T node, List<SceneGraphNode> result)
where T : SceneGraphNode
{
if (node == null || result == null)
throw new ArgumentNullException();
result.Clear();
result.Add(node);
FillTree(node, result);
}
}
}
@@ -135,10 +135,15 @@ bool sortInstallations(RiderInstallation* const& i1, RiderInstallation* const& i
int32 version2[3] = { 0 };
StringUtils::Parse(values1[0].Get(), &version1[0]);
StringUtils::Parse(values1[1].Get(), &version1[1]);
StringUtils::Parse(values1[2].Get(), &version1[2]);
if(values1.Count() > 2)
StringUtils::Parse(values1[2].Get(), &version1[2]);
StringUtils::Parse(values2[0].Get(), &version2[0]);
StringUtils::Parse(values2[1].Get(), &version2[1]);
StringUtils::Parse(values2[2].Get(), &version2[2]);
if(values2.Count() > 2)
StringUtils::Parse(values2[2].Get(), &version2[2]);
// Compare by MAJOR.MINOR.BUILD
if (version1[0] == version2[0])
@@ -135,6 +135,7 @@ namespace FlaxEditor.Actions
node.Delete();
}
_nodeParents.Clear();
FlaxEngine.Scripting.FlushRemovedObjects();
}
/// <summary>
@@ -109,7 +109,7 @@ namespace FlaxEditor.Windows.Assets
contextMenu.AddSeparator();
b = contextMenu.AddButton("Create Prefab", Editor.Prefabs.CreatePrefab);
b = contextMenu.AddButton("Create Prefab", () => Editor.Prefabs.CreatePrefab(Selection));
b.Enabled = isSingleActorSelected &&
(Selection[0] as ActorNode).CanCreatePrefab &&
Editor.Windows.ContentWin.CurrentViewFolder.CanHaveAssets;
@@ -230,7 +230,7 @@ namespace FlaxEditor.Windows
}
_view.IsSearching = true;
_view.ShowItems(items);
_view.ShowItems(items, _sortType);
}
private void UpdateItemsSearchFilter(ContentFolder folder, List<ContentItem> items, bool[] filters)
+29 -2
View File
@@ -39,6 +39,7 @@ namespace FlaxEditor.Windows
private TextBox _foldersSearchBox;
private TextBox _itemsSearchBox;
private ViewDropdown _viewDropdown;
private SortType _sortType;
private RootContentTreeNode _root;
@@ -215,6 +216,20 @@ namespace FlaxEditor.Windows
filterButton.Checked = _viewDropdown.IsSelected(filterButton.Text);
}
};
var sortBy = menu.AddChildMenu("Sort by");
sortBy.ContextMenu.AddButton("Alphabetic Order", OnSortByButtonClicked).Tag = SortType.AlphabeticOrder;
sortBy.ContextMenu.AddButton("Alphabetic Reverse", OnSortByButtonClicked).Tag = SortType.AlphabeticReverse;
sortBy.ContextMenu.VisibleChanged += control =>
{
if (!control.Visible)
return;
foreach (var item in ((ContextMenu)control).Items)
{
if (item is ContextMenuButton button)
button.Checked = _sortType == (SortType)button.Tag;
}
};
return menu;
}
@@ -230,6 +245,18 @@ namespace FlaxEditor.Windows
_viewDropdown.OnClicked(i);
}
private void OnSortByButtonClicked(ContextMenuButton button)
{
switch ((SortType)button.Tag)
{
case SortType.AlphabeticOrder: _sortType = SortType.AlphabeticOrder;
break;
case SortType.AlphabeticReverse: _sortType = SortType.AlphabeticReverse;
break;
}
RefreshView(SelectedNode);
}
/// <summary>
/// Shows popup dialog with UI to rename content item.
/// </summary>
@@ -701,12 +728,12 @@ namespace FlaxEditor.Windows
items.Add(node.Folder);
}
}
_view.ShowItems(items);
_view.ShowItems(items, _sortType);
}
else
{
// Show folder contents
_view.ShowItems(target.Folder.Children);
_view.ShowItems(target.Folder.Children, _sortType);
}
}
+27 -10
View File
@@ -446,12 +446,18 @@ namespace FlaxEditor.Windows
}
}
private struct QueueItem
{
public string PresetName;
public BuildTarget Target;
}
private PresetsColumn _presets;
private TargetsColumn _targets;
private int _selectedPresetIndex = -1;
private int _selectedTargetIndex = -1;
private CustomEditorPresenter _targetSettings;
private readonly Queue<BuildTarget> _buildingQueue = new Queue<BuildTarget>();
private readonly Queue<QueueItem> _buildingQueue = new Queue<QueueItem>();
private string _preBuildAction;
private string _postBuildAction;
private BuildPreset[] _data;
@@ -489,14 +495,14 @@ namespace FlaxEditor.Windows
{
// Execute pre-build action
if (!string.IsNullOrEmpty(_preBuildAction))
ExecueAction(_preBuildAction);
ExecuteAction(_preBuildAction);
_preBuildAction = null;
}
else if (type == GameCooker.EventType.BuildDone)
{
// Execute post-build action
if (!string.IsNullOrEmpty(_postBuildAction))
ExecueAction(_postBuildAction);
ExecuteAction(_postBuildAction);
_postBuildAction = null;
}
else if (type == GameCooker.EventType.BuildFailed)
@@ -506,7 +512,7 @@ namespace FlaxEditor.Windows
}
}
private void ExecueAction(string action)
private void ExecuteAction(string action)
{
string command = "echo off\ncd \"" + Globals.ProjectFolder.Replace('/', '\\') + "\"\necho on\n" + action;
command = command.Replace("\n", "\r\n");
@@ -545,21 +551,30 @@ namespace FlaxEditor.Windows
Editor.Log("Building all targets");
foreach (var e in preset.Targets)
{
_buildingQueue.Enqueue(e.DeepClone());
_buildingQueue.Enqueue(new QueueItem
{
PresetName = preset.Name,
Target = e.DeepClone(),
});
}
}
/// <summary>
/// Builds the target.
/// </summary>
/// <param name="preset">The preset.</param>
/// <param name="target">The target.</param>
public void Build(BuildTarget target)
public void Build(BuildPreset preset, BuildTarget target)
{
if (target == null)
throw new ArgumentNullException(nameof(target));
Editor.Log("Building target");
_buildingQueue.Enqueue(target.DeepClone());
_buildingQueue.Enqueue(new QueueItem
{
PresetName = preset.Name,
Target = target.DeepClone(),
});
}
private void BuildTarget()
@@ -569,7 +584,8 @@ namespace FlaxEditor.Windows
if (_data[_selectedPresetIndex].Targets == null || _data[_selectedPresetIndex].Targets.Length <= _selectedTargetIndex)
return;
Build(_data[_selectedPresetIndex].Targets[_selectedTargetIndex]);
var preset = _data[_selectedPresetIndex];
Build(preset, preset.Targets[_selectedTargetIndex]);
}
private void BuildAllTargets()
@@ -825,12 +841,13 @@ namespace FlaxEditor.Windows
{
if (_buildingQueue.Count > 0)
{
var target = _buildingQueue.Dequeue();
var item = _buildingQueue.Dequeue();
var target = item.Target;
_preBuildAction = target.PreBuildAction;
_postBuildAction = target.PostBuildAction;
GameCooker.Build(target.Platform, target.Mode, target.Output, BuildOptions.None, target.CustomDefines);
GameCooker.Build(target.Platform, target.Mode, target.Output, BuildOptions.None, target.CustomDefines, item.PresetName, target.Name);
}
else if (_exitOnBuildEnd)
{
+5
View File
@@ -27,6 +27,11 @@ void BoxVolume::SetSize(const Vector3& value)
#include "Engine/Debug/DebugDraw.h"
Color BoxVolume::GetWiresColor()
{
return Color::White;
}
void BoxVolume::OnDebugDraw()
{
const Color color = GetWiresColor();
+2 -2
View File
@@ -10,7 +10,7 @@
/// </summary>
API_CLASS(Abstract) class FLAXENGINE_API BoxVolume : public Actor
{
DECLARE_SCENE_OBJECT_ABSTRACT(BoxVolume);
DECLARE_SCENE_OBJECT(BoxVolume);
protected:
Vector3 _size;
@@ -47,7 +47,7 @@ protected:
}
#if USE_EDITOR
virtual Color GetWiresColor() = 0;
virtual Color GetWiresColor();
#endif
public:
+1
View File
@@ -46,6 +46,7 @@ typedef Dictionary<Guid, Actor*, HeapAllocation> ActorsLookup;
#define DECLARE_SCENE_OBJECT_ABSTRACT(type) \
DECLARE_SCRIPTING_TYPE_NO_SPAWN(type); \
static type* Spawn(const SpawnParams& params) { return nullptr; } \
explicit type(const SpawnParams& params)
#define DECLARE_SCENE_OBJECT_NO_SPAWN(type) \
+6 -1
View File
@@ -189,7 +189,12 @@ void LocalizationService::OnLocalizationChanged()
localeName[currentCulture.Length() + 5] = '8';
localeName[currentCulture.Length() + 6] = 0;
}
std::locale::global(std::locale(localeName));
try
{
std::locale::global(std::locale(localeName));
}
catch (std::runtime_error const&) {}
catch (...) {}
}
#endif
@@ -258,6 +258,11 @@ struct NavigationSceneRasterization
collisionData->ExtractGeometry(vb, ib);
Matrix meshColliderToWorld;
meshCollider->GetLocalToWorldMatrix(meshColliderToWorld);
for(auto& v : vb)
Vector3::Transform(v, meshColliderToWorld, v);
e.RasterizeTriangles();
}
else if (const auto* splineCollider = dynamic_cast<SplineCollider*>(actor))
@@ -105,7 +105,14 @@ void CharacterController::SetStepOffset(float value)
_stepOffset = value;
if (_controller)
_controller->setStepOffset(value);
{
const float scaling = _cachedScale.GetAbsolute().MaxValue();
const float contactOffset = Math::Max(_contactOffset, ZeroTolerance);
const float minSize = 0.001f;
const float height = Math::Max(Math::Abs(_height) * scaling, minSize);
const float radius = Math::Max(Math::Abs(_radius) * scaling - contactOffset, minSize);
_controller->setStepOffset(Math::Min(value, height + radius * 2.0f - minSize));
}
}
void CharacterController::SetUpDirection(const Vector3& up)
@@ -223,7 +230,6 @@ void CharacterController::CreateController()
desc.slopeLimit = Math::Cos(_slopeLimit * DegreesToRadians);
desc.nonWalkableMode = static_cast<PxControllerNonWalkableMode::Enum>(_nonWalkableMode);
desc.climbingMode = PxCapsuleClimbingMode::eEASY;
desc.stepOffset = _stepOffset;
if (Material && !Material->WaitForLoaded())
desc.material = ((PhysicalMaterial*)Material->Instance)->GetPhysXMaterial();
else
@@ -233,6 +239,7 @@ void CharacterController::CreateController()
const float minSize = 0.001f;
desc.height = Math::Max(Math::Abs(_height) * scaling, minSize);
desc.radius = Math::Max(Math::Abs(_radius) * scaling - desc.contactOffset, minSize);
desc.stepOffset = Math::Min(_stepOffset, desc.height + desc.radius * 2.0f - minSize);
// Create controller
_controller = (PxCapsuleController*)Physics::GetControllerManager()->createController(desc);
+6 -2
View File
@@ -24,6 +24,8 @@
bool CollisionCooking::CookConvexMesh(CookingInput& input, BytesContainer& output)
{
ENSURE_CAN_COOK;
if (input.VertexCount == 0)
LOG(Warning, "Empty mesh data for collision cooking.");
// Init options
PxConvexMeshDesc desc;
@@ -62,6 +64,8 @@ bool CollisionCooking::CookConvexMesh(CookingInput& input, BytesContainer& outpu
bool CollisionCooking::CookTriangleMesh(CookingInput& input, BytesContainer& output)
{
ENSURE_CAN_COOK;
if (input.VertexCount == 0 || input.IndexCount == 0)
LOG(Warning, "Empty mesh data for collision cooking.");
// Init options
PxTriangleMeshDesc desc;
@@ -274,11 +278,11 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali
// Combine meshes into one
int32 vCount = 0;
for (int32 i = 0; i < vertexCounts.Count(); i++)
vCount += vertexCounts[0];
vCount += vertexCounts[i];
finalVertexData.Allocate(vCount);
int32 iCount = 0;
for (int32 i = 0; i < indexCounts.Count(); i++)
iCount += indexCounts[0];
iCount += indexCounts[i];
finalIndexData.Allocate(iCount);
int32 vertexCounter = 0, indexCounter = 0;
for (int32 i = 0; i < meshesCount; i++)
+1
View File
@@ -492,6 +492,7 @@ ScriptingObject* ManagedBinaryModule::ManagedObjectSpawn(const ScriptingObjectSp
ScriptingObject* object = nativeTypePtr->Script.Spawn(params);
if (!object)
{
LOG(Error, "Failed to spawn object of type {0} with native base type {1}.", managedTypePtr->ToString(), nativeTypePtr->ToString());
return nullptr;
}
+2 -2
View File
@@ -13,5 +13,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("b8442186-4a70-7c85-704a-857c262d00f6")]
[assembly: AssemblyVersion("1.2.6222")]
[assembly: AssemblyFileVersion("1.2.6222")]
[assembly: AssemblyVersion("1.2.6223")]
[assembly: AssemblyFileVersion("1.2.6223")]
+3 -3
View File
@@ -3,11 +3,11 @@
#pragma once
#define FLAXENGINE_NAME "FlaxEngine"
#define FLAXENGINE_VERSION Version(1, 2, 6222)
#define FLAXENGINE_VERSION_TEXT "1.2.6222"
#define FLAXENGINE_VERSION Version(1, 2, 6223)
#define FLAXENGINE_VERSION_TEXT "1.2.6223"
#define FLAXENGINE_VERSION_MAJOR 1
#define FLAXENGINE_VERSION_MINOR 2
#define FLAXENGINE_VERSION_BUILD 6222
#define FLAXENGINE_VERSION_BUILD 6223
#define FLAXENGINE_COMPANY "Flax"
#define FLAXENGINE_COPYRIGHT "Copyright (c) 2012-2021 Wojciech Figat. All rights reserved."
+2
View File
@@ -228,6 +228,7 @@ static int64_t SetupHwTimer()
uint32_t regs[4];
CpuId( regs, 1 );
if( !( regs[3] & ( 1 << 4 ) ) ) InitFailure( "CPU doesn't support RDTSC instruction." );
#if !defined TRACY_NO_INVARIANT_CHECK
CpuId( regs, 0x80000007 );
if( !( regs[3] & ( 1 << 8 ) ) )
{
@@ -241,6 +242,7 @@ static int64_t SetupHwTimer()
#endif
}
}
#endif
#endif
return Profiler::GetTime();
+3
View File
@@ -34,7 +34,10 @@ public class tracy : ThirdPartyModule
options.PublicDefinitions.Add("TRACY_ENABLE");
if (options.Platform.Target == TargetPlatform.Windows)
{
options.PrivateDefinitions.Add("TRACY_DBGHELP_LOCK=DbgHelp");
options.PrivateDefinitions.Add("TRACY_NO_INVARIANT_CHECK");
}
}
/// <inheritdoc />
+2 -2
View File
@@ -313,7 +313,6 @@ namespace Flax.Build
//throw new Exception(string.Format("Platform {0} {1} is not supported.", targetPlatform, architecture));
var platform = Platform.GetPlatform(targetPlatform);
var toolchain = platform.GetToolchain(architecture);
// Special case: building C# bindings only (eg. when building Linux game on Windows without C++ scripting or for C#-only projects)
if (Configuration.BuildBindingsOnly || (project.IsCSharpOnlyProject && platform.HasModularBuildSupport))
@@ -327,7 +326,7 @@ namespace Flax.Build
switch (target.Type)
{
case TargetType.NativeCpp:
BuildTargetNativeCppBindingsOnly(rules, graph, target, buildContext, toolchain, platform, architecture, configuration);
BuildTargetNativeCppBindingsOnly(rules, graph, target, buildContext, platform, architecture, configuration);
break;
case TargetType.DotNet:
BuildTargetDotNet(rules, graph, target, platform, configuration);
@@ -338,6 +337,7 @@ namespace Flax.Build
continue;
}
var toolchain = platform.GetToolchain(architecture);
using (new ProfileEventScope(target.Name))
{
Log.Info(string.Format("Building target {0} in {1} for {2} {3}", target.Name, configuration, targetPlatform, architecture));
@@ -553,7 +553,7 @@ namespace Flax.Build
var graph = new TaskGraph(reference.Project.ProjectFolderPath);
var skipBuild = target.IsPreBuilt || (Configuration.SkipTargets != null && Configuration.SkipTargets.Contains(target.Name));
target.PreBuild();
referencedBuildData = BuildTargetNativeCppBindingsOnly(buildData.Rules, graph, target, buildContext, buildData.Toolchain, buildData.Platform, buildData.Architecture, buildData.Configuration, skipBuild);
referencedBuildData = BuildTargetNativeCppBindingsOnly(buildData.Rules, graph, target, buildContext, buildData.Platform, buildData.Architecture, buildData.Configuration, skipBuild);
if (!skipBuild)
{
using (new ProfileEventScope("PrepareTasks"))
@@ -935,7 +935,7 @@ namespace Flax.Build
return buildData;
}
private static BuildData BuildTargetNativeCppBindingsOnly(RulesAssembly rules, TaskGraph graph, Target target, Dictionary<Target, BuildData> buildContext, Toolchain toolchain, Platform platform, TargetArchitecture architecture, TargetConfiguration configuration, bool skipBuild = false)
private static BuildData BuildTargetNativeCppBindingsOnly(RulesAssembly rules, TaskGraph graph, Target target, Dictionary<Target, BuildData> buildContext, Platform platform, TargetArchitecture architecture, TargetConfiguration configuration, bool skipBuild = false)
{
if (buildContext.TryGetValue(target, out var buildData))
return buildData;
@@ -954,7 +954,7 @@ namespace Flax.Build
throw new Exception($"Cannot build target {target.Name}. The project file is missing (.flaxproj located in the folder above).");
// Setup build environment for the target
var targetBuildOptions = GetBuildOptions(target, toolchain.Platform, toolchain, toolchain.Architecture, configuration, project.ProjectFolderPath, skipBuild ? string.Empty : Configuration.HotReloadPostfix);
var targetBuildOptions = GetBuildOptions(target, platform, null, architecture, configuration, project.ProjectFolderPath, skipBuild ? string.Empty : Configuration.HotReloadPostfix);
using (new ProfileEventScope("PreBuild"))
{
@@ -992,13 +992,16 @@ namespace Flax.Build
{
using (new ProfileEventScope(reference.Project.Name))
{
if (buildData.Toolchain == null)
buildData.Toolchain = platform.GetToolchain(architecture);
if (Configuration.BuildBindingsOnly || reference.Project.IsCSharpOnlyProject || !platform.HasRequiredSDKsInstalled)
{
BuildTargetReferenceNativeCppBindingsOnly(buildContext, buildData, reference);
}
else
{
if (buildData.Toolchain == null)
buildData.Toolchain = platform.GetToolchain(architecture);
BuildTargetReferenceNativeCpp(buildContext, buildData, reference);
}
}
}
}
@@ -404,8 +404,9 @@ namespace Flax.Build.Projects.VisualStudioCode
json.BeginRootObject();
json.BeginArray("configurations");
json.BeginObject();
var project = solution.MainProject ?? solution.Projects.FirstOrDefault(x => x.Name == Globals.Project.Name);
if (project != null)
{
var project = solution.MainProject ?? solution.Projects.First(x => x.Name == Globals.Project.Name);
json.AddField("name", project.Name);
var targetPlatform = Platform.BuildPlatform.Target;