Thu, 21 Mar 2024 20:24:31 +0100
implement that nodes inherit the world transform of their parent
src/ascension/datatypes.h | file | annotate | diff | comparison | revisions | |
src/ascension/scene.h | file | annotate | diff | comparison | revisions | |
src/scene.c | file | annotate | diff | comparison | revisions | |
src/text.c | file | annotate | diff | comparison | revisions |
1.1 --- a/src/ascension/datatypes.h Fri Mar 15 00:06:59 2024 +0100 1.2 +++ b/src/ascension/datatypes.h Thu Mar 21 20:24:31 2024 +0100 1.3 @@ -149,4 +149,20 @@ 1.4 mat[asc_mat4_index(3,3)] = 1; 1.5 } 1.6 1.7 +static inline void asc_mat4f_mulst( 1.8 + asc_mat4f dest, 1.9 + asc_mat4f const left, 1.10 + asc_mat4f const right 1.11 +) { 1.12 + for (unsigned i = 0; i < 4; i++) { 1.13 + for (unsigned j = 0; j < 4; j++) { 1.14 + dest[asc_mat4_index(i, j)] = 0; 1.15 + for (int k = 0; k < 4; k++) { 1.16 + dest[asc_mat4_index(i,j)] += 1.17 + left[asc_mat4_index(i,k)] * right[asc_mat4_index(k,j)]; 1.18 + } 1.19 + } 1.20 + } 1.21 +} 1.22 + 1.23 #endif //ASCENSION_DATATYPES_H
2.1 --- a/src/ascension/scene.h Fri Mar 15 00:06:59 2024 +0100 2.2 +++ b/src/ascension/scene.h Thu Mar 21 20:24:31 2024 +0100 2.3 @@ -64,7 +64,9 @@ 2.4 asc_scene_update_func update_func; 2.5 asc_scene_update_func transform_update_func; 2.6 asc_scene_draw_func draw_func; 2.7 - asc_transform transform; 2.8 + asc_transform world_transform; 2.9 + asc_transform local_transform; 2.10 + asc_transform final_transform; 2.11 enum AscRenderGroup render_group; 2.12 bool need_full_update; 2.13 bool need_transform_update; 2.14 @@ -75,12 +77,8 @@ 2.15 */ 2.16 #define extend_asc_scene_node AscSceneNode base 2.17 2.18 -#define asc_node(obj) ((AscSceneNode*)obj) 2.19 - 2.20 #define asc_node_update(node) \ 2.21 ((AscSceneNode*)node)->need_full_update = true 2.22 -#define asc_node_update_transform(node) \ 2.23 - ((AscSceneNode*)node)->need_transform_update = true 2.24 2.25 struct asc_render_group_entry { 2.26 asc_scene_draw_func draw; 2.27 @@ -144,5 +142,8 @@ 2.28 __attribute__((__nonnull__)) 2.29 void asc_scene_remove_behavior(AscBehaviorNode *node); 2.30 2.31 +__attribute__((__nonnull__)) 2.32 +void asc_node_update_transform(AscSceneNode *node); 2.33 + 2.34 #endif // ASCENSION_SCENE_H 2.35
3.1 --- a/src/scene.c Fri Mar 15 00:06:59 2024 +0100 3.2 +++ b/src/scene.c Thu Mar 21 20:24:31 2024 +0100 3.3 @@ -38,6 +38,17 @@ 3.4 3.5 #include <assert.h> 3.6 3.7 +static CxTreeIterator asc_scene_node_iterator( 3.8 + AscSceneNode *node, 3.9 + bool visit_on_exit 3.10 +) { 3.11 + return cx_tree_iterator( 3.12 + node, visit_on_exit, 3.13 + offsetof(AscSceneNode, children), 3.14 + offsetof(AscSceneNode, next) 3.15 + ); 3.16 +} 3.17 + 3.18 void asc_scene_init(AscScene *scene) { 3.19 if (scene->root != NULL) { 3.20 asc_error("Scene is already initialized."); 3.21 @@ -78,11 +89,7 @@ 3.22 scene->rg_fonts_size = 0; 3.23 3.24 // skip the root node deliberately, we know it's just the container 3.25 - CxTreeIterator iter = cx_tree_iterator( 3.26 - scene->root, false, 3.27 - offsetof(AscSceneNode, children), 3.28 - offsetof(AscSceneNode, next) 3.29 - ); 3.30 + CxTreeIterator iter = asc_scene_node_iterator(scene->root, false); 3.31 cxIteratorNext(iter); 3.32 3.33 // update the children and add them to the render groups 3.34 @@ -103,8 +110,10 @@ 3.35 if (node->need_transform_update) { 3.36 assert(node->transform_update_func != NULL); 3.37 node->need_transform_update = false; 3.38 - asc_transform_identity(node->transform); 3.39 + asc_transform_identity(node->local_transform); 3.40 + asc_transform_copy(node->world_transform, node->parent->world_transform); 3.41 node->transform_update_func(node); 3.42 + asc_mat4f_mulst(node->final_transform, node->local_transform, node->world_transform); 3.43 } 3.44 3.45 // add to render group 3.46 @@ -155,7 +164,9 @@ 3.47 AscSceneNode *asc_scene_node_empty(void) { 3.48 AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); 3.49 node->free_func = (asc_scene_free_func) free; 3.50 - asc_transform_identity(node->transform); 3.51 + asc_transform_identity(node->local_transform); 3.52 + asc_transform_identity(node->world_transform); 3.53 + asc_transform_identity(node->final_transform); 3.54 return node; 3.55 } 3.56 3.57 @@ -166,11 +177,7 @@ 3.58 asc_scene_node_unlink(node); 3.59 3.60 // free the entire subtree 3.61 - CxTreeIterator iter = cx_tree_iterator( 3.62 - node, true, 3.63 - offsetof(AscSceneNode, children), 3.64 - offsetof(AscSceneNode, next) 3.65 - ); 3.66 + CxTreeIterator iter = asc_scene_node_iterator(node, true); 3.67 cx_foreach(AscSceneNode*, child, iter) { 3.68 if (!iter.exiting) continue; 3.69 if (child->free_func != NULL) { 3.70 @@ -224,3 +231,10 @@ 3.71 offsetof(AscBehaviorNode, next) 3.72 ); 3.73 } 3.74 + 3.75 +void asc_node_update_transform(AscSceneNode *node) { 3.76 + CxTreeIterator iter = asc_scene_node_iterator(node, false); 3.77 + cx_foreach(AscSceneNode*, n, iter) { 3.78 + n->need_transform_update = true; 3.79 + } 3.80 +} 3.81 \ No newline at end of file
4.1 --- a/src/text.c Fri Mar 15 00:06:59 2024 +0100 4.2 +++ b/src/text.c Thu Mar 21 20:24:31 2024 +0100 4.3 @@ -39,7 +39,7 @@ 4.4 4.5 // Upload model matrix 4.6 glUniformMatrix4fv(ASC_SHADER_FONT.base.model, 1, 4.7 - GL_FALSE, node->base.transform); 4.8 + GL_FALSE, node->base.final_transform); 4.9 4.10 // Upload surface 4.11 glActiveTexture(GL_TEXTURE0); 4.12 @@ -51,8 +51,8 @@ 4.13 } 4.14 4.15 static void asc_text_update_transform(AscText *node) { 4.16 - asc_transform_scale(node->base.transform, (float) node->dimension.width, (float) node->dimension.height, 0); 4.17 - asc_transform_translate2i(node->base.transform, node->position); 4.18 + asc_transform_scale2i(node->base.local_transform, node->dimension); 4.19 + asc_transform_translate2i(node->base.world_transform, node->position); 4.20 } 4.21 4.22 static void asc_text_update(AscText *node) {