// Copyright (c) Wojciech Figat. All rights reserved. #if USE_LARGE_WORLDS using Real = System.Double; #else using Real = System.Single; #endif using System; using System.Collections.Generic; using FlaxEditor.SceneGraph.Actors; using FlaxEngine; namespace FlaxEditor.SceneGraph { /// /// Represents root node of the whole scene graph. /// /// [HideInEditor] public abstract class RootNode : ActorNode { /// /// Initializes a new instance of the class. /// protected RootNode() : base(null, Guid.NewGuid()) { _treeNode.AutoFocus = false; } /// /// Initializes a new instance of the class. /// /// The node id. protected RootNode(Guid id) : base(null, id) { _treeNode.AutoFocus = false; } /// /// Called when actor child nodes get released. /// public event Action ActorChildNodesDispose; /// /// Called when actor child nodes get released. /// /// The node. public virtual void OnActorChildNodesDispose(ActorNode node) { ActorChildNodesDispose?.Invoke(node); } /// public override string Name => "Root"; /// public override SceneNode ParentScene => null; /// public override RootNode Root => this; /// public override bool CanCopyPaste => false; /// public override bool CanDuplicate => false; /// public override bool CanDelete => false; /// public override bool CanDrag => false; /// public override bool IsActive => true; /// public override bool IsActiveInHierarchy => true; /// public override Transform Transform { get => Transform.Identity; set { } } /// /// Performs raycasting over nodes hierarchy trying to get the closest object hit by the given ray. /// /// The ray. /// The view. /// The result distance. /// The raycasting flags. /// Hit object or null if there is no intersection at all. public SceneGraphNode RayCast(ref Ray ray, ref Ray view, out Real distance, RayCastData.FlagTypes flags = RayCastData.FlagTypes.None) { var data = new RayCastData { Ray = ray, View = view, Flags = flags }; return RayCast(ref data, out distance, out _); } /// /// Performs raycasting over nodes hierarchy trying to get the closest object hit by the given ray. /// /// The ray. /// The view. /// The result distance. /// The result intersection surface normal vector. /// The raycasting flags. /// Hit object or null if there is no intersection at all. public SceneGraphNode RayCast(ref Ray ray, ref Ray view, out Real distance, out Vector3 normal, RayCastData.FlagTypes flags = RayCastData.FlagTypes.None) { var data = new RayCastData { Ray = ray, View = view, Flags = flags }; return RayCast(ref data, out distance, out normal); } internal static Quaternion RaycastNormalRotation(ref Vector3 normal) { Quaternion rotation; if (normal == Vector3.Down) rotation = Quaternion.RotationZ(Mathf.Pi); else rotation = Quaternion.LookRotation(Vector3.Cross(Vector3.Cross(normal, Vector3.Forward), normal), normal); return rotation; } /// public override bool RayCastSelf(ref RayCastData ray, out Real distance, out Vector3 normal) { distance = 0; normal = Vector3.Up; return false; } /// public override void OnDebugDraw(ViewportDebugDrawData data) { } /// public override void Delete() { } /// /// Spawns the specified actor. /// /// The actor. /// The parent. public abstract void Spawn(Actor actor, Actor parent, int orderInParent = -1); /// /// Gets the undo. /// public abstract Undo Undo { get; } /// /// Gets the list of selected scene graph nodes in the editor context. /// [Deprecated in v1.10] /// [Obsolete("Use SceneContext.Selection instead.")] public List Selection => SceneContext.Selection; /// /// Gets the list of selected scene graph nodes in the editor context. /// public abstract ISceneEditingContext SceneContext { get; } } }