Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
SceneGraphNode.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018 DIVIDE-Studio
3 Copyright (c) 2009 Ionut Cava
4
5 This file is part of DIVIDE Framework.
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software
9 and associated documentation files (the "Software"), to deal in the Software
10 without restriction,
11 including without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so,
15 subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED,
22 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23 PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25 DAMAGES OR OTHER LIABILITY,
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
27 IN CONNECTION WITH THE SOFTWARE
28 OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 */
31
32#pragma once
33#ifndef DVD_SCENE_GRAPH_NODE_H_
34#define DVD_SCENE_GRAPH_NODE_H_
35
36#include "SceneNodeFwd.h"
38#include "IntersectionRecord.h"
40
43
44namespace Divide
45{
46
47 namespace GFX
48 {
49 struct MemoryBarrierCommand;
50 };
51
52 class SceneNode;
53 class SceneGraph;
54 class SceneState;
55 class PropertyWindow;
56 class BoundsComponent;
57 class TransformSystem;
58 class RenderPassManager;
59 class RenderPassExecutor;
60 class RenderingComponent;
61 class TransformComponent;
62
63 struct RenderPackage;
64 struct NodeCullParams;
65 struct CameraSnapshot;
66 struct RenderStagePass;
67 struct RenderPassCuller;
68
69
71 {
72 Handle<SceneNode> _handle = INVALID_HANDLE<SceneNode>;
73 SceneNode* _nodePtr = nullptr;
76 };
77
78 template<typename T> requires std::is_base_of_v<SceneNode, T>
79 Handle<T> ToHandle( const SceneNodeHandle handle );
80
81 template<typename T> requires std::is_base_of_v<SceneNode, T>
83
85 {
87 size_t _instanceCount = 1u;
92 bool _serialize = true;
93
94 };
95
96 namespace Attorney
97 {
98 class SceneGraphNodeEditor;
99 class SceneGraphNodeComponent;
100 class SceneGraphNodeSystem;
101 class SceneGraphNodeSceneGraph;
102 class SceneGraphNodeRenderPassCuller;
103 class SceneGraphNodeRenderPassManager;
104 class SceneGraphNodeRelationshipCache;
105 };
106
107 class SceneGraphNode final : public ECS::Entity<SceneGraphNode>,
108 public GUIDWrapper,
110 {
118
119 public:
120
121 enum class Flags : U16
122 {
123 LOADING = toBit( 1 ),
124 HOVERED = toBit( 2 ),
125 SELECTED = toBit( 3 ),
126 ACTIVE = toBit( 4 ),
129 SELECTION_LOCKED = toBit( 7 ),
130 IS_CONTAINER = toBit( 8 ),
131 COUNT = 9
132 };
133
135 {
137 eastl::fixed_vector<SceneGraphNode*, 32, true> _data;
138 std::atomic_uint _count{ 0u };
139
142 {
143 assert( idx < _count.load() );
144
146 return _data[idx];
147 }
148 };
149
150 public:
153 ~SceneGraphNode() override;
154
156 inline SceneGraph* sceneGraph() noexcept
157 {
158 return _sceneGraph;
159 }
160
163
166 bool removeChildNode( const SceneGraphNode* node, bool recursive = true, bool deleteNode = true );
167
169 SceneGraphNode* findChild( U64 nameHash, bool sceneNodeName = false, bool recursive = false ) const;
170
172 SceneGraphNode* findChild( I64 GUID, bool sceneNodeGuid = false, bool recursive = false ) const;
173
175 bool removeNodesByType( SceneNodeType nodeType );
176
178 void setParent( SceneGraphNode* parent, bool defer = false );
179
181 bool isChildOfType( U16 typeMask ) const;
182
184 bool isRelated( const SceneGraphNode* target ) const;
186 bool isRelated( const SceneGraphNode* target, SGNRelationshipCache::RelationshipType relationship ) const;
187
189 bool isChild( const SceneGraphNode* target, bool recursive ) const;
190
192 {
193 return _children;
194 }
195 const ChildContainer& getChildren() const noexcept
196 {
197 return _children;
198 }
199
201 void sceneUpdate( U64 deltaTimeUS, SceneState& sceneState );
202
204 void postLoad();
205
207 bool intersect( const Ray& intersectionRay, vec2<F32> range, vector<SGNRayResult>& intersections ) const;
208
209 void changeUsageContext( const NodeUsageContext& newContext );
210
212 void setFlag( Flags flag, bool recursive = true );
214 void clearFlag( Flags flag, bool recursive = true );
216 [[nodiscard]] bool hasFlag( const Flags flag ) const noexcept;
217
220 template <typename T = SceneNode> requires std::is_base_of_v<SceneNode, T>
221 T& getNode() noexcept
222 {
223 return static_cast<T&>(*_node);
224 }
225
227 {
229 }
230
233 template <typename T = SceneNode> requires std::is_base_of_v<SceneNode, T>
234 const T& getNode() const noexcept
235 {
236 return static_cast<const T&>(*_node);
237 }
238
240 template <typename T>
241 [[nodiscard]] FORCE_INLINE T* get() const
242 {
243 return GetComponent<T>();
244 }
245
246 FORCE_INLINE U32 dataFlag() const noexcept { return _descriptor._dataFlag; }
247
248 void SendEvent( ECS::CustomEvent&& event );
249
251 template<class E, class... ARGS>
252 void SendEvent( ARGS&&... eventArgs ) const
253 {
254 GetECSEngine().SendEvent<E>( FWD( eventArgs )... );
255 }
257 template<class E, class... ARGS>
258 void SendAndDispatchEvent( ARGS&&... eventArgs ) const
259 {
260 GetECSEngine().SendEventAndDispatch<E>( FWD( eventArgs )... );
261 }
262
265 template<class T, class ...P> requires std::is_base_of_v<SGNComponent, T>
266 T* AddSGNComponent( P&&... param )
267 {
268 SGNComponent* comp = static_cast<SGNComponent*>(AddComponent<T>( this, this->context(), FWD( param )... ));
270 return static_cast<T*>(comp);
271 }
272
274 template<class T> requires std::is_base_of_v<SGNComponent, T>
276 {
277 RemoveSGNComponentInternal( static_cast<SGNComponent*>(GetComponent<T>()) );
278 RemoveComponent<T>();
279 }
280
281 void AddComponents( U32 componentMask, bool allowDuplicates );
282 void RemoveComponents( U32 componentMask );
283 [[nodiscard]] bool HasComponents( ComponentType componentType ) const;
284 [[nodiscard]] bool HasComponents( U32 componentMask ) const;
286 void saveToXML( const ResourcePath& sceneLocation, DELEGATE<void, std::string_view> msgCallback = {} ) const;
287 void loadFromXML( const ResourcePath& sceneLocation );
289 void loadFromXML( const boost::property_tree::ptree& pt );
290
291 protected:
292 void updateCollisions( const SceneGraphNode& parentNode, IntersectionContainer& intersections, Mutex& intersectionsLock ) const;
293
294 private:
296 void processEvents();
297 SceneGraphNode* addChildNode( SceneGraphNode* sgn );
298
300 FrustumCollision stateCullNode( const NodeCullParams& params, U16 cullFlags, U32 filterMask, const F32 distanceToClosestPointSQ ) const;
301 FrustumCollision clippingCullNode( const NodeCullParams& params ) const;
302 FrustumCollision frustumCullNode( const NodeCullParams& params, U16 cullFlags, F32& distanceToClosestPointSQ ) const;
304 void prepareRender( RenderingComponent& rComp,
305 RenderPackage& pkg,
306 GFX::MemoryBarrierCommand& postDrawMemCmd,
307 const RenderStagePass& renderStagePass,
308 const CameraSnapshot& cameraSnapshot,
309 bool refreshData );
311 void onNetworkSend( U32 frameCount ) const;
313 void getAllNodes( vector<SceneGraphNode*>& nodeList );
315 void processDeleteQueue( vector<size_t>& childList );
317 bool saveCache( ByteBuffer& outputBuffer ) const;
319 bool loadCache( ByteBuffer& inputBuffer );
321 void setTransformDirty( U32 transformMask );
323 static void PostLoad( SceneNode* sceneNode, SceneGraphNode* sgn );
325 ECS::ECSEngine& GetECSEngine() const noexcept;
327 void invalidateRelationshipCache( SceneGraphNode* source = nullptr );
329 void setParentInternal();
330
331 bool canDraw( const RenderStagePass& stagePass ) const;
332
333 void AddSGNComponentInternal( SGNComponent* comp );
334 void RemoveSGNComponentInternal( SGNComponent* comp );
335
336 template<bool checkInternalNode = false>
337 SceneGraphNode* findChildInternal( U64 nameHash, bool recursive = false ) const;
338 template<bool checkInternalNode = false>
339 SceneGraphNode* findChildInternal( I64 GUID, bool recursive = false ) const;
340
341 private:
344
345 // ToDo: Remove this HORRIBLE hack -Ionut
346 struct hacks
347 {
349 TransformComponent* _transformComponentCache = nullptr;
350 BoundsComponent* _boundsComponentCache = nullptr;
351 RenderingComponent* _renderingComponent = nullptr;
353
354 struct events
355 {
356 // this should be ample storage PER FRAME for events.
357 static constexpr size_t EVENT_QUEUE_SIZE = 128;
358 std::array<ECS::CustomEvent, EVENT_QUEUE_SIZE> _events;
359 std::array<std::atomic_bool, EVENT_QUEUE_SIZE> _eventsFreeList;
361
363 POINTER_R( SceneNode, node, nullptr );
364 POINTER_R( ECS::ComponentManager, compManager, nullptr );
366 PROPERTY_R( Str<64>, name, "" );
367 PROPERTY_R( U64, nameHash, 0u );
368 PROPERTY_R( I64, queuedNewParent, -1 );
369 PROPERTY_R( U32, componentMask, 0u );
370 PROPERTY_R( U32, nodeFlags, 0u );
371 PROPERTY_R( U32, instanceCount, 1u );
372 PROPERTY_R( bool, serialize, true );
374 //ToDo: make this work in a multi-threaded environment
375 mutable I8 _frustPlaneCache = -1;
376
377 private:
379 };
380
381 namespace Attorney
382 {
384 {
386 {
387 return node->Hacks._editorComponents;
388 }
389
390 static const vector<EditorComponent*>& editorComponents( const SceneGraphNode* node ) noexcept
391 {
392 return node->Hacks._editorComponents;
393 }
394
396 };
397
399 {
400 static void processEvents( SceneGraphNode* node )
401 {
402 node->processEvents();
403 }
404 static void changeParent( SceneGraphNode* node )
405 {
406 node->setParentInternal();
407 }
408 static void onNetworkSend( const SceneGraphNode* node, const U32 frameCount )
409 {
410 node->onNetworkSend( frameCount );
411 }
412
413 static void getAllNodes( SceneGraphNode* node, vector<SceneGraphNode*>& nodeList )
414 {
415 node->getAllNodes( nodeList );
416 }
417
418 static void processDeleteQueue( SceneGraphNode* node, vector<size_t>& childList )
419 {
420 node->processDeleteQueue( childList );
421 }
422
423 static bool saveCache( const SceneGraphNode* node, ByteBuffer& outputBuffer )
424 {
425 return node->saveCache( outputBuffer );
426 }
427
428 static bool loadCache( SceneGraphNode* node, ByteBuffer& inputBuffer )
429 {
430 return node->loadCache( inputBuffer );
431 }
432 static void updateCollisions( const SceneGraphNode& node, const SceneGraphNode& parentNode, IntersectionContainer& intersections, Mutex& intersectionsLock )
433 {
434 node.updateCollisions( parentNode, intersections, intersectionsLock );
435 }
436 friend class Divide::SceneGraph;
437 };
438
440 {
441 static void setTransformDirty( SceneGraphNode* node, const U32 transformMask )
442 {
443 node->setTransformDirty( transformMask );
444 }
445
447 };
448
450 {
451 static void prepareRender( SceneGraphNode* node, RenderingComponent& rComp, RenderPackage& pkg, GFX::MemoryBarrierCommand& postDrawMemCmd, const CameraSnapshot& cameraSnapshot, const RenderStagePass& renderStagePass, const bool refreshData )
452 {
453 node->prepareRender( rComp, pkg, postDrawMemCmd, renderStagePass, cameraSnapshot, refreshData );
454 }
455
459 };
460
462 {
463 // Returns true if the node should be culled (is not visible for the current stage)
464 static FrustumCollision frustumCullNode( const SceneGraphNode* node, const NodeCullParams& params, const U16 cullFlags, F32& distanceToClosestPointSQ )
465 {
466 return node->frustumCullNode( params, cullFlags, distanceToClosestPointSQ );
467 }
468 static FrustumCollision stateCullNode( const SceneGraphNode* node, const NodeCullParams& params, const U16 cullFlags, const U32 filterMask, F32 distanceToClosestPointSQ )
469 {
470 return node->stateCullNode( params, cullFlags, filterMask, distanceToClosestPointSQ );
471 }
473 {
474 return node->clippingCullNode( params );
475 }
476
477 static FrustumCollision frustumCullNode( const SceneGraphNode* node, const NodeCullParams& params, const U16 cullFlags )
478 {
479 F32 distanceToClosestPointSQ = F32_MAX;
480 return frustumCullNode( node, params, cullFlags, distanceToClosestPointSQ );
481 }
482
484 };
485
487 {
488 static bool canDraw( const SceneGraphNode* node, const RenderStagePass& stagePass )
489 {
490 return node->canDraw( stagePass );
491 }
492
495 };
496
497
499 {
500 static const SGNRelationshipCache& relationshipCache( const SceneGraphNode* node ) noexcept
501 {
502 return node->_relationshipCache;
503 }
504
506 };
507
508 }; // namespace Attorney
509
510
511}; // namespace Divide
512#endif //DVD_SCENE_GRAPH_NODE_H_
513
514#include "SceneGraphNode.inl"
#define FWD(...)
#define FORCE_INLINE
static void prepareRender(SceneGraphNode *node, RenderingComponent &rComp, RenderPackage &pkg, GFX::MemoryBarrierCommand &postDrawMemCmd, const CameraSnapshot &cameraSnapshot, const RenderStagePass &renderStagePass, const bool refreshData)
static vector< EditorComponent * > & editorComponents(SceneGraphNode *node) noexcept
static const vector< EditorComponent * > & editorComponents(const SceneGraphNode *node) noexcept
static const SGNRelationshipCache & relationshipCache(const SceneGraphNode *node) noexcept
static FrustumCollision frustumCullNode(const SceneGraphNode *node, const NodeCullParams &params, const U16 cullFlags)
static FrustumCollision clippingCullNode(const SceneGraphNode *node, const NodeCullParams &params)
static FrustumCollision frustumCullNode(const SceneGraphNode *node, const NodeCullParams &params, const U16 cullFlags, F32 &distanceToClosestPointSQ)
static FrustumCollision stateCullNode(const SceneGraphNode *node, const NodeCullParams &params, const U16 cullFlags, const U32 filterMask, F32 distanceToClosestPointSQ)
static bool canDraw(const SceneGraphNode *node, const RenderStagePass &stagePass)
static void onNetworkSend(const SceneGraphNode *node, const U32 frameCount)
static void processEvents(SceneGraphNode *node)
static void getAllNodes(SceneGraphNode *node, vector< SceneGraphNode * > &nodeList)
static void updateCollisions(const SceneGraphNode &node, const SceneGraphNode &parentNode, IntersectionContainer &intersections, Mutex &intersectionsLock)
static void changeParent(SceneGraphNode *node)
static void processDeleteQueue(SceneGraphNode *node, vector< size_t > &childList)
static bool saveCache(const SceneGraphNode *node, ByteBuffer &outputBuffer)
static bool loadCache(SceneGraphNode *node, ByteBuffer &inputBuffer)
static void setTransformDirty(SceneGraphNode *node, const U32 transformMask)
Utility class that adds basic GUID management to objects.
Definition: GUIDWrapper.h:44
PlatformContext & context() noexcept
SceneGraphNode * findChild(U64 nameHash, bool sceneNodeName=false, bool recursive=false) const
Find a child Node using the given name (either SGN name or SceneNode name)
SceneGraph * sceneGraph() noexcept
Return a reference to the parent graph. Operator= should be disabled.
static void PostLoad(SceneNode *sceneNode, SceneGraphNode *sgn)
As opposed to "postLoad()" that's called when the SceneNode is ready for processing,...
void prepareRender(RenderingComponent &rComp, RenderPackage &pkg, GFX::MemoryBarrierCommand &postDrawMemCmd, const RenderStagePass &renderStagePass, const CameraSnapshot &cameraSnapshot, bool refreshData)
Called after preRender and after we rebuild our command buffers. Useful for modifying the command buf...
bool HasComponents(ComponentType componentType) const
void SendAndDispatchEvent(ARGS &&... eventArgs) const
Sends a global event with dispatched happening immediately. Avoid using often. Bad for performance.
FrustumCollision frustumCullNode(const NodeCullParams &params, U16 cullFlags, F32 &distanceToClosestPointSQ) const
void setParentInternal()
Changes this node's parent.
void clearFlag(Flags flag, bool recursive=true)
Clearing a flag might propagate to child nodes (e.g. selection).
void RemoveSGNComponentInternal(SGNComponent *comp)
~SceneGraphNode() override
If we are destroying the current graph node.
FORCE_INLINE SceneNodeHandle handle() const noexcept
bool intersect(const Ray &intersectionRay, vec2< F32 > range, vector< SGNRayResult > &intersections) const
Find the graph nodes whom's bounding boxes intersects the given ray.
void setFlag(Flags flag, bool recursive=true)
General purpose flag management. Certain flags propagate to children (e.g. selection)!
FrustumCollision stateCullNode(const NodeCullParams &params, U16 cullFlags, U32 filterMask, const F32 distanceToClosestPointSQ) const
Returns a collision result that determines if the node SHOULD be culled (is not visible for the curre...
void updateCollisions(const SceneGraphNode &parentNode, IntersectionContainer &intersections, Mutex &intersectionsLock) const
struct Divide::SceneGraphNode::events Events
void setTransformDirty(U32 transformMask)
Called by the TransformComponent whenever the transform changed.
void SendEvent(ECS::CustomEvent &&event)
void RemoveComponents(U32 componentMask)
bool loadCache(ByteBuffer &inputBuffer)
Similar to the loadFromXML call but is geared towards temporary state (e.g. save game)
ECS::ECSEngine & GetECSEngine() const noexcept
This indirect is used to avoid including ECS headers in this file, but we still need the ECS engine f...
PROPERTY_R(U64, nameHash, 0u)
bool isChildOfType(U16 typeMask) const
Checks if we have a parent matching the typeMask. We check recursively until we hit the top node (if ...
PROPERTY_R(U32, nodeFlags, 0u)
const ChildContainer & getChildren() const noexcept
bool isChild(const SceneGraphNode *target, bool recursive) const
Returns true if the specified target node is a parent or grandparent(if recursive == true) of the cur...
PROPERTY_R(NodeUsageContext, usageContext, NodeUsageContext::NODE_STATIC)
PROPERTY_R(Str< 64 >, name, "")
void processEvents()
Process any events that might of queued up during the ECS Update stages.
void onNetworkSend(U32 frameCount) const
Called whenever we send a networking packet from our NetworkingComponent (if any)....
ChildContainer _children
void setParent(SceneGraphNode *parent, bool defer=false)
Changing a node's parent means removing this node from the current parent's child list and appending ...
void SendEvent(ARGS &&... eventArgs) const
Sends a global event but dispatched is handled between update steps.
PROPERTY_R(bool, serialize, true)
void invalidateRelationshipCache(SceneGraphNode *source=nullptr)
Only called from withing "setParent()" (which is also called from "addChildNode()")....
bool isRelated(const SceneGraphNode *target) const
Returns true if the current node is related somehow to the specified target node (see RelationshipTyp...
void changeUsageContext(const NodeUsageContext &newContext)
SceneGraphNode * addChildNode(const SceneGraphNodeDescriptor &descriptor)
Add child node increments the node's ref counter if the node was already added to the scene graph.
struct Divide::SceneGraphNode::hacks Hacks
void processDeleteQueue(vector< size_t > &childList)
Destructs all of the nodes specified in the list and removes them from the _children container.
PROPERTY_R(U32, componentMask, 0u)
FORCE_INLINE T * get() const
Returns a pointer to a specific component. Returns null if the SGN does not have the component reques...
POINTER_R(SceneNode, node, nullptr)
void AddComponents(U32 componentMask, bool allowDuplicates)
FrustumCollision clippingCullNode(const NodeCullParams &params) const
void postLoad()
Invoked by the contained SceneNode when it finishes all of its internal loading and is ready for proc...
SGNRelationshipCache _relationshipCache
PROPERTY_R(I64, queuedNewParent, -1)
T * AddSGNComponent(P &&... param)
void AddSGNComponentInternal(SGNComponent *comp)
T & getNode() noexcept
bool hasFlag(const Flags flag) const noexcept
Returns true only if the current node has the specified flag. Does not check children!
FORCE_INLINE U32 dataFlag() const noexcept
POINTER_R(SceneGraph, sceneGraph, nullptr)
bool saveCache(ByteBuffer &outputBuffer) const
Similar to the saveToXML call but is geared towards temporary state (e.g. save game)
POINTER_R(ECS::ComponentManager, compManager, nullptr)
PROPERTY_R(U32, instanceCount, 1u)
void loadFromXML(const ResourcePath &sceneLocation)
const SceneGraphNodeDescriptor _descriptor
const T & getNode() const noexcept
bool removeChildNode(const SceneGraphNode *node, bool recursive=true, bool deleteNode=true)
void getAllNodes(vector< SceneGraphNode * > &nodeList)
Returns a bottom-up list(leafs -> root) of all of the nodes parented under the current one.
void RemoveSGNComponent()
Remove a component by type (if any). Because we have a limit of one component type per node,...
ChildContainer & getChildren() noexcept
bool canDraw(const RenderStagePass &stagePass) const
void saveToXML(const ResourcePath &sceneLocation, DELEGATE< void, std::string_view > msgCallback={}) const
Serialization: save to XML file.
POINTER_R(SceneGraphNode, parent, nullptr)
SceneGraphNode * findChildInternal(U64 nameHash, bool recursive=false) const
bool removeNodesByType(SceneNodeType nodeType)
If this function returns true, at least one node of the specified type was removed.
void sceneUpdate(U64 deltaTimeUS, SceneState &sceneState)
Called from parent SceneGraph.
void SendEventAndDispatch(ARGS &&... eventArgs) const
Definition: Engine.h:112
void SendEvent(ARGS &&... eventArgs) const
Definition: Engine.h:106
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
NodeUsageContext
Usage context affects lighting, navigation, physics, etc.
Definition: SceneNodeFwd.h:41
DELEGATE_STD< Ret, Args... > DELEGATE
eastl::fixed_vector< IntersectionRecord, 32u, true > IntersectionContainer
std::mutex Mutex
Definition: SharedMutex.h:40
SceneNodeType
ToDo: Move particle emitter to components (it will make them way more dynamic) - Ionut.
Definition: SceneNodeFwd.h:47
std::shared_mutex SharedMutex
Definition: SharedMutex.h:43
eastl::vector< Type > vector
Definition: Vector.h:42
std::shared_lock< mutex > SharedLock
Definition: SharedMutex.h:49
Project & parent
Definition: DefaultScene.h:41
constexpr F32 F32_MAX
uint16_t U16
constexpr U32 U32_MAX
SceneNodeHandle FromHandle(const Handle< T > handle)
int64_t I64
uint32_t U32
uint64_t U64
constexpr T toBit(const T X)
Converts an arbitrary positive integer value to a bitwise value used for masks.
Handle< T > ToHandle(const SceneNodeHandle handle)
SceneGraphNode * getChild(const U32 idx)
Return a specific child by index. Does not recurse.
eastl::fixed_vector< SceneGraphNode *, 32, true > _data
static constexpr size_t EVENT_QUEUE_SIZE
std::array< std::atomic_bool, EVENT_QUEUE_SIZE > _eventsFreeList
std::array< ECS::CustomEvent, EVENT_QUEUE_SIZE > _events
vector< EditorComponent * > _editorComponents
Handle< SceneNode > _handle
DELEGATE< void > _deleter