From 776e676d7b86bab2f78c63537bf49adb8cce6aca Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 26 May 2023 19:44:23 -0700 Subject: Add gfx_animate_scene() for convenience. --- gfx/include/gfx/scene/animation.h | 6 +++--- gfx/include/gfx/scene/node.h | 5 +++++ gfx/include/gfx/scene/scene.h | 4 ++++ gfx/src/scene/node.c | 4 ++++ gfx/src/scene/scene.c | 19 +++++++++++++++++++ gltfview/src/game.c | 5 +---- 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/gfx/include/gfx/scene/animation.h b/gfx/include/gfx/scene/animation.h index ce5d73d..eeb21fd 100644 --- a/gfx/include/gfx/scene/animation.h +++ b/gfx/include/gfx/scene/animation.h @@ -121,7 +121,7 @@ void gfx_update_animation(Anima*, R t); void gfx_stop_animation(Anima*); // TODO: Remove this, it's ugly. Things would be much simpler if scene nodes -// are allocated in arrays. Then our descs can take indices instead of pointers, -// and locating a node is simply a matter of indexing the array. The same is -// true for skeletons here and other objects. +// were allocated in arrays. Then our descs can take indices instead of +// pointers, and locating a node is simply a matter of indexing the array. The +// same is true for skeletons here and other objects. const Skeleton* gfx_get_anima_skeleton(const Anima* anima, size_t i); diff --git a/gfx/include/gfx/scene/node.h b/gfx/include/gfx/scene/node.h index 5d168c9..9507392 100644 --- a/gfx/include/gfx/scene/node.h +++ b/gfx/include/gfx/scene/node.h @@ -117,9 +117,14 @@ NodeIter gfx_get_node_child(const SceneNode*); /// Get the iterator's next sibling node. NodeIter gfx_get_next_child(NodeIter); +// TODO: Think about NodeIter and NodeIterMut for const safety. + /// Get a scene node from the iterator. const SceneNode* gfx_get_iter_node(NodeIter); +/// Get a scene node from the iterator. +SceneNode* gfx_get_iter_node_mut(NodeIter); + /// Get the node's (local) transform. mat4 gfx_get_node_transform(const SceneNode*); diff --git a/gfx/include/gfx/scene/scene.h b/gfx/include/gfx/scene/scene.h index 0de0f3c..5a1d823 100644 --- a/gfx/include/gfx/scene/scene.h +++ b/gfx/include/gfx/scene/scene.h @@ -1,5 +1,6 @@ #pragma once +#include #include typedef struct SceneNode SceneNode; @@ -8,3 +9,6 @@ typedef struct Scene Scene; /// Get the scene's root node. SceneNode* gfx_get_scene_root(Scene*); + +/// Update the scene's animations. +void gfx_animate_scene(Scene*, R t); diff --git a/gfx/src/scene/node.c b/gfx/src/scene/node.c index ea0f19d..2670680 100644 --- a/gfx/src/scene/node.c +++ b/gfx/src/scene/node.c @@ -275,6 +275,10 @@ const SceneNode* gfx_get_iter_node(NodeIter it) { return mem_get_node((node_idx){.val = it}); } +SceneNode* gfx_get_iter_node_mut(NodeIter it) { + return (SceneNode*)gfx_get_iter_node(it); +} + mat4 gfx_get_node_transform(const SceneNode* node) { assert(node); return node->transform; diff --git a/gfx/src/scene/scene.c b/gfx/src/scene/scene.c index d0d5e82..19b9379 100644 --- a/gfx/src/scene/scene.c +++ b/gfx/src/scene/scene.c @@ -19,3 +19,22 @@ SceneNode* gfx_get_scene_root(Scene* scene) { assert(scene); return scene->root; } + +static void gfx_animate_node(SceneNode* node, R t) { + assert(node); + + if (gfx_get_node_type(node) == AnimaNode) { + gfx_update_animation(gfx_get_node_anima(node), t); + } + + for (NodeIter it = gfx_get_node_child(node); it; + it = gfx_get_next_child(it)) { + gfx_animate_node(gfx_get_iter_node_mut(it), t); + } +} + +void gfx_animate_scene(Scene* scene, R t) { + assert(scene); + SceneNode* node = gfx_get_scene_root(scene); + gfx_animate_node(node, t); +} diff --git a/gltfview/src/game.c b/gltfview/src/game.c index 662272c..698267e 100644 --- a/gltfview/src/game.c +++ b/gltfview/src/game.c @@ -262,10 +262,7 @@ void game_end(Game* game) { gfx_destroy(&game->gfx); } void game_update(Game* game, double t, double dt) { // LOGD("Tick"); - // TODO: Animation should be handled by Gfx instead. Descend through the scene - // looking for animas and animate them. gfx_animate(t). - Anima* anima = gfx_get_node_anima(game->root_node); - gfx_update_animation(anima, t); + gfx_animate_scene(game->scene, (R)t); // TODO: Compute bounding boxes to then find a good orbit point and radius // for each scene. -- cgit v1.2.3