implement that nodes inherit the world transform of their parent

Thu, 21 Mar 2024 20:24:31 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 21 Mar 2024 20:24:31 +0100
changeset 38
6e5629ea4c5c
parent 37
8a8cc6725b48
child 39
7cf310cc47cb

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) {

mercurial