--- a/src/scene.c Mon Jul 07 22:41:48 2025 +0200 +++ b/src/scene.c Mon Jul 07 22:51:06 2025 +0200 @@ -149,35 +149,31 @@ // TODO: implement culling - // check if geometry needs update + // clear information flags from the previous frame asc_clear_flag(node->flags, ASC_SCENE_NODE_GRAPHICS_UPDATED | ASC_SCENE_NODE_TRANSFORM_UPDATED); + // check if geometry needs an update if (asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_GRAPHICS)) { asc_set_flag(node->flags, ASC_SCENE_NODE_GRAPHICS_UPDATED); asc_clear_flag(node->flags, ASC_SCENE_NODE_UPDATE_GRAPHICS); assert(node->update_func != NULL); node->update_func(node); } + // check if transform needs an update if (asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM)) { asc_set_flag(node->flags, ASC_SCENE_NODE_TRANSFORM_UPDATED); asc_clear_flag(node->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM); - - // Only recalculate from components if not using custom transform - if (!asc_test_flag(node->flags, ASC_SCENE_NODE_CUSTOM_TRANSFORM)) { - asc_transform_from_vec3f( + if (node->parent == scene->root) { + // skip unnecessary multiplication with unity matrix + asc_transform_copy(node->world_transform, node->transform); + } else { + asc_mat4f_mulst( + node->world_transform, node->transform, - node->position, - node->scale, - node->rotation + node->parent->world_transform ); } - - asc_mat4f_mulst( - node->world_transform, - node->transform, - node->parent->world_transform - ); } // add to render group