--- 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 +}