82 // update the children and add them to the render groups |
83 // update the children and add them to the render groups |
83 cx_foreach(AscSceneNode*, node, iter) { |
84 cx_foreach(AscSceneNode*, node, iter) { |
84 node->depth = iter.depth; |
85 node->depth = iter.depth; |
85 |
86 |
86 // skip hidden nodes (and all their children) |
87 // skip hidden nodes (and all their children) |
87 if (node->hidden) { |
88 if (asc_test_flag(node->flags, ASC_SCENE_NODE_HIDDEN)) { |
88 cxTreeVisitorContinue(iter); |
89 cxTreeVisitorContinue(iter); |
89 } |
90 } |
90 |
91 |
91 // execute behaviors, first |
92 // execute behaviors, first |
92 if (node->behaviors != NULL) { |
93 if (node->behaviors != NULL) { |
95 behavior(node); |
96 behavior(node); |
96 } |
97 } |
97 } |
98 } |
98 |
99 |
99 // TODO: implement culling |
100 // TODO: implement culling |
100 // TODO: implement a hidden flag (requires UCX tree-continue function) |
|
101 |
101 |
102 // check if geometry needs update |
102 // check if geometry needs update |
103 if (node->need_graphics_update) { |
103 if (asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_GRAPHICS)) { |
104 assert(node->update_func != NULL); |
104 assert(node->update_func != NULL); |
105 node->need_graphics_update = false; |
105 asc_clear_flag(node->flags, ASC_SCENE_NODE_UPDATE_GRAPHICS); |
106 node->update_func(node); |
106 node->update_func(node); |
107 } |
107 } |
108 if (node->need_transform_update) { |
108 if (asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM)) { |
109 node->need_transform_update = false; |
109 asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM); |
110 asc_transform_from_parts( |
110 asc_transform_from_parts( |
111 node->transform, |
111 node->transform, |
112 node->position, |
112 node->position, |
113 node->scale, |
113 node->scale, |
114 node->rotation |
114 node->rotation |
240 if (node->behaviors != NULL) { |
240 if (node->behaviors != NULL) { |
241 cxListFindRemove(node->behaviors, behavior); |
241 cxListFindRemove(node->behaviors, behavior); |
242 } |
242 } |
243 } |
243 } |
244 |
244 |
245 void asc_update_transform(AscSceneNode *node) { |
245 void asc_node_update(AscSceneNode *node) { |
246 if (node->need_transform_update) return; |
246 asc_set_flag(node->flags, ASC_SCENE_NODE_UPDATE_GRAPHICS); |
|
247 } |
|
248 |
|
249 void asc_node_update_transform(AscSceneNode *node) { |
|
250 // fast skip if node is already marked |
|
251 if (asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM)) { |
|
252 return; |
|
253 } |
247 |
254 |
248 CxTreeIterator iter = asc_scene_node_iterator(node, false); |
255 CxTreeIterator iter = asc_scene_node_iterator(node, false); |
249 cx_foreach(AscSceneNode*, n, iter) { |
256 cx_foreach(AscSceneNode*, n, iter) { |
250 // TODO: break/continue when subtree is already marked for update |
257 if (asc_test_flag(n->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM)) { |
251 n->need_transform_update = true; |
258 cxTreeIteratorContinue(iter); |
252 } |
259 } |
253 } |
260 asc_set_flag(n->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM); |
|
261 } |
|
262 } |