158 lines
5.8 KiB
C#
158 lines
5.8 KiB
C#
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using FlaxEngine;
|
|
|
|
namespace FlaxEditor.SceneGraph
|
|
{
|
|
/// <summary>
|
|
/// Set of tools for <see cref="SceneGraphNode"/> processing.
|
|
/// </summary>
|
|
[HideInEditor]
|
|
public static class SceneGraphTools
|
|
{
|
|
/// <summary>
|
|
/// Delegate for scene graph action execution callback.
|
|
/// </summary>
|
|
/// <param name="node">The node.</param>
|
|
/// <returns>True if call deeper, otherwise skip calling node children.</returns>
|
|
public delegate bool GraphExecuteCallbackDelegate(SceneGraphNode node);
|
|
|
|
/// <summary>
|
|
/// Executes the custom action on the graph nodes.
|
|
/// </summary>
|
|
/// <param name="node">The node</param>
|
|
/// <param name="callback">The callback.</param>
|
|
public static void ExecuteOnGraph(this SceneGraphNode node, GraphExecuteCallbackDelegate callback)
|
|
{
|
|
for (int i = 0; i < node.ChildNodes.Count; i++)
|
|
{
|
|
if (callback(node.ChildNodes[i]))
|
|
{
|
|
ExecuteOnGraph(node.ChildNodes[i], callback);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the array made of input nodes that are at the top level. The result collection contains only nodes that don't have parent nodes in the given collection.
|
|
/// </summary>
|
|
/// <typeparam name="T">The scene graph node type.</typeparam>
|
|
/// <param name="nodes">The nodes.</param>
|
|
/// <returns>The result.</returns>
|
|
public static List<T> BuildNodesParents<T>(this List<T> nodes)
|
|
where T : SceneGraphNode
|
|
{
|
|
var list = new List<T>();
|
|
BuildNodesParents(nodes, list);
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the list made of input nodes that are at the top level. The result collection contains only nodes that don't have parent nodes in the given collection.
|
|
/// </summary>
|
|
/// <typeparam name="T">The scene graph node type.</typeparam>
|
|
/// <param name="nodes">The nodes.</param>
|
|
/// <param name="result">The result.</param>
|
|
public static void BuildNodesParents<T>(this List<T> nodes, List<T> result)
|
|
where T : SceneGraphNode
|
|
{
|
|
if (nodes == null || result == null)
|
|
throw new ArgumentNullException();
|
|
|
|
result.Clear();
|
|
|
|
// Build solid part of the tree
|
|
var fullTree = BuildAllNodes(nodes);
|
|
|
|
for (var i = 0; i < nodes.Count; i++)
|
|
{
|
|
var target = nodes[i];
|
|
|
|
// If there is no target node parent in the solid tree list,
|
|
// then it means it's a local root node and can be added to the results.
|
|
if (!fullTree.Contains(target.ParentNode))
|
|
result.Add(target);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the array made of all nodes in the input list and child tree. The result collection contains all nodes in the tree.
|
|
/// </summary>
|
|
/// <param name="nodes">The nodes.</param>
|
|
/// <returns>The result.</returns>
|
|
public static List<SceneGraphNode> BuildAllNodes<T>(this List<T> nodes)
|
|
where T : SceneGraphNode
|
|
{
|
|
var list = new List<SceneGraphNode>();
|
|
BuildAllNodes(nodes, list);
|
|
return list;
|
|
}
|
|
|
|
private static void FillTree(SceneGraphNode node, List<SceneGraphNode> result)
|
|
{
|
|
result.AddRange(node.ChildNodes);
|
|
for (int i = 0; i < node.ChildNodes.Count; i++)
|
|
{
|
|
FillTree(node.ChildNodes[i], result);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the list made of all nodes in the input list and child tree. The result collection contains all nodes in the tree.
|
|
/// </summary>
|
|
/// <param name="nodes">The nodes.</param>
|
|
/// <param name="result">The result.</param>
|
|
public static void BuildAllNodes<T>(this List<T> nodes, List<SceneGraphNode> result)
|
|
where T : SceneGraphNode
|
|
{
|
|
if (nodes == null || result == null)
|
|
throw new ArgumentNullException();
|
|
|
|
result.Clear();
|
|
|
|
for (var i = 0; i < nodes.Count; i++)
|
|
{
|
|
var target = nodes[i];
|
|
|
|
// Check if has been already added
|
|
if (result.Contains(target))
|
|
continue;
|
|
|
|
// Add whole child tree to the results
|
|
result.Add(target);
|
|
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);
|
|
}
|
|
}
|
|
}
|