diff options
| author | 3gg <3gg@shellblade.net> | 2024-02-17 14:35:11 -0800 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2024-02-17 14:35:11 -0800 |
| commit | 6799f7bd263202d8697c5e27bf12f4e66e4c0ed1 (patch) | |
| tree | d89482cddb145cec3c4badac69889be126f27dfc | |
| parent | 6d5e336c5f1b249404d29bc4349b9cf95f058dbf (diff) | |
Introduce gfx_update().
| -rw-r--r-- | game/src/plugins/viewer.c | 19 | ||||
| -rw-r--r-- | gfx/include/gfx/renderer.h | 4 | ||||
| -rw-r--r-- | gfx/include/gfx/scene/model.h | 3 | ||||
| -rw-r--r-- | gfx/include/gfx/scene/node.h | 21 | ||||
| -rw-r--r-- | gfx/src/renderer/renderer.c | 33 | ||||
| -rw-r--r-- | gfx/src/scene/model.c | 4 | ||||
| -rw-r--r-- | gfx/src/scene/node.c | 29 |
7 files changed, 74 insertions, 39 deletions
diff --git a/game/src/plugins/viewer.c b/game/src/plugins/viewer.c index 945a422..88821af 100644 --- a/game/src/plugins/viewer.c +++ b/game/src/plugins/viewer.c | |||
| @@ -155,21 +155,15 @@ void update(Game* game, State* state, double t, double dt) { | |||
| 155 | assert(state->scene); | 155 | assert(state->scene); |
| 156 | assert(state->camera); | 156 | assert(state->camera); |
| 157 | 157 | ||
| 158 | // TODO: Move this to some sort of update_scene(). Note that models do not | ||
| 159 | // need to be animated if they are not visible to the camera. The camera | ||
| 160 | // update also should happen first. | ||
| 161 | Anima* anima = gfx_get_model_anima(state->model); | ||
| 162 | if (anima) { | ||
| 163 | gfx_update_animation(anima, (R)t); | ||
| 164 | } | ||
| 165 | |||
| 166 | const vec3 orbit_point = vec3_make(0, 2, 0); | 158 | const vec3 orbit_point = vec3_make(0, 2, 0); |
| 167 | Camera* camera = gfx_get_camera_camera(state->camera); | 159 | Camera* camera = gfx_get_camera_camera(state->camera); |
| 168 | spatial3_orbit( | 160 | spatial3_orbit( |
| 169 | &camera->spatial, orbit_point, | 161 | &camera->spatial, orbit_point, |
| 170 | /*radius=*/5, | 162 | /*radius=*/5, |
| 171 | /*azimuth=*/t * 0.5, /*zenith=*/0); | 163 | /*azimuth=*/(R)(t * 0.5), /*zenith=*/0); |
| 172 | spatial3_lookat(&camera->spatial, orbit_point); | 164 | spatial3_lookat(&camera->spatial, orbit_point); |
| 165 | |||
| 166 | gfx_update(state->scene, state->camera, (R)t); | ||
| 173 | } | 167 | } |
| 174 | 168 | ||
| 175 | /// Render the bounding boxes of all scene objects. | 169 | /// Render the bounding boxes of all scene objects. |
| @@ -207,9 +201,10 @@ static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) { | |||
| 207 | } | 201 | } |
| 208 | 202 | ||
| 209 | // Render children's boxes. | 203 | // Render children's boxes. |
| 210 | for (NodeIter it = gfx_get_node_child(node); it; | 204 | const SceneNode* child = gfx_get_node_child(node); |
| 211 | it = gfx_get_next_child(it)) { | 205 | while (child) { |
| 212 | render_bounding_boxes_rec(imm, gfx_get_iter_node(it)); | 206 | render_bounding_boxes_rec(imm, child); |
| 207 | child = gfx_get_node_sibling(child); | ||
| 213 | } | 208 | } |
| 214 | } | 209 | } |
| 215 | 210 | ||
diff --git a/gfx/include/gfx/renderer.h b/gfx/include/gfx/renderer.h index c420889..78d8bbd 100644 --- a/gfx/include/gfx/renderer.h +++ b/gfx/include/gfx/renderer.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include <math/aabb2.h> | 3 | #include <math/aabb2.h> |
| 4 | #include <math/aabb3.h> | 4 | #include <math/aabb3.h> |
| 5 | #include <math/camera.h> | 5 | #include <math/camera.h> |
| 6 | #include <math/defs.h> | ||
| 6 | #include <math/mat4.h> | 7 | #include <math/mat4.h> |
| 7 | #include <math/vec3.h> | 8 | #include <math/vec3.h> |
| 8 | #include <math/vec4.h> | 9 | #include <math/vec4.h> |
| @@ -35,6 +36,9 @@ typedef struct RenderSceneParams { | |||
| 35 | /// Render the scene. | 36 | /// Render the scene. |
| 36 | void gfx_render_scene(Renderer*, const RenderSceneParams*); | 37 | void gfx_render_scene(Renderer*, const RenderSceneParams*); |
| 37 | 38 | ||
| 39 | /// Update the scene. | ||
| 40 | void gfx_update(Scene*, const SceneCamera*, R t); | ||
| 41 | |||
| 38 | // ----------------------------------------------------------------------------- | 42 | // ----------------------------------------------------------------------------- |
| 39 | // Immediate Mode Renderer. | 43 | // Immediate Mode Renderer. |
| 40 | // ----------------------------------------------------------------------------- | 44 | // ----------------------------------------------------------------------------- |
diff --git a/gfx/include/gfx/scene/model.h b/gfx/include/gfx/scene/model.h index f4972a9..c55fc8c 100644 --- a/gfx/include/gfx/scene/model.h +++ b/gfx/include/gfx/scene/model.h | |||
| @@ -9,3 +9,6 @@ Anima* gfx_get_model_anima(Model*); | |||
| 9 | 9 | ||
| 10 | /// Return the model's root node. | 10 | /// Return the model's root node. |
| 11 | const SceneNode* gfx_get_model_root(const Model*); | 11 | const SceneNode* gfx_get_model_root(const Model*); |
| 12 | |||
| 13 | /// Return the model's root node. | ||
| 14 | SceneNode* gfx_get_model_root_mut(Model*); | ||
diff --git a/gfx/include/gfx/scene/node.h b/gfx/include/gfx/scene/node.h index d048894..77db85c 100644 --- a/gfx/include/gfx/scene/node.h +++ b/gfx/include/gfx/scene/node.h | |||
| @@ -13,9 +13,6 @@ typedef struct Model Model; | |||
| 13 | typedef struct SceneCamera SceneCamera; | 13 | typedef struct SceneCamera SceneCamera; |
| 14 | typedef struct SceneObject SceneObject; | 14 | typedef struct SceneObject SceneObject; |
| 15 | 15 | ||
| 16 | /// Scene node iterator. | ||
| 17 | typedef uint32_t NodeIter; | ||
| 18 | |||
| 19 | /// Scene node type. | 16 | /// Scene node type. |
| 20 | typedef enum NodeType { | 17 | typedef enum NodeType { |
| 21 | LogicalNode, | 18 | LogicalNode, |
| @@ -116,19 +113,17 @@ SceneObject* gfx_get_node_object(const SceneNode*); | |||
| 116 | /// Get the node's parent. | 113 | /// Get the node's parent. |
| 117 | const SceneNode* gfx_get_node_parent(const SceneNode*); | 114 | const SceneNode* gfx_get_node_parent(const SceneNode*); |
| 118 | 115 | ||
| 119 | /// Get an iterator to the node's first child. | 116 | /// Get the node's first child. |
| 120 | NodeIter gfx_get_node_child(const SceneNode*); | 117 | const SceneNode* gfx_get_node_child(const SceneNode*); |
| 121 | |||
| 122 | /// Get the iterator's next sibling node. | ||
| 123 | NodeIter gfx_get_next_child(NodeIter); | ||
| 124 | 118 | ||
| 125 | // TODO: Think about NodeIter and NodeIterMut for const safety. | 119 | /// Get the node's first child. |
| 120 | SceneNode* gfx_get_node_child_mut(SceneNode*); | ||
| 126 | 121 | ||
| 127 | /// Get a scene node from the iterator. | 122 | /// Get the node's immediate sibling. |
| 128 | const SceneNode* gfx_get_iter_node(NodeIter); | 123 | const SceneNode* gfx_get_node_sibling(const SceneNode*); |
| 129 | 124 | ||
| 130 | /// Get a scene node from the iterator. | 125 | /// Get the node's immediate sibling. |
| 131 | SceneNode* gfx_get_iter_node_mut(NodeIter); | 126 | SceneNode* gfx_get_node_sibling_mut(SceneNode*); |
| 132 | 127 | ||
| 133 | /// Get the node's (local) transform. | 128 | /// Get the node's (local) transform. |
| 134 | mat4 gfx_get_node_transform(const SceneNode*); | 129 | mat4 gfx_get_node_transform(const SceneNode*); |
diff --git a/gfx/src/renderer/renderer.c b/gfx/src/renderer/renderer.c index 30704e3..c72f719 100644 --- a/gfx/src/renderer/renderer.c +++ b/gfx/src/renderer/renderer.c | |||
| @@ -363,3 +363,36 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) { | |||
| 363 | 363 | ||
| 364 | draw_recursively(&state, mat4_id(), scene->root); | 364 | draw_recursively(&state, mat4_id(), scene->root); |
| 365 | } | 365 | } |
| 366 | |||
| 367 | static void update_rec(SceneNode* node, const SceneCamera* camera, R t) { | ||
| 368 | assert(node); | ||
| 369 | assert(camera); | ||
| 370 | |||
| 371 | const NodeType node_type = gfx_get_node_type(node); | ||
| 372 | |||
| 373 | // TODO: Models do not need to be animated if they are not visible to the | ||
| 374 | // camera. | ||
| 375 | if (node_type == AnimaNode) { | ||
| 376 | Anima* anima = gfx_get_node_anima(node); | ||
| 377 | gfx_update_animation(anima, (R)t); | ||
| 378 | } else if (node_type == ModelNode) { | ||
| 379 | Model* model = gfx_get_node_model(node); | ||
| 380 | SceneNode* root = gfx_get_model_root_mut(model); | ||
| 381 | update_rec(root, camera, t); | ||
| 382 | } | ||
| 383 | |||
| 384 | // Children. | ||
| 385 | SceneNode* child = gfx_get_node_child_mut(node); | ||
| 386 | while (child) { | ||
| 387 | update_rec(child, camera, t); | ||
| 388 | child = gfx_get_node_sibling_mut(child); | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | void gfx_update(Scene* scene, const SceneCamera* camera, R t) { | ||
| 393 | assert(scene); | ||
| 394 | assert(camera); | ||
| 395 | |||
| 396 | SceneNode* node = gfx_get_scene_root(scene); | ||
| 397 | update_rec(node, camera, t); | ||
| 398 | } | ||
diff --git a/gfx/src/scene/model.c b/gfx/src/scene/model.c index 89ff0c3..507c478 100644 --- a/gfx/src/scene/model.c +++ b/gfx/src/scene/model.c | |||
| @@ -39,3 +39,7 @@ const SceneNode* gfx_get_model_root(const Model* model) { | |||
| 39 | assert(model); | 39 | assert(model); |
| 40 | return mem_get_node(model->root); | 40 | return mem_get_node(model->root); |
| 41 | } | 41 | } |
| 42 | |||
| 43 | SceneNode* gfx_get_model_root_mut(Model* model) { | ||
| 44 | return (SceneNode*)gfx_get_model_root(model); | ||
| 45 | } | ||
diff --git a/gfx/src/scene/node.c b/gfx/src/scene/node.c index 0fbb696..05f6428 100644 --- a/gfx/src/scene/node.c +++ b/gfx/src/scene/node.c | |||
| @@ -234,29 +234,30 @@ const SceneNode* gfx_get_node_parent(const SceneNode* node) { | |||
| 234 | return mem_get_node(node->parent); | 234 | return mem_get_node(node->parent); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | NodeIter gfx_get_node_child(const SceneNode* node) { | 237 | const SceneNode* gfx_get_node_child(const SceneNode* node) { |
| 238 | assert(node); | 238 | assert(node); |
| 239 | return (NodeIter)node->child.val; | 239 | if (node->child.val) { |
| 240 | return mem_get_node(node->child); | ||
| 241 | } else { | ||
| 242 | return 0; | ||
| 243 | } | ||
| 240 | } | 244 | } |
| 241 | 245 | ||
| 242 | NodeIter gfx_get_next_child(NodeIter it) { | 246 | SceneNode* gfx_get_node_child_mut(SceneNode* node) { |
| 243 | if (!it) { | 247 | return (SceneNode*)gfx_get_node_child(node); |
| 244 | return it; | ||
| 245 | } | ||
| 246 | const SceneNode* cur_child = mem_get_node((node_idx){.val = it}); | ||
| 247 | const node_idx next_child = cur_child->next; | ||
| 248 | return (NodeIter)next_child.val; | ||
| 249 | } | 248 | } |
| 250 | 249 | ||
| 251 | const SceneNode* gfx_get_iter_node(NodeIter it) { | 250 | const SceneNode* gfx_get_node_sibling(const SceneNode* node) { |
| 252 | if (!it) { | 251 | assert(node); |
| 252 | if (node->next.val) { | ||
| 253 | return mem_get_node(node->next); | ||
| 254 | } else { | ||
| 253 | return 0; | 255 | return 0; |
| 254 | } | 256 | } |
| 255 | return mem_get_node((node_idx){.val = it}); | ||
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | SceneNode* gfx_get_iter_node_mut(NodeIter it) { | 259 | SceneNode* gfx_get_node_sibling_mut(SceneNode* node) { |
| 259 | return (SceneNode*)gfx_get_iter_node(it); | 260 | return (SceneNode*)gfx_get_node_sibling(node); |
| 260 | } | 261 | } |
| 261 | 262 | ||
| 262 | mat4 gfx_get_node_transform(const SceneNode* node) { | 263 | mat4 gfx_get_node_transform(const SceneNode* node) { |
