simplify how transforms work

Thu, 28 Mar 2024 23:30:21 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 28 Mar 2024 23:30:21 +0100
changeset 45
18de2af03531
parent 44
b3da4096c607
child 46
d3285aed65b3

simplify how transforms work

src/ascension/ascension.h file | annotate | diff | comparison | revisions
src/ascension/datatypes.h file | annotate | diff | comparison | revisions
src/ascension/scene.h file | annotate | diff | comparison | revisions
src/ascension/text.h file | annotate | diff | comparison | revisions
src/ascension/transform.h file | annotate | diff | comparison | revisions
src/scene.c file | annotate | diff | comparison | revisions
src/text.c file | annotate | diff | comparison | revisions
test/snake.c file | annotate | diff | comparison | revisions
     1.1 --- a/src/ascension/ascension.h	Tue Mar 26 20:37:21 2024 +0100
     1.2 +++ b/src/ascension/ascension.h	Thu Mar 28 23:30:21 2024 +0100
     1.3 @@ -34,9 +34,5 @@
     1.4  #include "text.h"
     1.5  #include "scene.h"
     1.6  
     1.7 -// some auto-casting magic
     1.8 -#define asc_node_update_transform(n) \
     1.9 -    asc_node_update_transform(((AscSceneNode*)n))
    1.10 -
    1.11  #endif /* ASCENSION_H */
    1.12  
     2.1 --- a/src/ascension/datatypes.h	Tue Mar 26 20:37:21 2024 +0100
     2.2 +++ b/src/ascension/datatypes.h	Thu Mar 28 23:30:21 2024 +0100
     2.3 @@ -57,6 +57,7 @@
     2.4  typedef union asc_vec3f {
     2.5      struct { float x, y, z; };
     2.6      struct { float width, height, depth; };
     2.7 +    struct { float pitch, yaw, roll; };
     2.8      float data[3];
     2.9  } asc_vec3f;
    2.10  
     3.1 --- a/src/ascension/scene.h	Tue Mar 26 20:37:21 2024 +0100
     3.2 +++ b/src/ascension/scene.h	Thu Mar 28 23:30:21 2024 +0100
     3.3 @@ -61,12 +61,13 @@
     3.4      AscBehaviorNode *behaviors;
     3.5      asc_scene_free_func free_func;
     3.6      asc_scene_update_func update_func;
     3.7 -    asc_scene_update_func transform_update_func;
     3.8      asc_scene_draw_func draw_func;
     3.9      unsigned depth;
    3.10 +    asc_vec3f position;
    3.11 +    asc_vec3f rotation;
    3.12 +    asc_vec3f scale;
    3.13 +    asc_transform transform;
    3.14      asc_transform world_transform;
    3.15 -    asc_transform local_transform;
    3.16 -    asc_transform final_transform;
    3.17      enum AscRenderGroup render_group;
    3.18      bool need_graphics_update;
    3.19      bool need_transform_update;
    3.20 @@ -142,8 +143,52 @@
    3.21  #define asc_node_update(node) \
    3.22      ((AscSceneNode*)node)->need_graphics_update = true
    3.23  
    3.24 +
    3.25  __attribute__((__nonnull__))
    3.26 -void asc_node_update_transform(AscSceneNode *node);
    3.27 +void asc_update_transform(AscSceneNode *node);
    3.28 +
    3.29 +
    3.30 +__attribute__((__nonnull__)) static inline
    3.31 +void asc_set_position(AscSceneNode *node, float x, float y, float z) {
    3.32 +    node->position.x = x;
    3.33 +    node->position.y = y;
    3.34 +    node->position.z = z;
    3.35 +    asc_update_transform(node);
    3.36 +}
    3.37 +
    3.38 +__attribute__((__nonnull__)) static inline
    3.39 +void asc_set_position2d(AscSceneNode *node, int x, int y) {
    3.40 +    node->position.x = (float)x;
    3.41 +    node->position.y = (float)y;
    3.42 +    node->position.z = 0.f;
    3.43 +    asc_update_transform(node);
    3.44 +}
    3.45 +
    3.46 +__attribute__((__nonnull__)) static inline
    3.47 +asc_vec2i asc_get_position2d(AscSceneNode *node) {
    3.48 +    return (asc_vec2i) {(int) node->position.x, (int) node->position.y};
    3.49 +}
    3.50 +
    3.51 +__attribute__((__nonnull__)) static inline
    3.52 +void asc_set_scale(AscSceneNode *node, float width, float height, float depth) {
    3.53 +    node->scale.width = width;
    3.54 +    node->scale.height = height;
    3.55 +    node->scale.depth = depth;
    3.56 +    asc_update_transform(node);
    3.57 +}
    3.58 +
    3.59 +__attribute__((__nonnull__)) static inline
    3.60 +void asc_set_scale2d(AscSceneNode *node, int width, int height) {
    3.61 +    node->scale.width = (float)width;
    3.62 +    node->scale.height = (float)height;
    3.63 +    node->scale.depth = 1.f;
    3.64 +    asc_update_transform(node);
    3.65 +}
    3.66 +
    3.67 +__attribute__((__nonnull__)) static inline
    3.68 +asc_vec2i asc_get_scale2d(AscSceneNode *node) {
    3.69 +    return (asc_vec2i) {(int) node->scale.width, (int) node->scale.height};
    3.70 +}
    3.71  
    3.72  #endif // ASCENSION_SCENE_H
    3.73  
     4.1 --- a/src/ascension/text.h	Tue Mar 26 20:37:21 2024 +0100
     4.2 +++ b/src/ascension/text.h	Thu Mar 28 23:30:21 2024 +0100
     4.3 @@ -35,12 +35,10 @@
     4.4      extend_asc_scene_node;
     4.5      char *text;
     4.6      AscFont const *font;
     4.7 -    asc_vec2i position;
     4.8      asc_col4i color;
     4.9      unsigned max_width;
    4.10      bool hidden;
    4.11      bool centered;
    4.12 -    asc_vec2i dimension;
    4.13      unsigned tex_id;
    4.14  } AscText;
    4.15  
     5.1 --- a/src/ascension/transform.h	Tue Mar 26 20:37:21 2024 +0100
     5.2 +++ b/src/ascension/transform.h	Thu Mar 28 23:30:21 2024 +0100
     5.3 @@ -57,42 +57,41 @@
     5.4  
     5.5  ASC_TRANFORM_FUNC void asc_transform_translate(
     5.6          asc_transform transform,
     5.7 -        float x, float y, float z
     5.8 +        asc_vec3f vec
     5.9  ) {
    5.10 -    transform[asc_mat4_index(3, 0)] += x;
    5.11 -    transform[asc_mat4_index(3, 1)] += y;
    5.12 -    transform[asc_mat4_index(3, 2)] += z;
    5.13 -}
    5.14 -
    5.15 -ASC_TRANFORM_FUNC void asc_transform_translate2i(
    5.16 -        asc_transform transform,
    5.17 -        asc_vec2i position
    5.18 -) {
    5.19 -    asc_transform_translate(
    5.20 -            transform,
    5.21 -            (float) position.x, (float) position.y, 0
    5.22 -    );
    5.23 +    transform[asc_mat4_index(3, 0)] += vec.x;
    5.24 +    transform[asc_mat4_index(3, 1)] += vec.y;
    5.25 +    transform[asc_mat4_index(3, 2)] += vec.z;
    5.26  }
    5.27  
    5.28  ASC_TRANFORM_FUNC void asc_transform_scale(
    5.29          asc_transform transform,
    5.30 -        float x, float y, float z
    5.31 +        asc_vec3f vec
    5.32  ) {
    5.33      for (unsigned i = 0 ; i < 3 ; i++) {
    5.34 -        transform[asc_mat4_index(0, i)] *= x;
    5.35 -        transform[asc_mat4_index(1, i)] *= y;
    5.36 -        transform[asc_mat4_index(2, i)] *= z;
    5.37 +        transform[asc_mat4_index(0, i)] *= vec.width;
    5.38 +        transform[asc_mat4_index(1, i)] *= vec.height;
    5.39 +        transform[asc_mat4_index(2, i)] *= vec.depth;
    5.40      }
    5.41  }
    5.42  
    5.43 -ASC_TRANFORM_FUNC void asc_transform_scale2i(
    5.44 +ASC_TRANFORM_FUNC void asc_transform_rotate(
    5.45          asc_transform transform,
    5.46 -        asc_vec2i dimensions
    5.47 +        asc_vec3f vec
    5.48  ) {
    5.49 -    asc_transform_scale(
    5.50 -            transform,
    5.51 -            (float) dimensions.width, (float) dimensions.height, 0
    5.52 -    );
    5.53 +    // TODO: implement
    5.54 +}
    5.55 +
    5.56 +ASC_TRANFORM_FUNC void asc_transform_from_parts(
    5.57 +        asc_transform transform,
    5.58 +        asc_vec3f position,
    5.59 +        asc_vec3f scale,
    5.60 +        asc_vec3f rotation
    5.61 +) {
    5.62 +    asc_transform_identity(transform);
    5.63 +    asc_transform_scale(transform, scale);
    5.64 +    asc_transform_translate(transform, position);
    5.65 +    asc_transform_rotate(transform, rotation);
    5.66  }
    5.67  
    5.68  #endif //ASCENSION_TRANSFORM_H
     6.1 --- a/src/scene.c	Tue Mar 26 20:37:21 2024 +0100
     6.2 +++ b/src/scene.c	Thu Mar 28 23:30:21 2024 +0100
     6.3 @@ -123,12 +123,18 @@
     6.4              node->update_func(node);
     6.5          }
     6.6          if (node->need_transform_update) {
     6.7 -            assert(node->transform_update_func != NULL);
     6.8              node->need_transform_update = false;
     6.9 -            asc_transform_identity(node->local_transform);
    6.10 -            asc_transform_copy(node->world_transform, node->parent->world_transform);
    6.11 -            node->transform_update_func(node);
    6.12 -            asc_mat4f_mulst(node->final_transform, node->local_transform, node->world_transform);
    6.13 +            asc_transform_from_parts(
    6.14 +                    node->transform,
    6.15 +                    node->position,
    6.16 +                    node->scale,
    6.17 +                    node->rotation
    6.18 +            );
    6.19 +            asc_mat4f_mulst(
    6.20 +                    node->world_transform,
    6.21 +                    node->transform,
    6.22 +                    node->parent->world_transform
    6.23 +            );
    6.24          }
    6.25  
    6.26          // add to render group
    6.27 @@ -174,7 +180,7 @@
    6.28          // Sprites
    6.29          // -------
    6.30          // TODO: see if we can really always ignore the view matrix
    6.31 -        shader = &asc_context.active_window->glctx.shader.sprite;
    6.32 +        shader = &asc_context.active_window->glctx.shader.sprite.base;
    6.33          glUseProgram(shader->id);
    6.34          glUniformMatrix4fv(shader->projection, 1,
    6.35                             GL_FALSE, camera->projection);
    6.36 @@ -192,9 +198,8 @@
    6.37  AscSceneNode *asc_scene_node_empty(void) {
    6.38      AscSceneNode *node = calloc(1, sizeof(AscSceneNode));
    6.39      node->free_func = (asc_scene_free_func) free;
    6.40 -    asc_transform_identity(node->local_transform);
    6.41 +    asc_transform_identity(node->transform);
    6.42      asc_transform_identity(node->world_transform);
    6.43 -    asc_transform_identity(node->final_transform);
    6.44      return node;
    6.45  }
    6.46  
    6.47 @@ -260,9 +265,12 @@
    6.48      );
    6.49  }
    6.50  
    6.51 -void asc_node_update_transform(AscSceneNode *node) {
    6.52 +void asc_update_transform(AscSceneNode *node) {
    6.53 +    if (node->need_transform_update) return;
    6.54 +
    6.55      CxTreeIterator iter = asc_scene_node_iterator(node, false);
    6.56      cx_foreach(AscSceneNode*, n, iter) {
    6.57 +        // TODO: break/continue when subtree is already marked for update
    6.58          n->need_transform_update = true;
    6.59      }
    6.60 -}
    6.61 \ No newline at end of file
    6.62 +}
     7.1 --- a/src/text.c	Tue Mar 26 20:37:21 2024 +0100
     7.2 +++ b/src/text.c	Thu Mar 28 23:30:21 2024 +0100
     7.3 @@ -42,7 +42,7 @@
     7.4  
     7.5      // Upload model matrix
     7.6      glUniformMatrix4fv(shader->base.model, 1,
     7.7 -                       GL_FALSE, node->base.final_transform);
     7.8 +                       GL_FALSE, node->base.world_transform);
     7.9  
    7.10      // Upload surface
    7.11      glActiveTexture(GL_TEXTURE0);
    7.12 @@ -56,11 +56,6 @@
    7.13      asc_primitives_draw_plane();
    7.14  }
    7.15  
    7.16 -static void asc_text_update_transform(AscText *node) {
    7.17 -    asc_transform_scale2i(node->base.local_transform, node->dimension);
    7.18 -    asc_transform_translate2i(node->base.world_transform, node->position);
    7.19 -}
    7.20 -
    7.21  static void asc_text_update(AscText *node) {
    7.22      // short circuit if fully transparent or hidden, we don't need anything
    7.23      if (node->color.alpha == 0 || node->hidden) {
    7.24 @@ -87,9 +82,9 @@
    7.25          asc_error(SDL_GetError());
    7.26          return;
    7.27      }
    7.28 -    node->dimension.width = surface->w;
    7.29 -    node->dimension.height = surface->h;
    7.30 -    asc_node_update_transform((AscSceneNode *) node);
    7.31 +    node->base.scale.width = (float) surface->w;
    7.32 +    node->base.scale.height = (float) surface->h;
    7.33 +    asc_update_transform((AscSceneNode *) node);
    7.34  
    7.35      // Transfer Image Data
    7.36      // TODO: move the image data transfer to a separate function - we will need it more often
    7.37 @@ -113,11 +108,10 @@
    7.38      node->base.render_group = ASC_RENDER_GROUP_SPRITE_BLEND;
    7.39      node->base.free_func = (asc_scene_free_func) asc_text_free;
    7.40      node->base.update_func = (asc_scene_update_func) asc_text_update;
    7.41 -    node->base.transform_update_func = (asc_scene_update_func) asc_text_update_transform;
    7.42      node->base.draw_func = (asc_scene_draw_func) asc_text_draw;
    7.43  
    7.44 -    node->position.x = x;
    7.45 -    node->position.y = y;
    7.46 +    node->base.position.x = (float) x;
    7.47 +    node->base.position.y = (float) y;
    7.48      node->font = asc_context.active_font;
    7.49      node->color = asc_context.ink;
    7.50      if (text != NULL) {
    7.51 @@ -126,7 +120,6 @@
    7.52  
    7.53      // initialize
    7.54      asc_text_update(node);
    7.55 -    asc_text_update_transform(node);
    7.56  
    7.57      return &node->base;
    7.58  }
     8.1 --- a/test/snake.c	Tue Mar 26 20:37:21 2024 +0100
     8.2 +++ b/test/snake.c	Thu Mar 28 23:30:21 2024 +0100
     8.3 @@ -55,14 +55,15 @@
     8.4  }
     8.5  
     8.6  static void update_score_counter(AscSceneNode *node) {
     8.7 -    AscText *text = asc_text_data(node);
     8.8 -
     8.9      // tie to bottom left of the screen
    8.10      if (asc_window_active->resized) {
    8.11          asc_vec2i bottom_left = asc_window_active->dimensions;
    8.12 -        text->position.x = bottom_left.x - text->dimension.width - 10;
    8.13 -        text->position.y = bottom_left.y - text->dimension.height - 10;
    8.14 -        asc_node_update_transform(text);
    8.15 +        asc_vec2i scale = asc_get_scale2d(node);
    8.16 +        asc_set_position2d(
    8.17 +                node,
    8.18 +                bottom_left.x - scale.width - 10,
    8.19 +                bottom_left.y - scale.height - 10
    8.20 +        );
    8.21      }
    8.22  }
    8.23  

mercurial