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 }