Merge remote-tracking branch 'origin/1.1' into linux-editor

# Conflicts:
#	Source/Engine/Core/Math/BoundingSphere.cs
#	Source/Engine/Debug/DebugDraw.cpp
#	Source/Engine/Platform/Win32/Win32Platform.cpp
#	Source/Engine/Platform/Win32/Win32Platform.h
This commit is contained in:
Wojtek Figat
2021-02-23 22:32:17 +01:00
129 changed files with 6085 additions and 1891 deletions

View File

@@ -195,6 +195,56 @@ namespace FlaxEditor.Modules
OnSelectionChanged();
}
private void OnDirty(ActorNode node)
{
var options = Editor.Options.Options;
var isPlayMode = Editor.StateMachine.IsPlayMode;
var actor = node.Actor;
// Auto CSG mesh rebuild
if (!isPlayMode && options.General.AutoRebuildCSG)
{
if (actor is BoxBrush && actor.Scene)
actor.Scene.BuildCSG(options.General.AutoRebuildCSGTimeoutMs);
}
// Auto NavMesh rebuild
if (!isPlayMode && options.General.AutoRebuildNavMesh && actor.Scene && node.AffectsNavigationWithChildren)
{
var bounds = actor.BoxWithChildren;
Navigation.BuildNavMesh(actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs);
}
}
private void OnDirty(IEnumerable<SceneGraphNode> objects)
{
var options = Editor.Options.Options;
var isPlayMode = Editor.StateMachine.IsPlayMode;
// Auto CSG mesh rebuild
if (!isPlayMode && options.General.AutoRebuildCSG)
{
foreach (var obj in objects)
{
if (obj is ActorNode node && node.Actor is BoxBrush)
node.Actor.Scene.BuildCSG(options.General.AutoRebuildCSGTimeoutMs);
}
}
// Auto NavMesh rebuild
if (!isPlayMode && options.General.AutoRebuildNavMesh)
{
foreach (var obj in objects)
{
if (obj is ActorNode node && node.Actor.Scene && node.AffectsNavigationWithChildren)
{
var bounds = node.Actor.BoxWithChildren;
Navigation.BuildNavMesh(node.Actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs);
}
}
}
}
/// <summary>
/// Spawns the specified actor to the game (with undo).
/// </summary>
@@ -242,21 +292,92 @@ namespace FlaxEditor.Modules
SpawnEnd?.Invoke();
var options = Editor.Options.Options;
OnDirty(actorNode);
}
// Auto CSG mesh rebuild
if (!isPlayMode && options.General.AutoRebuildCSG)
/// <summary>
/// Converts the selected actor to another type.
/// </summary>
/// <param name="to">The type to convert in.</param>
public void Convert(Type to)
{
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 parent = old.Parent;
var orderInParent = old.OrderInParent;
SelectionDeleteBegin?.Invoke();
actionList[0] = new SelectionChangeAction(Selection.ToArray(), new SceneGraphNode[0], OnSelectionUndo);
actionList[0].Do();
actionList[1] = new DeleteActorsAction(new List<SceneGraphNode>
{
if (actor is BoxBrush && actor.Scene)
actor.Scene.BuildCSG(options.General.AutoRebuildCSGTimeoutMs);
Editor.Instance.Scene.GetActorNode(old)
});
actionList[1].Do();
SelectionDeleteEnd?.Invoke();
SpawnBegin?.Invoke();
// Copy properties
actor.Transform = old.Transform;
actor.StaticFlags = old.StaticFlags;
actor.HideFlags = old.HideFlags;
actor.Layer = old.Layer;
actor.Tag = old.Tag;
actor.Name = old.Name;
actor.IsActive = old.IsActive;
// Spawn actor
Level.SpawnActor(actor, parent);
if (parent != null)
actor.OrderInParent = orderInParent;
if (Editor.StateMachine.IsPlayMode)
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;
}
// Auto NavMesh rebuild
if (!isPlayMode && options.General.AutoRebuildNavMesh && actor.Scene && (actor.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation)
var actorNode = Editor.Instance.Scene.GetActorNode(actor);
if (actorNode == null)
throw new InvalidOperationException("Failed to create scene node for the spawned actor.");
actorNode.PostSpawn();
Editor.Scene.MarkSceneEdited(actor.Scene);
actionList[2] = new DeleteActorsAction(new List<SceneGraphNode>
{
var bounds = actor.BoxWithChildren;
Navigation.BuildNavMesh(actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs);
}
actorNode
}, true);
actionList[3] = new SelectionChangeAction(new SceneGraphNode[0], new SceneGraphNode[] { actorNode }, OnSelectionUndo);
actionList[3].Do();
var actions = new MultiUndoAction(actionList);
Undo.AddAction(actions);
SpawnEnd?.Invoke();
OnDirty(actorNode);
}
/// <summary>
@@ -269,8 +390,6 @@ namespace FlaxEditor.Modules
if (objects.Count == 0)
return;
bool isPlayMode = Editor.StateMachine.IsPlayMode;
SelectionDeleteBegin?.Invoke();
// Change selection
@@ -290,30 +409,7 @@ namespace FlaxEditor.Modules
SelectionDeleteEnd?.Invoke();
var options = Editor.Options.Options;
// Auto CSG mesh rebuild
if (!isPlayMode && options.General.AutoRebuildCSG)
{
foreach (var obj in objects)
{
if (obj is ActorNode node && node.Actor is BoxBrush)
node.Actor.Scene.BuildCSG(options.General.AutoRebuildCSGTimeoutMs);
}
}
// Auto NavMesh rebuild
if (!isPlayMode && options.General.AutoRebuildNavMesh)
{
foreach (var obj in objects)
{
if (obj is ActorNode node && node.Actor.Scene && (node.Actor.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation)
{
var bounds = node.Actor.BoxWithChildren;
Navigation.BuildNavMesh(node.Actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs);
}
}
}
OnDirty(objects);
}
/// <summary>