1.1 --- a/src/scene.c Fri Mar 15 00:06:59 2024 +0100 1.2 +++ b/src/scene.c Thu Mar 21 20:24:31 2024 +0100 1.3 @@ -38,6 +38,17 @@ 1.4 1.5 #include <assert.h> 1.6 1.7 +static CxTreeIterator asc_scene_node_iterator( 1.8 + AscSceneNode *node, 1.9 + bool visit_on_exit 1.10 +) { 1.11 + return cx_tree_iterator( 1.12 + node, visit_on_exit, 1.13 + offsetof(AscSceneNode, children), 1.14 + offsetof(AscSceneNode, next) 1.15 + ); 1.16 +} 1.17 + 1.18 void asc_scene_init(AscScene *scene) { 1.19 if (scene->root != NULL) { 1.20 asc_error("Scene is already initialized."); 1.21 @@ -78,11 +89,7 @@ 1.22 scene->rg_fonts_size = 0; 1.23 1.24 // skip the root node deliberately, we know it's just the container 1.25 - CxTreeIterator iter = cx_tree_iterator( 1.26 - scene->root, false, 1.27 - offsetof(AscSceneNode, children), 1.28 - offsetof(AscSceneNode, next) 1.29 - ); 1.30 + CxTreeIterator iter = asc_scene_node_iterator(scene->root, false); 1.31 cxIteratorNext(iter); 1.32 1.33 // update the children and add them to the render groups 1.34 @@ -103,8 +110,10 @@ 1.35 if (node->need_transform_update) { 1.36 assert(node->transform_update_func != NULL); 1.37 node->need_transform_update = false; 1.38 - asc_transform_identity(node->transform); 1.39 + asc_transform_identity(node->local_transform); 1.40 + asc_transform_copy(node->world_transform, node->parent->world_transform); 1.41 node->transform_update_func(node); 1.42 + asc_mat4f_mulst(node->final_transform, node->local_transform, node->world_transform); 1.43 } 1.44 1.45 // add to render group 1.46 @@ -155,7 +164,9 @@ 1.47 AscSceneNode *asc_scene_node_empty(void) { 1.48 AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); 1.49 node->free_func = (asc_scene_free_func) free; 1.50 - asc_transform_identity(node->transform); 1.51 + asc_transform_identity(node->local_transform); 1.52 + asc_transform_identity(node->world_transform); 1.53 + asc_transform_identity(node->final_transform); 1.54 return node; 1.55 } 1.56 1.57 @@ -166,11 +177,7 @@ 1.58 asc_scene_node_unlink(node); 1.59 1.60 // free the entire subtree 1.61 - CxTreeIterator iter = cx_tree_iterator( 1.62 - node, true, 1.63 - offsetof(AscSceneNode, children), 1.64 - offsetof(AscSceneNode, next) 1.65 - ); 1.66 + CxTreeIterator iter = asc_scene_node_iterator(node, true); 1.67 cx_foreach(AscSceneNode*, child, iter) { 1.68 if (!iter.exiting) continue; 1.69 if (child->free_func != NULL) { 1.70 @@ -224,3 +231,10 @@ 1.71 offsetof(AscBehaviorNode, next) 1.72 ); 1.73 } 1.74 + 1.75 +void asc_node_update_transform(AscSceneNode *node) { 1.76 + CxTreeIterator iter = asc_scene_node_iterator(node, false); 1.77 + cx_foreach(AscSceneNode*, n, iter) { 1.78 + n->need_transform_update = true; 1.79 + } 1.80 +} 1.81 \ No newline at end of file