src/scene.c

changeset 33
e7ddb52facd3
parent 32
86468a71dd73
child 37
8a8cc6725b48
equal deleted inserted replaced
32:86468a71dd73 33:e7ddb52facd3
30 30
31 #include <cx/tree.h> 31 #include <cx/tree.h>
32 32
33 #include <assert.h> 33 #include <assert.h>
34 34
35 #define node_layout_ \
36 offsetof(AscSceneNode, parent), offsetof(AscSceneNode, children), \
37 offsetof(AscSceneNode, prev), offsetof(AscSceneNode, next)
38 #define child_list_off_ \ 35 #define child_list_off_ \
39 offsetof(AscSceneNode, children), offsetof(AscSceneNode, next) 36 offsetof(AscSceneNode, children), offsetof(AscSceneNode, next)
40 37
41 void asc_scene_init(AscScene *scene) { 38 void asc_scene_init(AscScene *scene) {
42 if (scene->root != NULL) { 39 if (scene->root != NULL) {
59 CxTreeIterator iter = cx_tree_iterator(scene->root, false, child_list_off_); 56 CxTreeIterator iter = cx_tree_iterator(scene->root, false, child_list_off_);
60 57
61 // skip the root node deliberately, we know it's just the container 58 // skip the root node deliberately, we know it's just the container
62 cxIteratorNext(iter); 59 cxIteratorNext(iter);
63 60
64 // draw the children 61 // update the children
65 cx_foreach(AscSceneNode*, node, iter) { 62 cx_foreach(AscSceneNode*, node, iter) {
63 // execute behaviors, first
64 AscBehaviorNode *behavior = node->behaviors;
65 while (behavior) {
66 behavior->func(node);
67 behavior = behavior->next;
68 }
69
70 // check if geometry needs update
66 if (node->need_update && node->update_func != NULL) { 71 if (node->need_update && node->update_func != NULL) {
67 node->need_update = false; 72 node->need_update = false;
68 asc_transform_copy(node->transform, node->parent->transform); 73 asc_transform_copy(node->transform, node->parent->transform);
69 node->update_func(node); 74 node->update_func(node);
70 } 75 }
76
71 // TODO: don't visit the tree for drawing, visit the render groups 77 // TODO: don't visit the tree for drawing, visit the render groups
72 if (node->draw_func != NULL) { 78 if (node->draw_func != NULL) {
73 node->draw_func(node); 79 node->draw_func(node);
74 } 80 }
75 } 81 }
100 } 106 }
101 } 107 }
102 } 108 }
103 109
104 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { 110 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) {
105 cx_tree_link(parent, node, node_layout_); 111 cx_tree_link(
112 parent, node,
113 offsetof(AscSceneNode, parent),
114 offsetof(AscSceneNode, children),
115 offsetof(AscSceneNode, prev),
116 offsetof(AscSceneNode, next)
117 );
106 } 118 }
107 119
108 void asc_scene_node_unlink(AscSceneNode *node) { 120 void asc_scene_node_unlink(AscSceneNode *node) {
109 cx_tree_unlink(node, node_layout_); 121 cx_tree_unlink(
122 node,
123 offsetof(AscSceneNode, parent),
124 offsetof(AscSceneNode, children),
125 offsetof(AscSceneNode, prev),
126 offsetof(AscSceneNode, next)
127 );
110 } 128 }
129
130 AscBehaviorNode *asc_scene_add_behavior(AscSceneNode *node, asc_scene_update_func behavior) {
131 AscBehaviorNode *behavior_node = calloc(1, sizeof(AscBehaviorNode));
132 behavior_node->func = behavior;
133 cx_tree_link(
134 node,
135 behavior_node,
136 offsetof(AscBehaviorNode, parent),
137 offsetof(AscSceneNode, behaviors),
138 offsetof(AscBehaviorNode, prev),
139 offsetof(AscBehaviorNode, next)
140 );
141 return behavior_node;
142 }
143
144 void asc_scene_remove_behavior(AscBehaviorNode *node) {
145 cx_tree_unlink(
146 node,
147 offsetof(AscBehaviorNode, parent),
148 offsetof(AscSceneNode, behaviors),
149 offsetof(AscBehaviorNode, prev),
150 offsetof(AscBehaviorNode, next)
151 );
152 }

mercurial