src/scene.c

changeset 38
6e5629ea4c5c
parent 37
8a8cc6725b48
child 39
7cf310cc47cb
--- a/src/scene.c	Fri Mar 15 00:06:59 2024 +0100
+++ b/src/scene.c	Thu Mar 21 20:24:31 2024 +0100
@@ -38,6 +38,17 @@
 
 #include <assert.h>
 
+static CxTreeIterator asc_scene_node_iterator(
+        AscSceneNode *node,
+        bool visit_on_exit
+) {
+    return cx_tree_iterator(
+            node, visit_on_exit,
+            offsetof(AscSceneNode, children),
+            offsetof(AscSceneNode, next)
+    );
+}
+
 void asc_scene_init(AscScene *scene) {
     if (scene->root != NULL) {
         asc_error("Scene is already initialized.");
@@ -78,11 +89,7 @@
     scene->rg_fonts_size = 0;
 
     // skip the root node deliberately, we know it's just the container
-    CxTreeIterator iter = cx_tree_iterator(
-            scene->root, false,
-            offsetof(AscSceneNode, children),
-            offsetof(AscSceneNode, next)
-    );
+    CxTreeIterator iter = asc_scene_node_iterator(scene->root, false);
     cxIteratorNext(iter);
 
     // update the children and add them to the render groups
@@ -103,8 +110,10 @@
         if (node->need_transform_update) {
             assert(node->transform_update_func != NULL);
             node->need_transform_update = false;
-            asc_transform_identity(node->transform);
+            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);
         }
 
         // add to render group
@@ -155,7 +164,9 @@
 AscSceneNode *asc_scene_node_empty(void) {
     AscSceneNode *node = calloc(1, sizeof(AscSceneNode));
     node->free_func = (asc_scene_free_func) free;
-    asc_transform_identity(node->transform);
+    asc_transform_identity(node->local_transform);
+    asc_transform_identity(node->world_transform);
+    asc_transform_identity(node->final_transform);
     return node;
 }
 
@@ -166,11 +177,7 @@
     asc_scene_node_unlink(node);
 
     // free the entire subtree
-    CxTreeIterator iter = cx_tree_iterator(
-            node, true,
-            offsetof(AscSceneNode, children),
-            offsetof(AscSceneNode, next)
-    );
+    CxTreeIterator iter = asc_scene_node_iterator(node, true);
     cx_foreach(AscSceneNode*, child, iter) {
         if (!iter.exiting) continue;
         if (child->free_func != NULL) {
@@ -224,3 +231,10 @@
             offsetof(AscBehaviorNode, next)
     );
 }
+
+void asc_node_update_transform(AscSceneNode *node) {
+    CxTreeIterator iter = asc_scene_node_iterator(node, false);
+    cx_foreach(AscSceneNode*, n, iter) {
+        n->need_transform_update = true;
+    }
+}
\ No newline at end of file

mercurial