comparison Renderer/Engine/SceneGraphRoot.cc @ 0:04e28d8d3c6f

first commit
author Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
date Mon, 08 Nov 2010 01:23:25 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:04e28d8d3c6f
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 "Application.h"
10
11 static int cnt = 0;
12 static const int SGLIST_LENGTH = 138;
13 static int sg_src_size = SGLIST_LENGTH ;
14 static int sg_src_id = -1;
15 static SceneGraphPtr *sg_src;
16
17
18 SceneGraphRoot *sgroot;
19
20 SceneGraphRoot::SceneGraphRoot(float w, float h)
21 {
22 // SGLIST_LENGTH 決め打ちかぁ、動的生成にする場合上限決めておいた方がいいのかな
23 //
24 sg_src = (SceneGraphPtr*) malloc(sizeof(SceneGraphPtr)*SGLIST_LENGTH);
25
26 camera = new Camera(w, h, this);
27
28 iterator = new SceneGraphIterator;
29 controller = create_controller();
30
31 sg_exec_tree = NULL;
32 sg_draw_tree = NULL;
33 sg_available_list = NULL;
34 sg_remove_list = NULL;
35
36 sgroot = this;
37
38 screen_w = (int)w;
39 screen_h = (int)h;
40 int light_num = 4;
41 light_sysswitch = 0;
42
43 for (int i = 0; i < light_num; i++) {
44 light[i] = new SceneGraph;
45 light[i]->xyz[0] = 0;
46 light[i]->xyz[1] = 0;
47 light[i]->xyz[2] = 0;
48
49 light_switch[i] = 0;
50
51 }
52
53 move_finish_flag = 0;
54
55 // TODO
56 // 今はとりあえず camera を Root にしています
57 // 今はそれすらもしてません
58 //sg_exec_tree = camera;
59 }
60
61 SceneGraphRoot::~SceneGraphRoot()
62 {
63 SceneGraphPtr p = sg_available_list;
64
65 while (p) {
66 SceneGraphPtr tmp = p->next;
67 delete p;
68 p = tmp;
69 cnt--;
70 }
71
72 p = sg_remove_list;
73
74 while (p) {
75 SceneGraphPtr tmp = p->next;
76 delete p;
77 p = tmp;
78 cnt--;
79 }
80
81 free(sg_src);
82 delete camera;
83 int light_num = 4;
84 for (int i = 0; i < light_num; i++) {
85 delete light[i];
86 }
87 delete iterator;
88 delete controller;
89 }
90
91 /**
92 * xml ファイルから生成された SceneGraph を sg_src に登録する。
93 *
94 * @param sg SceneGraph created by xmlfile
95 */
96 void
97 SceneGraphRoot::registSceneGraph(SceneGraphPtr sg)
98 {
99 int dup;
100 if ((dup = getSgid(sg->name))>=0) { // while...
101 sg_src[dup]->name = "";
102 // we should remove this. but some one may use it...
103 }
104 if (sg_src_id+1> sg_src_size) {
105 sg_src_size *= 2;
106 sg_src = (SceneGraphPtr*)realloc(sg_src, sg_src_size*sizeof(SceneGraphPtr));
107 }
108 sg->sgid = ++sg_src_id;
109 sg_src[sg->sgid] = sg;
110 }
111
112
113 void
114 SceneGraphRoot::addNext(SceneGraphPtr sg)
115 {
116 SceneGraphPtr last = sg_available_list;
117
118 if (!last) {
119 sg_available_list = sg;
120 } else {
121 while (last->next) {
122 last = last->next;
123 }
124 last->next = sg;
125 sg->prev = last;
126 }
127
128 cnt++;
129 }
130
131 /* XMLファイルからポリゴンを作成 */
132 void
133 SceneGraphRoot::createFromXMLfile(TaskManager *manager, const char *xmlfile)
134 {
135 xmlDocPtr doc;
136 xmlNodePtr cur;
137 SceneGraphPtr tmp;
138
139 /* パース DOM生成 */
140 doc = xmlParseFile(xmlfile);
141 cur = xmlDocGetRootElement(doc);
142
143 /* ?? */
144 xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");
145
146 /* XMLのノードを一つずつ解析 */
147 for (cur=cur->children; cur; cur=cur->next) {
148 /* 扱うのはsurfaceオンリー */
149 if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) {
150 continue;
151 }
152
153 /* ポリゴン(SceneGraph)生成 */
154 tmp = new SceneGraph(manager, cur);
155 registSceneGraph(tmp);
156 }
157 xmlFreeDoc(doc);
158 }
159
160 void
161 SceneGraphRoot::createFromXMLmemory(TaskManager *manager, SceneGraph *node, char *data, int len)
162 {
163 xmlDocPtr doc;
164 xmlNodePtr cur;
165
166 // size は取れるはず、テスト用に mmap したデータを使う
167 /* パース DOM生成 */
168
169 doc = xmlParseMemory(data, len);
170 cur = xmlDocGetRootElement(doc);
171
172 /* ?? */
173 xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D");
174
175 /* XMLのノードを一つずつ解析 */
176 for (cur=cur->children; cur; cur=cur->next) {
177 /* 扱うのはsurfaceオンリー */
178 if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) {
179 continue;
180 }
181 /* ポリゴン(SceneGraph)生成 */
182 SceneGraphPtr original = new SceneGraph(manager, cur);
183 registSceneGraph(original);
184 SceneGraphPtr clone = createSceneGraph(original->sgid);
185 node->addChild(clone);
186 }
187 xmlFreeDoc(doc);
188 }
189
190 SceneGraphPtr
191 SceneGraphRoot::createSceneGraph(int id)
192 {
193 SceneGraphPtr src;
194 SceneGraphPtr p;
195
196 if (id < 0 || id > sg_src_size) {
197 printf("error: createSceneGraph(int id): id not found.\n");
198 return NULL;
199 }
200
201 /* オリジナルの SceneGraph */
202 src = sg_src[id];
203
204 /* ユーザーにはオリジナルの clone を返す */
205 p = src->clone();
206
207 /* move, collision に sgroot を渡したいのでここで sgroot を渡しておく*/
208 p->sgroot = (void *)this;
209
210 addNext(p);
211
212 return p;
213 }
214
215
216
217
218 SceneGraphPtr
219 SceneGraphRoot::createSceneGraph(const char *name)
220 {
221 SceneGraphPtr src;
222 SceneGraphPtr p;
223
224 int id = getSgid(name);
225 if (id < 0) {
226 printf("error: createSceneGraph(name): name object not found.\n");
227 return NULL;
228 }
229
230 /* オリジナルの SceneGraph */
231 src = sg_src[id];
232
233 /* ユーザーにはオリジナルの clone を返す */
234 p = src->clone();
235
236 /* move, collision に sgroot を渡したいのでここで sgroot を渡しておく*/
237 p->sgroot = (void *)this;
238
239 addNext(p);
240
241 return p;
242 }
243
244 int
245 SceneGraphRoot::getSgid(const char *name)
246 {
247 for(int i =0;i<= sg_src_id; i++) {
248 if (sg_src[i] && strcmp(name,sg_src[i]->name) == 0)
249 return i;
250 }
251 return -1;
252 }
253
254 int
255 SceneGraphRoot::getLast()
256 {
257 if (sg_src_id>=0)
258 return sg_src[sg_src_id]->sgid;
259 return -1;
260 }
261
262 /**
263 * 何も表示しない、move,collision もしない SceneGraph を生成
264 * いずれ、Transform3D 的なものに回す予定
265 */
266 SceneGraphPtr
267 SceneGraphRoot::createSceneGraph()
268 {
269 SceneGraphPtr p = new SceneGraph;
270
271 /* move, collision に sgroot を渡したいのでここで sgroot を渡しておく*/
272 p->sgroot = (void *)this;
273
274 addNext(p);
275 p->flag_drawable = 0;
276
277 return p;
278 }
279
280 void
281 SceneGraphRoot::speExecute(int screen_w, int screen_h)
282 {
283
284 SceneGraphPtr list = sg_available_list;
285 // SceneGraphPtr t = sg_exec_tree;
286 // SceneGraphPtr cur_parent = camera;
287
288 // 前フレームで描画した SceneGraph は削除
289 allRemove(sg_remove_list);
290
291 // 前フレームに作られた SceneGraph は描画用に移行
292 // 現フレームでの操作は以下の tree,list には適用されない
293 sg_draw_tree = sg_exec_tree;
294 sg_remove_list = sg_available_list;
295
296 // 現フレームで新しく SceneGraph がコピーされるので初期化
297 sg_exec_tree = NULL;
298 sg_available_list = NULL;
299
300 camera->move_execute(screen_w, screen_h);
301 camera->update(screen_w, screen_h);
302
303 camera->children = NULL;
304 camera->lastChild = NULL;
305
306 list->move_execute(screen_w, screen_h);
307 list->collision_check(screen_w, screen_h, list);
308
309 list->frame++;
310 list = list->next;
311
312 if(sg_exec_tree != NULL) {
313 return;
314 }
315
316 /*removeのflagをもとにtreeを形成*/
317 /* spe から送り返されてきた property の配列を見て生成する for()*/
318 /*
319 for (Property *t = (Property*)app->property[0]; is_end(t); t++){
320 SceneGraphPtr s = app->scenegraph_factory(t); // SceneGraphNode を作る
321 t->scenegraph = s; // property list には SceneGraphへのポインタが入っている
322 app->scenegraph_connector(property[0], s); // add する
323 }
324 */
325
326
327 // 現在、allExecute が終わった時点では
328 // camera->children が User SceneGraph の root になる
329
330 /**
331 * NULL じゃなかったら、setSceneData が呼ばれてるから
332 * そっちを次の Scene にする
333 */
334
335 sg_exec_tree = camera->children;
336 }
337
338
339
340 void
341 SceneGraphRoot::allExecute(int screen_w, int screen_h)
342 {
343 SceneGraphPtr list = sg_available_list;
344 SceneGraphPtr t = sg_exec_tree;
345 SceneGraphPtr cur_parent = camera;
346
347 // 前フレームで描画した SceneGraph は削除
348 allRemove(sg_remove_list);
349
350 // 前フレームに作られた SceneGraph は描画用に移行
351 // 現フレームでの操作は以下の tree,list には適用されない
352 sg_draw_tree = sg_exec_tree;
353 sg_remove_list = sg_available_list;
354
355 // 現フレームで新しく SceneGraph がコピーされるので初期化
356 sg_exec_tree = NULL;
357 sg_available_list = NULL;
358
359 camera->move_execute(screen_w, screen_h);
360 camera->update(screen_w, screen_h);
361
362 camera->children = NULL;
363 camera->lastChild = NULL;
364
365 /*まずは全部動作させる*/
366 while (list) {
367
368 list->move_execute(screen_w, screen_h);
369 list->collision_check(screen_w, screen_h, list);
370
371 list->frame++;
372 list = list->next;
373 }
374
375 int light_num = 4;
376 for (int i = 0; i < light_num; i++) {
377
378 get_matrix(light[i]->matrix, light[i]->angle, light[i]->xyz, camera->matrix);
379
380 light_vector[i*4] = 0.0f;
381 light_vector[i*4+1] = 0.0f;
382 light_vector[i*4+2] = 0.0f;
383 light_vector[i*4+3] = 1.0f;
384
385 ApplyMatrix(&light_vector[i*4], light[i]->matrix);
386
387 light_vector[i*4] /= light_vector[i*4+2];
388 light_vector[i*4+1] /= light_vector[i*4+2];
389
390 /*SIMD演算のため*/
391 light_vector[i*4+2] *= -1;
392 light_vector[i*4+3] *= -1;
393
394 }
395
396
397 if(sg_exec_tree != NULL) {
398 return;
399 }
400
401 /*removeのflagをもとにtreeを形成*/
402 while (t) {
403 SceneGraphPtr c = NULL;
404 if (!t->isRemoved()) {
405 c = t->clone();
406 addNext(c);
407 cur_parent->addChild(c);
408 c->frame = t->frame;
409 /*親の回転、座標から、子の回転、座標を算出*/
410 get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix);
411 /*法線用の行列。Cameraの行列を抜いている(Cameraのコンストラクタで、単位行列にしている)*/
412 get_matrix(c->real_matrix, c->angle, c->xyz, cur_parent->real_matrix);
413 //get_matrix(c->real_matrix, c->angle, c->xyz, camera->real_matrix);
414
415 }
416
417 if (t->children != NULL && c != NULL) {
418 cur_parent = c;
419 t = t->children;
420 } else if (t->brother != NULL) {
421 t = t->brother;
422 } else {
423 while (t) {
424 if (t->brother != NULL) {
425 t = t->brother;
426 break;
427 } else {
428 if (t->parent == NULL) {
429 t = NULL;
430 break;
431 } else {
432 cur_parent = cur_parent->parent;
433 t = t->parent;
434 }
435 }
436 }
437 }
438 }
439
440
441
442 // 現在、allExecute が終わった時点では
443 // camera->children が User SceneGraph の root になる
444
445 /**
446 * NULL じゃなかったら、setSceneData が呼ばれてるから
447 * そっちを次の Scene にする
448 */
449
450 sg_exec_tree = camera->children;
451 }
452
453 void
454 SceneGraphRoot::oneExecute(int screen_w, int screen_h)
455 {
456 SceneGraphPtr list = sg_available_list;
457 //SceneGraphPtr t = sg_exec_tree;
458 //SceneGraphPtr cur_parent = camera;
459
460 // 前フレームで描画した SceneGraph は削除
461 allRemove(sg_remove_list);
462
463 // 前フレームに作られた SceneGraph は描画用に移行
464 // 現フレームでの操作は以下の tree,list には適用されない
465 sg_draw_tree = sg_exec_tree;
466 sg_remove_list = sg_available_list;
467
468 // 現フレームで新しく SceneGraph がコピーされるので初期化
469 sg_exec_tree = NULL;
470 sg_available_list = NULL;
471
472 camera->move_execute(screen_w, screen_h);
473 camera->update(screen_w, screen_h);
474
475 camera->children = NULL;
476 camera->lastChild = NULL;
477
478 /* ここから */
479 list->move_execute(screen_w, screen_h);
480 // ここで move_execute から実行される move_task の処理が終わるまで待ちたい
481 //while(move_finish_flag == 0) {}
482 //move_finish_flag = 0;
483
484 list->create_sg_execute();
485
486 list->collision_check(screen_w, screen_h, list);
487 /* ここまで exec_task にする */
488
489
490 /* ここから下を exec_task の post_func に*/
491 list->frame++;
492 list = list->next;
493
494
495 int light_num = 4;
496 for (int i = 0; i < light_num; i++) {
497
498 get_matrix(light[i]->matrix, light[i]->angle, light[i]->xyz, camera->matrix);
499
500 light_vector[i*4] = 0.0f;
501 light_vector[i*4+1] = 0.0f;
502 light_vector[i*4+2] = 0.0f;
503 light_vector[i*4+3] = 1.0f;
504
505 ApplyMatrix(&light_vector[i*4], light[i]->matrix);
506
507 light_vector[i*4] /= light_vector[i*4+2];
508 light_vector[i*4+1] /= light_vector[i*4+2];
509
510 }
511
512 if(sg_exec_tree != NULL) {
513 return;
514 }
515 }
516
517 /*
518 ExecMove task の post func として呼んでやる
519 */
520 void
521 SceneGraphRoot::move_finish()
522 {
523 list->collision_check(screen_w, screen_h, list);
524
525 list->frame++;
526 //list = list->next;
527
528 int light_num = 4;
529 for (int i = 0; i < light_num; i++) {
530
531 get_matrix(light[i]->matrix, light[i]->angle, light[i]->xyz, camera->matrix);
532
533 light_vector[i*4] = 0.0f;
534 light_vector[i*4+1] = 0.0f;
535 light_vector[i*4+2] = 0.0f;
536 light_vector[i*4+3] = 1.0f;
537
538 ApplyMatrix(&light_vector[i*4], light[i]->matrix);
539
540 light_vector[i*4] /= light_vector[i*4+2];
541 light_vector[i*4+1] /= light_vector[i*4+2];
542
543 light_vector[i*4+2] *= -1;
544 light_vector[i*4+3] *= -1;
545 }
546
547 //sgchange->viewer->light_xyz_stock = getLightVector();
548 }
549
550
551 void
552 SceneGraphRoot::appTaskRegist(regist_func new_register)
553 {
554 this->regist = new_register;
555 }
556
557 void
558 SceneGraphRoot::regist_execute()
559 {
560 (*regist)(this);
561 }
562
563 void
564 SceneGraphRoot::allRemove(SceneGraphPtr list)
565 {
566 SceneGraphPtr p = list;
567
568 while (p) {
569 SceneGraphPtr p1 = p->next;
570 delete p;
571 p = p1;
572 cnt--;
573 }
574 }
575
576 void
577 SceneGraphRoot::checkRemove()
578 {
579 SceneGraphPtr p = sg_available_list;
580 SceneGraphPtr p1;
581
582 while (p) {
583 p1 = p->next;
584 if (p->isRemoved()) {
585 sg_exec_tree = p->realRemoveFromTree(sg_exec_tree);
586 sg_available_list = p->realRemoveFromList(sg_available_list);
587 }
588 delete p;
589 p = p1;
590 }
591 }
592
593 SceneGraphPtr
594 SceneGraphRoot::getExecuteSceneGraph()
595 {
596 return sg_exec_tree;
597 }
598
599 SceneGraphPtr
600 SceneGraphRoot::getDrawSceneGraph()
601 {
602 return sg_draw_tree;
603 }
604
605 void
606 SceneGraphRoot::updateControllerState()
607 {
608 controller->check();
609 }
610
611 void
612 SceneGraphRoot::setSceneData(SceneGraphPtr sg)
613 {
614 sg_exec_tree = sg;
615 }
616
617 Pad*
618 SceneGraphRoot::getController()
619 {
620 return controller;
621 }
622
623 SceneGraphIteratorPtr
624 SceneGraphRoot::getIterator()
625 {
626 iterator->set(sg_remove_list);
627 return iterator;
628 }
629
630 SceneGraphIteratorPtr
631 SceneGraphRoot::getIterator(SceneGraphPtr list)
632 {
633 iterator->set(list);
634 return iterator;
635 }
636
637 CameraPtr
638 SceneGraphRoot::getCamera()
639 {
640 return camera;
641 }
642
643
644 SceneGraphPtr
645 SceneGraphRoot::getLight(int id)
646 {
647
648 return light[id];
649
650 }
651
652
653 float*
654 SceneGraphRoot::getLightVector()
655 {
656 return light_vector;
657 }
658
659 int*
660 SceneGraphRoot::getLightSwitch()
661 {
662 return light_switch;
663 }
664
665 int
666 SceneGraphRoot::getLightSysSwitch()
667 {
668 return light_sysswitch;
669 }
670
671 void
672 SceneGraphRoot::OnLightSwitch(int id)
673 {
674 light_switch[id] = 1;
675 }
676
677 void
678 SceneGraphRoot::OffLightSwitch(int id)
679 {
680 light_switch[id] = 0;
681 }
682
683 void
684 SceneGraphRoot::OnLightSysSwitch()
685 {
686
687 light_sysswitch = 1;
688
689 }
690
691 void
692 SceneGraphRoot::OffLightSysSwitch()
693 {
694
695 light_sysswitch = 0;
696
697 }
698
699
700 void
701 SceneGraphRoot::set_game_task(int id, void *property, int size, PostFunction post_func)
702 {
703 HTask *task = sgroot->tmanager->create_task(id);
704 task->set_cpu(SPE_ANY);
705 task->add_inData(property, size);
706 task->add_outData(property, size);
707 task->add_param((memaddr)1);
708 task->set_post(post_func, (void*)property, 0);
709 wait_game_task->wait_for(task);
710 task->spawn();
711 }
712
713 void
714 SceneGraphRoot::set_game_task(int id, void *property, void *pad, int size, PostFunction post_func)
715 {
716 HTask *task = sgroot->tmanager->create_task(id);
717 task->set_cpu(SPE_ANY);
718 task->add_inData(property, size);
719 task->add_inData(pad, sizeof(Pad));
720 task->add_outData(property, size);
721 task->set_post(post_func, (void*)property, 0);
722 wait_game_task->wait_for(task);
723 task->spawn();
724 }
725
726 void
727 main_task_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
728 {
729 int size = node->property_size;
730 void *e = node->propertyptr;
731 int move = node->move_id;
732 PostFunction post_func = node->post_func;
733
734 SceneGraphRoot *sgroottmp = (SceneGraphRoot*)sgroot_;
735 sgroottmp->set_game_task(move, (void*)e, size, post_func);
736 }
737
738 void
739 pad_task_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
740 {
741 int size = node->property_size;
742 void *e = node->propertyptr;
743 int move = node->move_id;
744 PostFunction post_func = node->post_func;
745
746 SceneGraphRoot *sgroottmp = (SceneGraphRoot*)sgroot_;
747 void *pad = (void*)sgroottmp->getController();
748
749 sgroottmp->set_game_task(move, (void*)e, pad, size, post_func);
750 }
751
752 void
753 SceneGraphRoot::set_move_task(SceneGraphPtr node, int move, void *property, int size,
754 PostFunction post_func)
755 {
756 node->move = main_task_move;
757 node->post_func = post_func;
758 node->move_id = move;
759 node->propertyptr = property;
760 node->property_size = size;
761 }
762
763 void
764 SceneGraphRoot::set_pad_task(SceneGraphPtr node, int move, void *property, int size,
765 PostFunction post_func)
766 {
767 node->move = pad_task_move;
768 node->post_func = post_func;
769 node->move_id = move;
770 node->propertyptr = property;
771 node->property_size = size;
772 }
773
774 /* end */