Optimize automatic navmesh rebuild in editor for navmesh relevant actors only

This commit is contained in:
Wojtek Figat
2021-02-19 13:02:27 +01:00
parent 9f80b9853c
commit 6d7bd78816
11 changed files with 51 additions and 11 deletions

View File

@@ -165,7 +165,10 @@ namespace FlaxEditor.Gizmo
if (_selectionParents[i] is ActorNode actorNode) if (_selectionParents[i] is ActorNode actorNode)
{ {
bounds = BoundingBox.Merge(bounds, actorNode.Actor.BoxWithChildren); bounds = BoundingBox.Merge(bounds, actorNode.Actor.BoxWithChildren);
navigationDirty |= (actorNode.Actor.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation; if (actorNode.AffectsNavigationWithChildren)
{
navigationDirty |= actorNode.Actor.HasStaticFlag(StaticFlags.Navigation);
}
} }
} }
} }

View File

@@ -195,10 +195,11 @@ namespace FlaxEditor.Modules
OnSelectionChanged(); OnSelectionChanged();
} }
private void OnDirty(Actor actor) private void OnDirty(ActorNode node)
{ {
var options = Editor.Options.Options; var options = Editor.Options.Options;
var isPlayMode = Editor.StateMachine.IsPlayMode; var isPlayMode = Editor.StateMachine.IsPlayMode;
var actor = node.Actor;
// Auto CSG mesh rebuild // Auto CSG mesh rebuild
if (!isPlayMode && options.General.AutoRebuildCSG) if (!isPlayMode && options.General.AutoRebuildCSG)
@@ -208,7 +209,7 @@ namespace FlaxEditor.Modules
} }
// Auto NavMesh rebuild // Auto NavMesh rebuild
if (!isPlayMode && options.General.AutoRebuildNavMesh && actor.Scene && (actor.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation) if (!isPlayMode && options.General.AutoRebuildNavMesh && actor.Scene && node.AffectsNavigationWithChildren)
{ {
var bounds = actor.BoxWithChildren; var bounds = actor.BoxWithChildren;
Navigation.BuildNavMesh(actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs); Navigation.BuildNavMesh(actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs);
@@ -235,7 +236,7 @@ namespace FlaxEditor.Modules
{ {
foreach (var obj in objects) foreach (var obj in objects)
{ {
if (obj is ActorNode node && node.Actor.Scene && (node.Actor.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation) if (obj is ActorNode node && node.Actor.Scene && node.AffectsNavigationWithChildren)
{ {
var bounds = node.Actor.BoxWithChildren; var bounds = node.Actor.BoxWithChildren;
Navigation.BuildNavMesh(node.Actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs); Navigation.BuildNavMesh(node.Actor.Scene, bounds, options.General.AutoRebuildNavMeshTimeoutMs);
@@ -291,7 +292,7 @@ namespace FlaxEditor.Modules
SpawnEnd?.Invoke(); SpawnEnd?.Invoke();
OnDirty(actor); OnDirty(actorNode);
} }
/// <summary> /// <summary>
@@ -376,7 +377,7 @@ namespace FlaxEditor.Modules
SpawnEnd?.Invoke(); SpawnEnd?.Invoke();
OnDirty(actor); OnDirty(actorNode);
} }
/// <summary> /// <summary>

View File

@@ -76,6 +76,29 @@ namespace FlaxEditor.SceneGraph
_treeNode.LinkNode(this); _treeNode.LinkNode(this);
} }
/// <summary>
/// Gets a value indicating whether this actor affects navigation.
/// </summary>
public virtual bool AffectsNavigation => false;
/// <summary>
/// Gets a value indicating whether this actor affects navigation or any of its children (recursive).
/// </summary>
public bool AffectsNavigationWithChildren
{
get
{
if (_actor.HasStaticFlag(StaticFlags.Navigation) && AffectsNavigation)
return true;
for (var i = 0; i < ChildNodes.Count; i++)
{
if (ChildNodes[i] is ActorNode actorChild && actorChild.AffectsNavigationWithChildren)
return true;
}
return false;
}
}
/// <summary> /// <summary>
/// Tries to find the tree node for the specified actor. /// Tries to find the tree node for the specified actor.
/// </summary> /// </summary>

View File

@@ -18,6 +18,9 @@ namespace FlaxEditor.SceneGraph
{ {
} }
/// <inheritdoc />
public override bool AffectsNavigation => true;
/// <inheritdoc /> /// <inheritdoc />
public override bool RayCastSelf(ref RayCastData ray, out float distance, out Vector3 normal) public override bool RayCastSelf(ref RayCastData ray, out float distance, out Vector3 normal)
{ {

View File

@@ -78,6 +78,9 @@ namespace FlaxEditor.SceneGraph.Actors
AddChildNode(new LinkNode(this, new Guid(bytes), false)); AddChildNode(new LinkNode(this, new Guid(bytes), false));
} }
/// <inheritdoc />
public override bool AffectsNavigation => true;
/// <inheritdoc /> /// <inheritdoc />
public override bool RayCastSelf(ref RayCastData ray, out float distance, out Vector3 normal) public override bool RayCastSelf(ref RayCastData ray, out float distance, out Vector3 normal)
{ {

View File

@@ -16,5 +16,8 @@ namespace FlaxEditor.SceneGraph.Actors
: base(actor) : base(actor)
{ {
} }
/// <inheritdoc />
public override bool AffectsNavigation => true;
} }
} }

View File

@@ -15,5 +15,8 @@ namespace FlaxEditor.SceneGraph.Actors
: base(actor) : base(actor)
{ {
} }
/// <inheritdoc />
public override bool AffectsNavigation => true;
} }
} }

View File

@@ -190,7 +190,7 @@ namespace FlaxEditor.Tools.Terrain
// Auto NavMesh rebuild // Auto NavMesh rebuild
if (!isPlayMode && editorOptions.General.AutoRebuildNavMesh) if (!isPlayMode && editorOptions.General.AutoRebuildNavMesh)
{ {
if (terrain.Scene && (terrain.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation) if (terrain.Scene && terrain.HasStaticFlag(StaticFlags.Navigation))
{ {
Navigation.BuildNavMesh(terrain.Scene, patchBounds, editorOptions.General.AutoRebuildNavMeshTimeoutMs); Navigation.BuildNavMesh(terrain.Scene, patchBounds, editorOptions.General.AutoRebuildNavMeshTimeoutMs);
} }

View File

@@ -207,7 +207,7 @@ namespace FlaxEditor.Tools.Terrain
// Auto NavMesh rebuild // Auto NavMesh rebuild
if (!isPlayMode && editorOptions.General.AutoRebuildNavMesh) if (!isPlayMode && editorOptions.General.AutoRebuildNavMesh)
{ {
if (terrain.Scene && (terrain.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation) if (terrain.Scene && terrain.HasStaticFlag(StaticFlags.Navigation))
{ {
Navigation.BuildNavMesh(terrain.Scene, patchBounds, editorOptions.General.AutoRebuildNavMeshTimeoutMs); Navigation.BuildNavMesh(terrain.Scene, patchBounds, editorOptions.General.AutoRebuildNavMeshTimeoutMs);
} }

View File

@@ -154,7 +154,7 @@ namespace FlaxEditor.Tools.Terrain.Sculpt
// Auto NavMesh rebuild // Auto NavMesh rebuild
if (!isPlayMode && editorOptions.General.AutoRebuildNavMesh) if (!isPlayMode && editorOptions.General.AutoRebuildNavMesh)
{ {
if (terrain.Scene && (terrain.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation) if (terrain.Scene && terrain.HasStaticFlag(StaticFlags.Navigation))
{ {
Navigation.BuildNavMesh(terrain.Scene, brushBounds, editorOptions.General.AutoRebuildNavMeshTimeoutMs); Navigation.BuildNavMesh(terrain.Scene, brushBounds, editorOptions.General.AutoRebuildNavMeshTimeoutMs);
} }

View File

@@ -210,10 +210,11 @@ namespace FlaxEditor.Windows
if (Editor.Undo.Enabled) if (Editor.Undo.Enabled)
{ {
bool navigationDirty = (_pilotActor.StaticFlags & StaticFlags.Navigation) == StaticFlags.Navigation; ActorNode node = Editor.Scene.GetActorNode(_pilotActor);
bool navigationDirty = node.AffectsNavigationWithChildren;
var action = new TransformObjectsAction var action = new TransformObjectsAction
( (
new List<SceneGraphNode> { Editor.Scene.GetActorNode(_pilotActor) }, new List<SceneGraphNode> { node },
new List<Transform> { _pilotStart }, new List<Transform> { _pilotStart },
ref _pilotBounds, ref _pilotBounds,
navigationDirty navigationDirty