Mercurial > hg > Game > Cerium
comparison Renderer/Engine/SceneGraphRoot.cc @ 539:3bc98f6d31ff draft
Reorganization..
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 12 Oct 2009 09:39:35 +0900 |
parents | |
children | 1a31b8820a4d |
comparison
equal
deleted
inserted
replaced
538:5641d121818e | 539:3bc98f6d31ff |
---|---|
1 #include <SDL.h> | |
2 #include <SDL_image.h> | |
3 #include <libxml/parser.h> | |
4 #include "SceneGraphRoot.h" | |
5 #include "xml.h" | |
6 #include "sys.h" | |
7 #include "TextureHash.h" | |
8 #include "texture.h" | |
9 #include "SGList.h" | |
10 | |
11 int cnt = 0; | |
12 | |
13 SceneGraphRoot::SceneGraphRoot(float w, float h) | |
14 { | |
15 sg_src = new SceneGraphPtr[SGLIST_LENGTH]; | |
16 camera = new Camera(w, h); | |
17 iterator = new SceneGraphIterator; | |
18 controller = create_controller(); | |
19 | |
20 sg_exec_tree = NULL; | |
21 sg_draw_tree = NULL; | |
22 sg_available_list = NULL; | |
23 sg_remove_list = NULL; | |
24 | |
25 // TODO | |
26 // 今はとりあえず camera を Root にしています | |
27 // 今はそれすらもしてません | |
28 //sg_exec_tree = camera; | |
29 } | |
30 | |
31 SceneGraphRoot::~SceneGraphRoot(void) | |
32 { | |
33 SceneGraphPtr p = sg_available_list; | |
34 | |
35 while (p) { | |
36 SceneGraphPtr tmp = p->next; | |
37 delete p; | |
38 p = tmp; | |
39 cnt--; | |
40 } | |
41 | |
42 p = sg_remove_list; | |
43 | |
44 while (p) { | |
45 SceneGraphPtr tmp = p->next; | |
46 delete p; | |
47 p = tmp; | |
48 cnt--; | |
49 } | |
50 | |
51 delete [] sg_src; | |
52 delete camera; | |
53 delete iterator; | |
54 delete controller; | |
55 } | |
56 | |
57 /** | |
58 * xml ファイルから生成された SceneGraph を sg_src に登録する。 | |
59 * | |
60 * @param sg SceneGraph created by xmlfile | |
61 */ | |
62 void | |
63 SceneGraphRoot::registSceneGraph(SceneGraphPtr sg) | |
64 { | |
65 for (int i = 0; i < SGLIST_LENGTH; i++) { | |
66 if (strcmp(sg->name, sglist_table[i]) == 0) { | |
67 sg->sgid = i; | |
68 sg_src[i] = sg; | |
69 return; | |
70 } | |
71 } | |
72 | |
73 fprintf(stderr, "error: (%s:%3d) Can't find Scene \"%s\"\n", | |
74 __FUNCTION__, __LINE__, sg->name); | |
75 } | |
76 | |
77 void | |
78 SceneGraphRoot::addNext(SceneGraphPtr sg) | |
79 { | |
80 SceneGraphPtr last = sg_available_list; | |
81 | |
82 if (!last) { | |
83 sg_available_list = sg; | |
84 } else { | |
85 while (last->next) { | |
86 last = last->next; | |
87 } | |
88 last->next = sg; | |
89 sg->prev = last; | |
90 } | |
91 | |
92 cnt++; | |
93 } | |
94 | |
95 /* XMLファイルからポリゴンを作成 */ | |
96 void | |
97 SceneGraphRoot::createFromXMLfile(TaskManager *manager, const char *xmlfile) | |
98 { | |
99 xmlDocPtr doc; | |
100 xmlNodePtr cur; | |
101 SceneGraphPtr tmp; | |
102 | |
103 /* パース DOM生成 */ | |
104 doc = xmlParseFile(xmlfile); | |
105 cur = xmlDocGetRootElement(doc); | |
106 | |
107 /* ?? */ | |
108 xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); | |
109 | |
110 /* XMLのノードを一つずつ解析 */ | |
111 for (cur=cur->children; cur; cur=cur->next) { | |
112 /* 扱うのはsurfaceオンリー */ | |
113 if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) { | |
114 continue; | |
115 } | |
116 | |
117 /* ポリゴン(SceneGraph)生成 */ | |
118 tmp = new SceneGraph(manager, cur); | |
119 | |
120 registSceneGraph(tmp); | |
121 } | |
122 | |
123 xmlFreeDoc(doc); | |
124 } | |
125 | |
126 SceneGraphPtr | |
127 SceneGraphRoot::createSceneGraph(int id) | |
128 { | |
129 SceneGraphPtr src; | |
130 SceneGraphPtr p; | |
131 | |
132 if (id < 0 || id > SGLIST_LENGTH) { | |
133 return NULL; | |
134 } | |
135 | |
136 /* オリジナルの SceneGraph */ | |
137 src = sg_src[id]; | |
138 | |
139 /* ユーザーにはオリジナルの clone を返す */ | |
140 p = src->clone(); | |
141 | |
142 addNext(p); | |
143 | |
144 return p; | |
145 } | |
146 | |
147 /** | |
148 * 何も表示しない、move,collision もしない SceneGraph を生成 | |
149 * いずれ、Transform3D 的なものに回す予定 | |
150 */ | |
151 SceneGraphPtr | |
152 SceneGraphRoot::createSceneGraph(void) | |
153 { | |
154 SceneGraphPtr p = new SceneGraph; | |
155 | |
156 addNext(p); | |
157 p->flag_drawable = 0; | |
158 | |
159 return p; | |
160 } | |
161 | |
162 void | |
163 SceneGraphRoot::speExecute(int screen_w, int screen_h) | |
164 { | |
165 | |
166 SceneGraphPtr list = sg_available_list; | |
167 // SceneGraphPtr t = sg_exec_tree; | |
168 // SceneGraphPtr cur_parent = camera; | |
169 | |
170 // 前フレームで描画した SceneGraph は削除 | |
171 allRemove(sg_remove_list); | |
172 | |
173 // 前フレームに作られた SceneGraph は描画用に移行 | |
174 // 現フレームでの操作は以下の tree,list には適用されない | |
175 sg_draw_tree = sg_exec_tree; | |
176 sg_remove_list = sg_available_list; | |
177 | |
178 // 現フレームで新しく SceneGraph がコピーされるので初期化 | |
179 sg_exec_tree = NULL; | |
180 sg_available_list = NULL; | |
181 | |
182 camera->move_execute(screen_w, screen_h); | |
183 camera->update(screen_w, screen_h); | |
184 | |
185 camera->children = NULL; | |
186 camera->lastChild = NULL; | |
187 | |
188 list->move_execute(screen_w, screen_h); | |
189 list->collision_check(screen_w, screen_h, list); | |
190 | |
191 list->frame++; | |
192 list = list->next; | |
193 | |
194 if(sg_exec_tree != NULL) { | |
195 return; | |
196 } | |
197 | |
198 /*removeのflagをもとにtreeを形成*/ | |
199 /* spe から送り返されてきた property の配列を見て生成する for()*/ | |
200 /* | |
201 for (Property *t = property[0]; is_end(t); t++){ | |
202 SceneGraphPtr s = application->scenegraph_factory(t); // SceneGraphNode を作る | |
203 t->scenegraph = s; // property list には SceneGraphへのポインタが入っている | |
204 application->scenegraph_connector(property[0], s); // add する | |
205 } | |
206 */ | |
207 | |
208 | |
209 | |
210 // 現在、allExecute が終わった時点では | |
211 // camera->children が User SceneGraph の root になる | |
212 | |
213 /** | |
214 * NULL じゃなかったら、setSceneData が呼ばれてるから | |
215 * そっちを次の Scene にする | |
216 */ | |
217 | |
218 sg_exec_tree = camera->children; | |
219 } | |
220 | |
221 | |
222 void | |
223 SceneGraphRoot::allExecute(int screen_w, int screen_h) | |
224 { | |
225 SceneGraphPtr list = sg_available_list; | |
226 SceneGraphPtr t = sg_exec_tree; | |
227 SceneGraphPtr cur_parent = camera; | |
228 | |
229 // 前フレームで描画した SceneGraph は削除 | |
230 allRemove(sg_remove_list); | |
231 | |
232 // 前フレームに作られた SceneGraph は描画用に移行 | |
233 // 現フレームでの操作は以下の tree,list には適用されない | |
234 sg_draw_tree = sg_exec_tree; | |
235 sg_remove_list = sg_available_list; | |
236 | |
237 // 現フレームで新しく SceneGraph がコピーされるので初期化 | |
238 sg_exec_tree = NULL; | |
239 sg_available_list = NULL; | |
240 | |
241 camera->move_execute(screen_w, screen_h); | |
242 camera->update(screen_w, screen_h); | |
243 | |
244 camera->children = NULL; | |
245 camera->lastChild = NULL; | |
246 | |
247 /*まずは全部動作させる*/ | |
248 while (list) { | |
249 | |
250 list->move_execute(screen_w, screen_h); | |
251 list->collision_check(screen_w, screen_h, list); | |
252 | |
253 list->frame++; | |
254 list = list->next; | |
255 | |
256 } | |
257 | |
258 if(sg_exec_tree != NULL) { | |
259 return; | |
260 } | |
261 | |
262 /*removeのflagをもとにtreeを形成*/ | |
263 while (t) { | |
264 SceneGraphPtr c = NULL; | |
265 if (!t->isRemoved()) { | |
266 c = t->clone(); | |
267 addNext(c); | |
268 cur_parent->addChild(c); | |
269 c->frame = t->frame; | |
270 /*親の回転、座標から、子の回転、座標を算出*/ | |
271 get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix); | |
272 } | |
273 | |
274 if (t->children != NULL && c != NULL) { | |
275 cur_parent = c; | |
276 t = t->children; | |
277 } else if (t->brother != NULL) { | |
278 t = t->brother; | |
279 } else { | |
280 while (t) { | |
281 if (t->brother != NULL) { | |
282 t = t->brother; | |
283 break; | |
284 } else { | |
285 if (t->parent == NULL) { | |
286 t = NULL; | |
287 break; | |
288 } else { | |
289 cur_parent = cur_parent->parent; | |
290 t = t->parent; | |
291 | |
292 } | |
293 } | |
294 } | |
295 } | |
296 } | |
297 | |
298 | |
299 | |
300 // 現在、allExecute が終わった時点では | |
301 // camera->children が User SceneGraph の root になる | |
302 | |
303 /** | |
304 * NULL じゃなかったら、setSceneData が呼ばれてるから | |
305 * そっちを次の Scene にする | |
306 */ | |
307 | |
308 sg_exec_tree = camera->children; | |
309 } | |
310 | |
311 void | |
312 SceneGraphRoot::allRemove(SceneGraphPtr list) | |
313 { | |
314 SceneGraphPtr p = list; | |
315 | |
316 while (p) { | |
317 SceneGraphPtr p1 = p->next; | |
318 delete p; | |
319 p = p1; | |
320 cnt--; | |
321 } | |
322 } | |
323 | |
324 void | |
325 SceneGraphRoot::checkRemove(void) | |
326 { | |
327 SceneGraphPtr p = sg_available_list; | |
328 SceneGraphPtr p1; | |
329 | |
330 while (p) { | |
331 p1 = p->next; | |
332 if (p->isRemoved()) { | |
333 sg_exec_tree = p->realRemoveFromTree(sg_exec_tree); | |
334 sg_available_list = p->realRemoveFromList(sg_available_list); | |
335 } | |
336 delete p; | |
337 p = p1; | |
338 } | |
339 } | |
340 | |
341 SceneGraphPtr | |
342 SceneGraphRoot::getExecuteSceneGraph(void) | |
343 { | |
344 return sg_exec_tree; | |
345 } | |
346 | |
347 SceneGraphPtr | |
348 SceneGraphRoot::getDrawSceneGraph(void) | |
349 { | |
350 return sg_draw_tree; | |
351 } | |
352 | |
353 void | |
354 SceneGraphRoot::updateControllerState(void) | |
355 { | |
356 controller->check(); | |
357 } | |
358 | |
359 void | |
360 SceneGraphRoot::setSceneData(SceneGraphPtr sg) | |
361 { | |
362 sg_exec_tree = sg; | |
363 } | |
364 | |
365 Pad* | |
366 SceneGraphRoot::getController(void) | |
367 { | |
368 return controller; | |
369 } | |
370 | |
371 SceneGraphIteratorPtr | |
372 SceneGraphRoot::getIterator(void) | |
373 { | |
374 iterator->set(sg_remove_list); | |
375 return iterator; | |
376 } | |
377 | |
378 SceneGraphIteratorPtr | |
379 SceneGraphRoot::getIterator(SceneGraphPtr list) | |
380 { | |
381 iterator->set(list); | |
382 return iterator; | |
383 } | |
384 | |
385 CameraPtr | |
386 SceneGraphRoot::getCamera(void) | |
387 { | |
388 return camera; | |
389 } |