Oxygen Engine
Modern C++ 3D Engine using OpenGL
Loading...
Searching...
No Matches
node.h
1#ifndef OE_SCENE_NODE_H
2#define OE_SCENE_NODE_H
3
4#include <stdexcept>
5#include <string>
6#include <vector>
7
8#include <algorithm>
9#include "aabb.h"
10#include "transform.h"
11
12#include "node_ptr.h"
13
15{
16 std::vector<std::string> split(const std::string &input, const std::string& separator);
17}
18
19namespace oe::scene
20{
21 using NodeType = uint64_t;
22 const NodeType NodeTypeALL = 0;
23
29 class Node : public Transform
30 {
31 public:
32 Node(const NodePtr& identifier):
33 scene_data(identifier)
34 {}
35
44 void setChild(const NodePtr& child)
45 {
46 if (child.scene != scene_data.scene) [[unlikely]]
47 {
48 throw std::invalid_argument("Node parent is not in the current scene!");
49 }
50
51 // child already a child of this node
52 if (child->parent == scene_data)
53 {
54 return;
55 }
56
57 if (child->parent)
58 {
59 child->parent->_remove_child(child);
60 }
61
62 child->parent = scene_data;
63 children.push_back(child);
64
65 forceDirty(true);
66 child->forceDirty(true);
67 }
68
76 void setParent(const NodePtr& new_parent)
77 {
78 if (new_parent.scene != scene_data.scene) [[unlikely]]
79 {
80 throw std::invalid_argument("Node parent is not in the current scene!");
81 }
82
83 if (new_parent == parent)
84 {
85 return;
86 }
87
88 if (parent)
89 {
90 parent->_remove_child(scene_data);
91 }
92
93 new_parent->setChild(scene_data);
94
95 forceDirty(true);
96 }
97
105 void moveToRoot() noexcept
106 {
107 parent->_remove_child(scene_data);
108 parent = {};
109
110 forceDirty(true);
111 }
112
113 /*
114 * @brief Do actions on children
115 */
116 //void foreachChildren(void (*func)(const NodePtr&, void*), const bool recursion = false, void* user_data = nullptr);
117
118 /*
119 * @brief Do actions on children
120 * @note same as above but with a lambda, might be slower
121 */
122 //void foreachChildren(std::function<void(const NodePtr&)> func, const bool recursion = false);
123
127 const std::string getAbsoluteName(const std::string& separator = "/") const noexcept
128 {
129 return (parent ? parent->getAbsoluteName(separator) + separator : "") + name;
130 }
131
138 NodePtr search(const std::string path, const std::string separator = "/")
139 {
140 if (path == "")
141 return {};
142
143 return searchFromThisNode(name + separator + path, separator);
144 }
145
151 NodePtr searchFromThisNode(const std::string& path, const std::string& separator) noexcept;
152
160 const AABB& getBoundingBox() const;
161
167
168 /*
169 * @brief Get all node parents hierarchy of the node
170 * @return first element is direct parent, second element is parent of parent, ..., last element is the root parent
171 *
172 * @note Will be empty for root nodes
173 */
174 //std::vector<NodePtr> getParentHierarchy() const;
175
180 {
181 return {getAbsoluteModelMatrix()};
182 }
183
187 glm::vec3 getAbsolutePosition() const
188 {
189 return glm::vec3(getAbsoluteModelMatrix() * glm::vec4(0, 0, 0, 1));
190 }
191
195 const glm::mat4& getAbsoluteModelMatrix() const;
196
204 const glm::mat4 getAbsoluteInverseModelMatrix() const
205 {
206 return glm::inverse(getAbsoluteModelMatrix());
207 }
208
209 /*
210 * @brief Get the rotation needed to orient the node at a specified target
211 *
212 * @param target Target Position
213 * @param up Desired upward direction (change it if you want roll effects)
214 *
215 * @todo maybe deprecated and put in trandform?
216 */
217 //glm::quat getRotationNeededToLookAt(const glm::vec3& target, const glm::vec3& up = glm::vec3(0.f, 1.f, 0.f)) const;
218
219 /*
220 * @brief Orient the node to stare at a specified target
221 *
222 * @param target Target Position
223 * @param up Desired upward direction (change it if you want roll effects)
224 */
225 //void lookAt(const glm::vec3& target, const glm::vec3& up = glm::vec3(0.f, 1.f, 0.f));
226
232 void generateModel(const bool recursive = true) const;
233
240
246 void* user_data = 0;
247
253 bool is_active = true;
254
256 std::string name = "";
257
263
264 NodePtr parent;
265
266 std::vector<NodePtr> children;
267
279 mutable AABB aabb;
280 private:
281 void _remove_child(const NodePtr& child) noexcept
282 {
283 // Remove child from children list
284 auto it = find(children.begin(), children.end(), child);
285
286 if (it != children.end())
287 {
288 children.erase(it);
289 }
290
291 child->forceDirty(true);
292 }
293
294 mutable glm::mat4 _model_matrix = glm::mat4(1.0f);
295
296 mutable glm::mat4 _absolute_model_matrix = glm::mat4(1.0f);
297
298 NodePtr _internal_search(
299 const std::vector<std::string>::iterator& begin,
300 const std::vector<std::string>::iterator& end
301 ) noexcept;
302
306 bool _has_dirty_parents() const;
307
311 NodePtr _fetch_dirty_parent() const;
312 };
313
314 //using Node = GenericNode<?>;
315
316}
317
318#endif
Axis-aligned bounding box.
Definition aabb.h:13
Scene node.
Definition node.h:30
NodePtr searchFromThisNode(const std::string &path, const std::string &separator) noexcept
search starting from this node
void setChild(const NodePtr &child)
Change the parent of a node to be this one.
Definition node.h:44
bool is_active
Toggle to check if the Node is active.
Definition node.h:253
std::string name
Name, used as identifier for search.
Definition node.h:256
NodePtr search(const std::string path, const std::string separator="/")
Search for a node among children using a name path.
Definition node.h:138
const AABB getEnglobingBoundingBox() const
Compute englobing bounding box including all children ones.
void setParent(const NodePtr &new_parent)
Change the parent of this node to "parent".
Definition node.h:76
void moveToRoot() noexcept
Detach the node from parent to make it a root node.
Definition node.h:105
void * user_data
Custom user data, you can use it to store flags / pointer / physics / etc... related to this node.
Definition node.h:246
Transform getAbsoluteTransform() const
Get Node transform relative from world origin.
Definition node.h:179
const glm::mat4 & getAbsoluteModelMatrix() const
Get absolute model matrix (by taking the parents into account)
void generateModel(const bool recursive=true) const
Force regeneration of Models Matrices.
AABB aabb
Computed AABB (taking node transform into account)
Definition node.h:279
NodePtr scene_data
Scene pointer to this node.
Definition node.h:239
glm::vec3 getAbsolutePosition() const
Get Node position from world origin.
Definition node.h:187
AABB raw_aabb
Raw bounding box (ie. without taking node transform)
Definition node.h:262
const AABB & getBoundingBox() const
Recompute and return bounding box from raw AABB.
const glm::mat4 getAbsoluteInverseModelMatrix() const
Get absolute inverse model matrix (by taking the parents into account)
Definition node.h:204
const std::string getAbsoluteName(const std::string &separator="/") const noexcept
Get absolute name (from the hierarchy)
Definition node.h:127
Manage local Translation / Rotation / Scale of an entity in the world.
Definition transform.h:65
void forceDirty(const bool is_dirty) const noexcept
Set custom dirty status.
Definition transform.h:538
Scene related management (Render-agnostic Geometry, Manger, etc...)
Definition debug.h:19
Definition node.h:15
std::vector< std::string > split(const std::string &input, const std::string &separator)
Wrapper to a node reference to use pointers to node even if the actual node moves in memory.
Definition node_ptr.h:19
SceneType * scene
Scene containing the Node.
Definition node_ptr.h:59