summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-05-26 13:59:57 -0700
committer3gg <3gg@shellblade.net>2023-05-26 13:59:57 -0700
commit49d327315f5be8b72b7c100ec95ecaa5ace8126d (patch)
treec32d76d88a1d6fadb289af7044d6a06c6a1f201c
parentf815866f62e0f6a371c0e1cb4a385b41bcffd1ce (diff)
Add node getters and iterators.
-rw-r--r--gfx/include/gfx/scene/node.h60
-rw-r--r--gfx/src/scene/node.c80
2 files changed, 115 insertions, 25 deletions
diff --git a/gfx/include/gfx/scene/node.h b/gfx/include/gfx/scene/node.h
index ab6ca12..5d168c9 100644
--- a/gfx/include/gfx/scene/node.h
+++ b/gfx/include/gfx/scene/node.h
@@ -1,7 +1,11 @@
1#pragma once 1#pragma once
2 2
3#include "animation.h" 3#include "animation.h"
4
4#include <math/fwd.h> 5#include <math/fwd.h>
6#include <math/mat4.h>
7
8#include <stdint.h>
5 9
6typedef struct Anima Anima; 10typedef struct Anima Anima;
7typedef struct Joint Joint; 11typedef struct Joint Joint;
@@ -9,6 +13,9 @@ typedef struct Light Light;
9typedef struct SceneCamera SceneCamera; 13typedef struct SceneCamera SceneCamera;
10typedef struct SceneObject SceneObject; 14typedef struct SceneObject SceneObject;
11 15
16/// Scene node iterator.
17typedef uint32_t NodeIter;
18
12/// Scene node type. 19/// Scene node type.
13typedef enum NodeType { 20typedef enum NodeType {
14 LogicalNode, 21 LogicalNode,
@@ -25,6 +32,10 @@ typedef enum NodeType {
25/// Light, SceneObject, etc), as well as of child nodes. 32/// Light, SceneObject, etc), as well as of child nodes.
26typedef struct SceneNode SceneNode; 33typedef struct SceneNode SceneNode;
27 34
35// -----------------------------------------------------------------------------
36// Constructors and destructor.
37// -----------------------------------------------------------------------------
38
28/// Create a new scene node. 39/// Create a new scene node.
29/// 40///
30/// This node does not contain any camera, light, object, etc. and exists simply 41/// This node does not contain any camera, light, object, etc. and exists simply
@@ -68,6 +79,10 @@ void gfx_construct_object_node(SceneNode*, SceneObject*);
68/// Node resources -- cameras, lights, objects, etc. -- are also destroyed. 79/// Node resources -- cameras, lights, objects, etc. -- are also destroyed.
69void gfx_destroy_node(SceneNode**); 80void gfx_destroy_node(SceneNode**);
70 81
82// -----------------------------------------------------------------------------
83// Getters.
84// -----------------------------------------------------------------------------
85
71/// Return the node's type. 86/// Return the node's type.
72NodeType gfx_get_node_type(const SceneNode*); 87NodeType gfx_get_node_type(const SceneNode*);
73 88
@@ -76,6 +91,45 @@ NodeType gfx_get_node_type(const SceneNode*);
76/// The node must be of type AnimaNode. 91/// The node must be of type AnimaNode.
77Anima* gfx_get_node_anima(const SceneNode*); 92Anima* gfx_get_node_anima(const SceneNode*);
78 93
94/// Get the node's camera.
95///
96/// The node must be of type CameraNode.
97SceneCamera* gfx_get_node_camera(const SceneNode* node);
98
99/// Get the node's joint.
100///
101/// The node must be of type JointNode.
102Joint* gfx_get_node_joint(const SceneNode*);
103
104/// Get the node's light.
105///
106/// The node must be of type LightNode.
107Light* gfx_get_node_light(const SceneNode*);
108
109/// Get the node's scene object.
110///
111/// The node must be of type ObjectNode.
112SceneObject* gfx_get_node_object(const SceneNode*);
113
114/// Get an iterator to the node's first child.
115NodeIter gfx_get_node_child(const SceneNode*);
116
117/// Get the iterator's next sibling node.
118NodeIter gfx_get_next_child(NodeIter);
119
120/// Get a scene node from the iterator.
121const SceneNode* gfx_get_iter_node(NodeIter);
122
123/// Get the node's (local) transform.
124mat4 gfx_get_node_transform(const SceneNode*);
125
126/// Get the node's global transform.
127mat4 gfx_get_node_global_transform(const SceneNode*);
128
129// -----------------------------------------------------------------------------
130// Setters.
131// -----------------------------------------------------------------------------
132
79/// Set the node's parent. 133/// Set the node's parent.
80/// 134///
81/// Pass in null to unwire from the existing parent, if one exists. 135/// Pass in null to unwire from the existing parent, if one exists.
@@ -93,11 +147,5 @@ void gfx_set_node_rotation(SceneNode*, const quat* rotation);
93/// Set the node's rotation. 147/// Set the node's rotation.
94void gfx_set_node_rotation_mat(SceneNode*, const mat4* rotation); 148void gfx_set_node_rotation_mat(SceneNode*, const mat4* rotation);
95 149
96/// Get the node's (local) transform.
97mat4 gfx_get_node_transform(const SceneNode*);
98
99/// Get the node's global transform.
100mat4 gfx_get_node_global_transform(const SceneNode*);
101
102/// Log the node's hierarchy. 150/// Log the node's hierarchy.
103void gfx_log_node_hierarchy(const SceneNode*); 151void gfx_log_node_hierarchy(const SceneNode*);
diff --git a/gfx/src/scene/node.c b/gfx/src/scene/node.c
index 760951b..ea0f19d 100644
--- a/gfx/src/scene/node.c
+++ b/gfx/src/scene/node.c
@@ -227,10 +227,69 @@ NodeType gfx_get_node_type(const SceneNode* node) {
227 return node->type; 227 return node->type;
228} 228}
229 229
230#define NODE_GET(node, field, expected_type) \
231 { \
232 assert(node); \
233 assert(node->type == expected_type); \
234 return mem_get_##field(node->field); \
235 }
236
230Anima* gfx_get_node_anima(const SceneNode* node) { 237Anima* gfx_get_node_anima(const SceneNode* node) {
238 NODE_GET(node, anima, AnimaNode);
239}
240
241SceneCamera* gfx_get_node_camera(const SceneNode* node) {
242 NODE_GET(node, camera, CameraNode);
243}
244
245Joint* gfx_get_node_joint(const SceneNode* node) {
246 NODE_GET(node, joint, JointNode);
247}
248
249Light* gfx_get_node_light(const SceneNode* node) {
250 NODE_GET(node, light, LightNode);
251}
252
253SceneObject* gfx_get_node_object(const SceneNode* node) {
254 NODE_GET(node, object, ObjectNode);
255}
256
257NodeIter gfx_get_node_child(const SceneNode* node) {
231 assert(node); 258 assert(node);
232 assert(node->type == AnimaNode); 259 return (NodeIter)node->child.val;
233 return mem_get_anima(node->anima); 260}
261
262NodeIter gfx_get_next_child(NodeIter it) {
263 if (!it) {
264 return it;
265 }
266 const SceneNode* cur_child = mem_get_node((node_idx){.val = it});
267 const node_idx next_child = cur_child->next;
268 return (NodeIter)next_child.val;
269}
270
271const SceneNode* gfx_get_iter_node(NodeIter it) {
272 if (!it) {
273 return 0;
274 }
275 return mem_get_node((node_idx){.val = it});
276}
277
278mat4 gfx_get_node_transform(const SceneNode* node) {
279 assert(node);
280 return node->transform;
281}
282
283mat4 gfx_get_node_global_transform(const SceneNode* node) {
284 assert(node);
285 mat4 transform = node->transform;
286 node_idx parent_index = node->parent;
287 while (parent_index.val != 0) {
288 const SceneNode* parent = mem_get_node(parent_index);
289 transform = mat4_mul(parent->transform, transform);
290 parent_index = parent->parent;
291 }
292 return transform;
234} 293}
235 294
236void gfx_set_node_parent(SceneNode* child, SceneNode* parent) { 295void gfx_set_node_parent(SceneNode* child, SceneNode* parent) {
@@ -263,23 +322,6 @@ void gfx_set_node_rotation_mat(SceneNode* node, const mat4* rotation) {
263 mat4_set_3x3(&node->transform, *rotation); 322 mat4_set_3x3(&node->transform, *rotation);
264} 323}
265 324
266mat4 gfx_get_node_transform(const SceneNode* node) {
267 assert(node);
268 return node->transform;
269}
270
271mat4 gfx_get_node_global_transform(const SceneNode* node) {
272 assert(node);
273 mat4 transform = node->transform;
274 node_idx parent_index = node->parent;
275 while (parent_index.val != 0) {
276 const SceneNode* parent = mem_get_node(parent_index);
277 transform = mat4_mul(parent->transform, transform);
278 parent_index = parent->parent;
279 }
280 return transform;
281}
282
283static const char* get_node_type_str(NodeType type) { 325static const char* get_node_type_str(NodeType type) {
284 switch (type) { 326 switch (type) {
285 case LogicalNode: 327 case LogicalNode: