Thu, 28 Mar 2024 23:30:21 +0100
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 |
--- a/src/ascension/ascension.h Tue Mar 26 20:37:21 2024 +0100 +++ b/src/ascension/ascension.h Thu Mar 28 23:30:21 2024 +0100 @@ -34,9 +34,5 @@ #include "text.h" #include "scene.h" -// some auto-casting magic -#define asc_node_update_transform(n) \ - asc_node_update_transform(((AscSceneNode*)n)) - #endif /* ASCENSION_H */
--- a/src/ascension/datatypes.h Tue Mar 26 20:37:21 2024 +0100 +++ b/src/ascension/datatypes.h Thu Mar 28 23:30:21 2024 +0100 @@ -57,6 +57,7 @@ typedef union asc_vec3f { struct { float x, y, z; }; struct { float width, height, depth; }; + struct { float pitch, yaw, roll; }; float data[3]; } asc_vec3f;
--- a/src/ascension/scene.h Tue Mar 26 20:37:21 2024 +0100 +++ b/src/ascension/scene.h Thu Mar 28 23:30:21 2024 +0100 @@ -61,12 +61,13 @@ AscBehaviorNode *behaviors; asc_scene_free_func free_func; asc_scene_update_func update_func; - asc_scene_update_func transform_update_func; asc_scene_draw_func draw_func; unsigned depth; + asc_vec3f position; + asc_vec3f rotation; + asc_vec3f scale; + asc_transform transform; asc_transform world_transform; - asc_transform local_transform; - asc_transform final_transform; enum AscRenderGroup render_group; bool need_graphics_update; bool need_transform_update; @@ -142,8 +143,52 @@ #define asc_node_update(node) \ ((AscSceneNode*)node)->need_graphics_update = true + __attribute__((__nonnull__)) -void asc_node_update_transform(AscSceneNode *node); +void asc_update_transform(AscSceneNode *node); + + +__attribute__((__nonnull__)) static inline +void asc_set_position(AscSceneNode *node, float x, float y, float z) { + node->position.x = x; + node->position.y = y; + node->position.z = z; + asc_update_transform(node); +} + +__attribute__((__nonnull__)) static inline +void asc_set_position2d(AscSceneNode *node, int x, int y) { + node->position.x = (float)x; + node->position.y = (float)y; + node->position.z = 0.f; + asc_update_transform(node); +} + +__attribute__((__nonnull__)) static inline +asc_vec2i asc_get_position2d(AscSceneNode *node) { + return (asc_vec2i) {(int) node->position.x, (int) node->position.y}; +} + +__attribute__((__nonnull__)) static inline +void asc_set_scale(AscSceneNode *node, float width, float height, float depth) { + node->scale.width = width; + node->scale.height = height; + node->scale.depth = depth; + asc_update_transform(node); +} + +__attribute__((__nonnull__)) static inline +void asc_set_scale2d(AscSceneNode *node, int width, int height) { + node->scale.width = (float)width; + node->scale.height = (float)height; + node->scale.depth = 1.f; + asc_update_transform(node); +} + +__attribute__((__nonnull__)) static inline +asc_vec2i asc_get_scale2d(AscSceneNode *node) { + return (asc_vec2i) {(int) node->scale.width, (int) node->scale.height}; +} #endif // ASCENSION_SCENE_H
--- a/src/ascension/text.h Tue Mar 26 20:37:21 2024 +0100 +++ b/src/ascension/text.h Thu Mar 28 23:30:21 2024 +0100 @@ -35,12 +35,10 @@ extend_asc_scene_node; char *text; AscFont const *font; - asc_vec2i position; asc_col4i color; unsigned max_width; bool hidden; bool centered; - asc_vec2i dimension; unsigned tex_id; } AscText;
--- a/src/ascension/transform.h Tue Mar 26 20:37:21 2024 +0100 +++ b/src/ascension/transform.h Thu Mar 28 23:30:21 2024 +0100 @@ -57,42 +57,41 @@ ASC_TRANFORM_FUNC void asc_transform_translate( asc_transform transform, - float x, float y, float z + asc_vec3f vec ) { - transform[asc_mat4_index(3, 0)] += x; - transform[asc_mat4_index(3, 1)] += y; - transform[asc_mat4_index(3, 2)] += z; -} - -ASC_TRANFORM_FUNC void asc_transform_translate2i( - asc_transform transform, - asc_vec2i position -) { - asc_transform_translate( - transform, - (float) position.x, (float) position.y, 0 - ); + transform[asc_mat4_index(3, 0)] += vec.x; + transform[asc_mat4_index(3, 1)] += vec.y; + transform[asc_mat4_index(3, 2)] += vec.z; } ASC_TRANFORM_FUNC void asc_transform_scale( asc_transform transform, - float x, float y, float z + asc_vec3f vec ) { for (unsigned i = 0 ; i < 3 ; i++) { - transform[asc_mat4_index(0, i)] *= x; - transform[asc_mat4_index(1, i)] *= y; - transform[asc_mat4_index(2, i)] *= z; + transform[asc_mat4_index(0, i)] *= vec.width; + transform[asc_mat4_index(1, i)] *= vec.height; + transform[asc_mat4_index(2, i)] *= vec.depth; } } -ASC_TRANFORM_FUNC void asc_transform_scale2i( +ASC_TRANFORM_FUNC void asc_transform_rotate( asc_transform transform, - asc_vec2i dimensions + asc_vec3f vec ) { - asc_transform_scale( - transform, - (float) dimensions.width, (float) dimensions.height, 0 - ); + // TODO: implement +} + +ASC_TRANFORM_FUNC void asc_transform_from_parts( + asc_transform transform, + asc_vec3f position, + asc_vec3f scale, + asc_vec3f rotation +) { + asc_transform_identity(transform); + asc_transform_scale(transform, scale); + asc_transform_translate(transform, position); + asc_transform_rotate(transform, rotation); } #endif //ASCENSION_TRANSFORM_H
--- a/src/scene.c Tue Mar 26 20:37:21 2024 +0100 +++ b/src/scene.c Thu Mar 28 23:30:21 2024 +0100 @@ -123,12 +123,18 @@ node->update_func(node); } if (node->need_transform_update) { - assert(node->transform_update_func != NULL); node->need_transform_update = false; - 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); + asc_transform_from_parts( + node->transform, + node->position, + node->scale, + node->rotation + ); + asc_mat4f_mulst( + node->world_transform, + node->transform, + node->parent->world_transform + ); } // add to render group @@ -174,7 +180,7 @@ // Sprites // ------- // TODO: see if we can really always ignore the view matrix - shader = &asc_context.active_window->glctx.shader.sprite; + shader = &asc_context.active_window->glctx.shader.sprite.base; glUseProgram(shader->id); glUniformMatrix4fv(shader->projection, 1, GL_FALSE, camera->projection); @@ -192,9 +198,8 @@ AscSceneNode *asc_scene_node_empty(void) { AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); node->free_func = (asc_scene_free_func) free; - asc_transform_identity(node->local_transform); + asc_transform_identity(node->transform); asc_transform_identity(node->world_transform); - asc_transform_identity(node->final_transform); return node; } @@ -260,9 +265,12 @@ ); } -void asc_node_update_transform(AscSceneNode *node) { +void asc_update_transform(AscSceneNode *node) { + if (node->need_transform_update) return; + CxTreeIterator iter = asc_scene_node_iterator(node, false); cx_foreach(AscSceneNode*, n, iter) { + // TODO: break/continue when subtree is already marked for update n->need_transform_update = true; } -} \ No newline at end of file +}
--- a/src/text.c Tue Mar 26 20:37:21 2024 +0100 +++ b/src/text.c Thu Mar 28 23:30:21 2024 +0100 @@ -42,7 +42,7 @@ // Upload model matrix glUniformMatrix4fv(shader->base.model, 1, - GL_FALSE, node->base.final_transform); + GL_FALSE, node->base.world_transform); // Upload surface glActiveTexture(GL_TEXTURE0); @@ -56,11 +56,6 @@ asc_primitives_draw_plane(); } -static void asc_text_update_transform(AscText *node) { - asc_transform_scale2i(node->base.local_transform, node->dimension); - asc_transform_translate2i(node->base.world_transform, node->position); -} - static void asc_text_update(AscText *node) { // short circuit if fully transparent or hidden, we don't need anything if (node->color.alpha == 0 || node->hidden) { @@ -87,9 +82,9 @@ asc_error(SDL_GetError()); return; } - node->dimension.width = surface->w; - node->dimension.height = surface->h; - asc_node_update_transform((AscSceneNode *) node); + node->base.scale.width = (float) surface->w; + node->base.scale.height = (float) surface->h; + asc_update_transform((AscSceneNode *) node); // Transfer Image Data // TODO: move the image data transfer to a separate function - we will need it more often @@ -113,11 +108,10 @@ node->base.render_group = ASC_RENDER_GROUP_SPRITE_BLEND; node->base.free_func = (asc_scene_free_func) asc_text_free; node->base.update_func = (asc_scene_update_func) asc_text_update; - node->base.transform_update_func = (asc_scene_update_func) asc_text_update_transform; node->base.draw_func = (asc_scene_draw_func) asc_text_draw; - node->position.x = x; - node->position.y = y; + node->base.position.x = (float) x; + node->base.position.y = (float) y; node->font = asc_context.active_font; node->color = asc_context.ink; if (text != NULL) { @@ -126,7 +120,6 @@ // initialize asc_text_update(node); - asc_text_update_transform(node); return &node->base; }
--- a/test/snake.c Tue Mar 26 20:37:21 2024 +0100 +++ b/test/snake.c Thu Mar 28 23:30:21 2024 +0100 @@ -55,14 +55,15 @@ } static void update_score_counter(AscSceneNode *node) { - AscText *text = asc_text_data(node); - // tie to bottom left of the screen if (asc_window_active->resized) { asc_vec2i bottom_left = asc_window_active->dimensions; - text->position.x = bottom_left.x - text->dimension.width - 10; - text->position.y = bottom_left.y - text->dimension.height - 10; - asc_node_update_transform(text); + asc_vec2i scale = asc_get_scale2d(node); + asc_set_position2d( + node, + bottom_left.x - scale.width - 10, + bottom_left.y - scale.height - 10 + ); } }