--- a/src/scene.c Fri Mar 15 00:06:59 2024 +0100 +++ b/src/scene.c Thu Mar 21 20:24:31 2024 +0100 @@ -38,6 +38,17 @@ #include <assert.h> +static CxTreeIterator asc_scene_node_iterator( + AscSceneNode *node, + bool visit_on_exit +) { + return cx_tree_iterator( + node, visit_on_exit, + offsetof(AscSceneNode, children), + offsetof(AscSceneNode, next) + ); +} + void asc_scene_init(AscScene *scene) { if (scene->root != NULL) { asc_error("Scene is already initialized."); @@ -78,11 +89,7 @@ scene->rg_fonts_size = 0; // skip the root node deliberately, we know it's just the container - CxTreeIterator iter = cx_tree_iterator( - scene->root, false, - offsetof(AscSceneNode, children), - offsetof(AscSceneNode, next) - ); + CxTreeIterator iter = asc_scene_node_iterator(scene->root, false); cxIteratorNext(iter); // update the children and add them to the render groups @@ -103,8 +110,10 @@ if (node->need_transform_update) { assert(node->transform_update_func != NULL); node->need_transform_update = false; - asc_transform_identity(node->transform); + asc_transform_identity(node->local_transform); + asc_transform_copy(node->world_transform, node->parent->world_transform); node->transform_update_func(node); + asc_mat4f_mulst(node->final_transform, node->local_transform, node->world_transform); } // add to render group @@ -155,7 +164,9 @@ AscSceneNode *asc_scene_node_empty(void) { AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); node->free_func = (asc_scene_free_func) free; - asc_transform_identity(node->transform); + asc_transform_identity(node->local_transform); + asc_transform_identity(node->world_transform); + asc_transform_identity(node->final_transform); return node; } @@ -166,11 +177,7 @@ asc_scene_node_unlink(node); // free the entire subtree - CxTreeIterator iter = cx_tree_iterator( - node, true, - offsetof(AscSceneNode, children), - offsetof(AscSceneNode, next) - ); + CxTreeIterator iter = asc_scene_node_iterator(node, true); cx_foreach(AscSceneNode*, child, iter) { if (!iter.exiting) continue; if (child->free_func != NULL) { @@ -224,3 +231,10 @@ offsetof(AscBehaviorNode, next) ); } + +void asc_node_update_transform(AscSceneNode *node) { + CxTreeIterator iter = asc_scene_node_iterator(node, false); + cx_foreach(AscSceneNode*, n, iter) { + n->need_transform_update = true; + } +} \ No newline at end of file