1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef API_3D_ECS_SYSTEMS_INODE_SYSTEM_H
17 #define API_3D_ECS_SYSTEMS_INODE_SYSTEM_H
18
19 #include <3d/namespace.h>
20 #include <base/containers/array_view.h>
21 #include <base/containers/string.h>
22 #include <base/containers/string_view.h>
23 #include <base/containers/vector.h>
24 #include <base/math/quaternion.h>
25 #include <base/math/vector.h>
26 #include <core/ecs/entity.h>
27 #include <core/ecs/intf_system.h>
28
29 CORE_BEGIN_NAMESPACE()
30 class IComponentManager;
31 CORE_END_NAMESPACE()
32
CORE3D_BEGIN_NAMESPACE()33 CORE3D_BEGIN_NAMESPACE()
34 /** @ingroup group_ecs_systems_inode */
35 /**
36 * Scene Node.
37 * Scene node has components automatically for:
38 * NodeComponent, NameComponent, LocalMatrixComponent, TransformComponent, WorldMatrixComponent
39 */
40 class ISceneNode {
41 public:
42 virtual ~ISceneNode() = default;
43
44 /** Retrieve name of this node.
45 */
46 virtual BASE_NS::string GetName() const = 0;
47
48 /** Set name of this node.
49 * @param name String to be set as a name for this node.
50 */
51 virtual void SetName(BASE_NS::string_view name) = 0;
52
53 /** Set node enabled or disabled, Disabled node is excluded from rendering and logic that is run by ECS systems.
54 * @param isEnabled Boolean value that defines whether this node is enabled or disabled.
55 */
56 virtual void SetEnabled(bool isEnabled) = 0;
57
58 /** Check whether node is enabled or disabled.
59 */
60 virtual bool GetEnabled() const = 0;
61
62 /** Check whether node and all its parent nodes are enabled or disabled.
63 */
64 virtual bool GetEffectivelyEnabled() const = 0;
65
66 /** Retrieve parent of this node.
67 */
68 virtual ISceneNode* GetParent() const = 0;
69
70 /** Set parent of this node.
71 * @param node Parent to be set for this node.
72 */
73 virtual void SetParent(ISceneNode const& node) = 0;
74
75 /** Check if given node is this node or descendant of this node.
76 * @param node a Node which against parenthood is checked
77 */
78 virtual bool IsAncestorOf(ISceneNode const& node) = 0;
79
80 /** Retrieve children of this node.
81 */
82 virtual BASE_NS::array_view<ISceneNode* const> GetChildren() const = 0;
83
84 /** Retrieve children of this node.
85 */
86 virtual BASE_NS::array_view<ISceneNode*> GetChildren() = 0;
87
88 /** Retrieve Entity that is associated to this node.
89 */
90 virtual CORE_NS::Entity GetEntity() const = 0;
91
92 /** Get child node of given parent node by name.
93 * @param name Name which is used to find children.
94 */
95 virtual const ISceneNode* GetChild(BASE_NS::string_view const& name) const = 0;
96
97 /** Get child node of given parent node by name.
98 * @param name Name which is used to find children.
99 */
100 virtual ISceneNode* GetChild(BASE_NS::string_view const& name) = 0;
101
102 /** Add the given node as a child of this node. The node will be placed last in the child list.
103 * @param node Node to add
104 * @return true if node could be added
105 */
106 virtual bool AddChild(ISceneNode& node) = 0;
107
108 /** Add the given node as a child of this node. The node will be inserted to the given index, or last if the index
109 * is out of bounds.
110 * @param index Insert location.
111 * @param node Node to add.
112 * @return true if node could be added.
113 */
114 virtual bool InsertChild(size_t index, ISceneNode& node) = 0;
115
116 /** Remove the given node from this node.
117 * @param node Node to add
118 * @return true if node could be removed.
119 */
120 virtual bool RemoveChild(ISceneNode& node) = 0;
121
122 /** Remove the node at the given index from this node.
123 * @param index Location to remove.
124 * @return true if node could be removed, false if index is out of bounds.
125 */
126 virtual bool RemoveChild(size_t index) = 0;
127
128 /** Remove all child nodes.
129 * @return true if nodes could be removed.
130 */
131 virtual bool RemoveChildren() = 0;
132
133 /** Get child node of given parent node by path.
134 * @param path String of a path which is then used like (ie. path/to/child).
135 */
136 virtual const ISceneNode* LookupNodeByPath(BASE_NS::string_view const& path) const = 0;
137
138 /** Get child node of given parent node by path.
139 * @param path String of a path which is then used like (ie. path/to/child).
140 */
141 virtual ISceneNode* LookupNodeByPath(BASE_NS::string_view const& path) = 0;
142
143 /** Recursively look up node by name (returns the first node with given name assigned).
144 * @param name Name of the node.
145 */
146 virtual const ISceneNode* LookupNodeByName(BASE_NS::string_view const& name) const = 0;
147
148 /** Recursively look up node by name (returns the first node with given name assigned).
149 * @param name Name of the node.
150 */
151 virtual ISceneNode* LookupNodeByName(BASE_NS::string_view const& name) = 0;
152
153 /** Recursively look up node by component type (returns the first node that has given component assigned).
154 * @param componentManager Component manager that defines the type of the component.
155 */
156 virtual const ISceneNode* LookupNodeByComponent(const CORE_NS::IComponentManager& componentManager) const = 0;
157
158 /** Recursively look up node by component type (returns the first node that has given component assigned).
159 * @param componentManager Component manager that defines the type of the component.
160 */
161 virtual ISceneNode* LookupNodeByComponent(const CORE_NS::IComponentManager& componentManager) = 0;
162
163 /** Recursively look up multiple nodes in hierarchy by component type (returns all nodes with given component
164 * assigned).
165 * @param componentManager Component manager that defines the type of the component.
166 */
167 virtual BASE_NS::vector<const ISceneNode*> LookupNodesByComponent(
168 const CORE_NS::IComponentManager& componentManager) const = 0;
169
170 /** Recursively look up multiple nodes in hierarchy by component type (returns all nodes with given component
171 * assigned).
172 * @param componentManager Component manager that defines the type of the component.
173 */
174 virtual BASE_NS::vector<ISceneNode*> LookupNodesByComponent(const CORE_NS::IComponentManager& componentManager) = 0;
175
176 // Convenience methods for accessing node transform data.
177 /** Get nodes position data
178 */
179 virtual BASE_NS::Math::Vec3 GetPosition() const = 0;
180
181 /** Get nodes rotation data
182 */
183 virtual BASE_NS::Math::Quat GetRotation() const = 0;
184
185 /** Get nodes scale data
186 */
187 virtual BASE_NS::Math::Vec3 GetScale() const = 0;
188
189 /** Set nodes scale data
190 */
191 virtual void SetScale(const BASE_NS::Math::Vec3& scale) = 0;
192
193 /** Set nodes position data
194 */
195 virtual void SetPosition(const BASE_NS::Math::Vec3& position) = 0;
196
197 /** Set nodes rotation data
198 */
199 virtual void SetRotation(const BASE_NS::Math::Quat& rotation) = 0;
200 };
201
202 /** @ingroup group_ecs_systems_inode */
203 class INodeSystem : public CORE_NS::ISystem {
204 public:
205 static constexpr BASE_NS::Uid UID { "b564d740-3d39-41e7-9add-0bdbdbdf23a8" };
206
207 /** Retrieve root node of the scene graph.
208 */
209 virtual ISceneNode& GetRootNode() const = 0;
210
211 /** Get node from entity.
212 * @param entity Entity object where we get node from
213 */
214 virtual ISceneNode* GetNode(CORE_NS::Entity entity) const = 0;
215
216 /** Create new scene node.
217 * Creates components for LocalMatrixComponent, NodeComponent, NameComponent, TransformComponent,
218 * WorldMatrixComponent.
219 */
220 virtual ISceneNode* CreateNode() = 0;
221
222 /* Create a clone of a node. Clones all components that the node has.
223 * @param node Node to be cloned.
224 * @param recursive Set to true to also clone all children of the node recursively.
225 */
226 virtual ISceneNode* CloneNode(const ISceneNode& node, bool recursive) = 0;
227
228 /** Destroy the scene node and its children.
229 * @param node Node to destroy.
230 */
231 virtual void DestroyNode(ISceneNode& node) = 0;
232
233 /** Listener for changes in SceneNode children. */
234 class SceneNodeListener {
235 public:
236 enum class EventType : uint8_t {
237 /** Child added */
238 ADDED,
239 /** Child removed */
240 REMOVED,
241 };
242 /** Signals a change in a node's children.
243 * @param parent Node where change happened.
244 * @param type Type of the change.
245 * @param child Child node.
246 * @param index Index where node was added or removed.
247 */
248 virtual void OnChildChanged(
249 const ISceneNode& parent, EventType type, const ISceneNode& child, size_t index) = 0;
250
251 protected:
252 virtual ~SceneNodeListener() = default;
253 };
254
255 /** Add listener for SceneNode events.
256 */
257 virtual void AddListener(SceneNodeListener& listener) = 0;
258
259 /** Remove SceneNode event listener.
260 */
261 virtual void RemoveListener(SceneNodeListener& listener) = 0;
262
263 protected:
264 INodeSystem() = default;
265 INodeSystem(const INodeSystem&) = delete;
266 INodeSystem(INodeSystem&&) = delete;
267 INodeSystem& operator=(const INodeSystem&) = delete;
268 INodeSystem& operator=(INodeSystem&&) = delete;
269 };
270
271 /** @ingroup group_ecs_systems_inode */
272 /** Return name of this system
273 */
GetName(const INodeSystem *)274 inline constexpr BASE_NS::string_view GetName(const INodeSystem*)
275 {
276 return "NodeSystem";
277 }
278 CORE3D_END_NAMESPACE()
279
280 #endif // API_3D_ECS_SYSTEMS_INODE_SYSTEM_H
281