Mercurial > hg > Game > Cerium
view TaskManager/Test/test_render/SceneGraphRoot.cc @ 533:bf9c44b21d67 draft
add Application/send_linda.cc
author | aaa |
---|---|
date | Thu, 22 Oct 2009 19:34:38 +0900 |
parents | 413667c70a1d |
children | 4c7125468f69 |
line wrap: on
line source
#include <SDL.h> #include <SDL_image.h> #include <libxml/parser.h> #include "SceneGraphRoot.h" #include "xml.h" #include "sys.h" #include "TextureHash.h" #include "texture.h" //#include "SGList.h" #include "Application.h" int cnt = 0; static const int SGLIST_LENGTH = 138; SceneGraphRoot::SceneGraphRoot(float w, float h) { // SGLIST_LENGTH 決め打ちかぁ、動的生成にする場合上限決めておいた方がいいのかな // sg_src = new SceneGraphPtr[SGLIST_LENGTH]; camera = new Camera(w, h); iterator = new SceneGraphIterator; sglist = new SceneGraphList; controller = create_controller(); sg_exec_tree = NULL; sg_draw_tree = NULL; sg_available_list = NULL; sg_remove_list = NULL; // TODO // 今はとりあえず camera を Root にしています // 今はそれすらもしてません //sg_exec_tree = camera; } SceneGraphRoot::~SceneGraphRoot(void) { SceneGraphPtr p = sg_available_list; while (p) { SceneGraphPtr tmp = p->next; delete p; p = tmp; cnt--; } p = sg_remove_list; while (p) { SceneGraphPtr tmp = p->next; delete p; p = tmp; cnt--; } delete [] sg_src; delete camera; delete iterator; delete controller; } /** * xml ファイルから生成された SceneGraph を sg_src に登録する。 * * @param sg SceneGraph created by xmlfile */ void SceneGraphRoot::registSceneGraph(SceneGraphPtr sg) { #if 0 for (int i = 0; i < SGLIST_LENGTH; i++) { if (strcmp(sg->name, sglist_table[i]) == 0) { sg->sgid = i; sg_src[i] = sg; return; } } fprintf(stderr, "error: (%s:%3d) Can't find Scene \"%s\"\n", __FUNCTION__, __LINE__, sg->name); #endif } void SceneGraphRoot::addNext(SceneGraphPtr sg) { SceneGraphPtr last = sg_available_list; if (!last) { sg_available_list = sg; } else { while (last->next) { last = last->next; } last->next = sg; sg->prev = last; } cnt++; } /* XMLファイルからポリゴンを作成 */ void SceneGraphRoot::createFromXMLfile(TaskManager *manager, const char *xmlfile) { xmlDocPtr doc; xmlNodePtr cur; SceneGraphPtr tmp; /* パース DOM生成 */ doc = xmlParseFile(xmlfile); cur = xmlDocGetRootElement(doc); /* ?? */ xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); /* XMLのノードを一つずつ解析 */ for (cur=cur->children; cur; cur=cur->next) { /* 扱うのはsurfaceオンリー */ if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) { continue; } /* ポリゴン(SceneGraph)生成 */ tmp = new SceneGraph(manager, cur); addSceneGraphList(manager, tmp); registSceneGraphList(tmp); } xmlFreeDoc(doc); } SceneGraphPtr SceneGraphRoot::createSceneGraph(int id) { SceneGraphPtr src; SceneGraphPtr p; if (id < 0 || id > SGLIST_LENGTH) { return NULL; } /* オリジナルの SceneGraph */ src = sg_src[id]; /* ユーザーにはオリジナルの clone を返す */ p = src->clone(); addNext(p); return p; } #if 1 void SceneGraphRoot::registSceneGraphList(SceneGraphPtr sg) { /* SceneGraphRoot にメンバ変数 SceneGraphList を持たせておくか SceneGraphList sglist sg->name で検索して、有れば sg_src に追加。 sgid は sglist のメンバ変数 sgid で管理する感じ */ SgStruct *s = sglist->get(sg->name); if (s != NULL) { sg->sgid = sglist->sgid; s->id = sglist->sgid; sg_src[sg->sgid] = sg; sglist->sgid++; return; } fprintf(stderr, "error: (%s:%3d) Can't find Scene \"%s\"\n", __FUNCTION__, __LINE__, sg->name); } const char * //SceneGraphRoot::createFromXMLmemory(TaskManager *manager, const char *xmlfile) //SceneGraphRoot::createFromXMLmemory(TaskManager *manager, st_mmap_t mmap_t) SceneGraphRoot::createFromXMLmemory(TaskManager *manager, char *data, int len) { xmlDocPtr doc; xmlNodePtr cur; SceneGraphPtr tmp; // size は取れるはず、テスト用に mmap したデータを使う /* パース DOM生成 */ doc = xmlParseMemory(data, len); cur = xmlDocGetRootElement(doc); /* ?? */ xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); /* XMLのノードを一つずつ解析 */ for (cur=cur->children; cur; cur=cur->next) { /* 扱うのはsurfaceオンリー */ if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) { continue; } /* ポリゴン(SceneGraph)生成 */ tmp = new SceneGraph(manager, cur); addSceneGraphList(manager, tmp); registSceneGraphList(tmp); } xmlFreeDoc(doc); // 1つの xml file に object は1つだと想定しているので、だめだこりゃ return tmp->name; } /* 生成された SceneGraph のを sglist に登録 */ void SceneGraphRoot::addSceneGraphList(TaskManager *manager, SceneGraphPtr tmp) { SgStruct *sg_t = (SgStruct *)manager->allocate(sizeof(SgStruct)); sg_t->name = tmp->name; sglist->addLast(sg_t); } SceneGraphPtr SceneGraphRoot::createSceneGraph(const char *name) { SceneGraphPtr src; SceneGraphPtr p; // SceneGraphList から name を検索して id 取得 SgStruct *e = sglist->get(name); int id = e->id; if (id < 0) { return NULL; } /* オリジナルの SceneGraph */ src = sg_src[id]; /* ユーザーにはオリジナルの clone を返す */ p = src->clone(); addNext(p); return p; } #endif /** * 何も表示しない、move,collision もしない SceneGraph を生成 * いずれ、Transform3D 的なものに回す予定 */ SceneGraphPtr SceneGraphRoot::createSceneGraph(void) { SceneGraphPtr p = new SceneGraph; addNext(p); p->flag_drawable = 0; return p; } void SceneGraphRoot::speExecute(int screen_w, int screen_h) { SceneGraphPtr list = sg_available_list; // SceneGraphPtr t = sg_exec_tree; // SceneGraphPtr cur_parent = camera; // 前フレームで描画した SceneGraph は削除 allRemove(sg_remove_list); // 前フレームに作られた SceneGraph は描画用に移行 // 現フレームでの操作は以下の tree,list には適用されない sg_draw_tree = sg_exec_tree; sg_remove_list = sg_available_list; // 現フレームで新しく SceneGraph がコピーされるので初期化 sg_exec_tree = NULL; sg_available_list = NULL; camera->move_execute(screen_w, screen_h); camera->update(screen_w, screen_h); camera->children = NULL; camera->lastChild = NULL; list->move_execute(screen_w, screen_h); list->collision_check(screen_w, screen_h, list); list->frame++; list = list->next; if(sg_exec_tree != NULL) { return; } /*removeのflagをもとにtreeを形成*/ /* spe から送り返されてきた property の配列を見て生成する for()*/ /* for (Property *t = (Property*)app->property[0]; is_end(t); t++){ SceneGraphPtr s = app->scenegraph_factory(t); // SceneGraphNode を作る t->scenegraph = s; // property list には SceneGraphへのポインタが入っている app->scenegraph_connector(property[0], s); // add する } */ // 現在、allExecute が終わった時点では // camera->children が User SceneGraph の root になる /** * NULL じゃなかったら、setSceneData が呼ばれてるから * そっちを次の Scene にする */ sg_exec_tree = camera->children; } void SceneGraphRoot::speExecute(int screen_w, int screen_h, Application *app) { // SceneGraphPtr t = sg_exec_tree; // SceneGraphPtr cur_parent = camera; // 前フレームで描画した SceneGraph は削除 allRemove(sg_remove_list); // 前フレームに作られた SceneGraph は描画用に移行 // 現フレームでの操作は以下の tree,list には適用されない sg_draw_tree = sg_exec_tree; sg_remove_list = sg_available_list; // 現フレームで新しく SceneGraph がコピーされるので初期化 sg_exec_tree = NULL; sg_available_list = NULL; camera->move_execute(screen_w, screen_h); camera->update(screen_w, screen_h); camera->children = NULL; camera->lastChild = NULL; if(sg_exec_tree != NULL) { return; } /*removeのflagをもとにtreeを形成*/ /* spe から送り返されてきた property の配列を見て生成する for()*/ /* Application内に移動 */ app->property_ope(sg_available_list); /* for (Property *t = (Property *)properties[0]; is_end(t); t++){ SceneGraphPtr s = app->scenegraph_factory(t); // SceneGraphNode を作る t->scenegraph = s; // property list には SceneGraphへのポインタが入っている app->scenegraph_connector(property[0], s); // add する } */ // 現在、allExecute が終わった時点では // camera->children が User SceneGraph の root になる /** * NULL じゃなかったら、setSceneData が呼ばれてるから * そっちを次の Scene にする */ sg_exec_tree = camera->children; } void SceneGraphRoot::allExecute(int screen_w, int screen_h) { SceneGraphPtr list = sg_available_list; SceneGraphPtr t = sg_exec_tree; SceneGraphPtr cur_parent = camera; // 前フレームで描画した SceneGraph は削除 allRemove(sg_remove_list); // 前フレームに作られた SceneGraph は描画用に移行 // 現フレームでの操作は以下の tree,list には適用されない sg_draw_tree = sg_exec_tree; sg_remove_list = sg_available_list; // 現フレームで新しく SceneGraph がコピーされるので初期化 sg_exec_tree = NULL; sg_available_list = NULL; camera->move_execute(screen_w, screen_h); camera->update(screen_w, screen_h); camera->children = NULL; camera->lastChild = NULL; /*まずは全部動作させる*/ while (list) { list->move_execute(screen_w, screen_h); list->collision_check(screen_w, screen_h, list); list->frame++; list = list->next; } if(sg_exec_tree != NULL) { return; } /*removeのflagをもとにtreeを形成*/ while (t) { SceneGraphPtr c = NULL; if (!t->isRemoved()) { c = t->clone(); addNext(c); cur_parent->addChild(c); c->frame = t->frame; /*親の回転、座標から、子の回転、座標を算出*/ get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix); } if (t->children != NULL && c != NULL) { cur_parent = c; t = t->children; } else if (t->brother != NULL) { t = t->brother; } else { while (t) { if (t->brother != NULL) { t = t->brother; break; } else { if (t->parent == NULL) { t = NULL; break; } else { cur_parent = cur_parent->parent; t = t->parent; } } } } } // 現在、allExecute が終わった時点では // camera->children が User SceneGraph の root になる /** * NULL じゃなかったら、setSceneData が呼ばれてるから * そっちを次の Scene にする */ sg_exec_tree = camera->children; } void SceneGraphRoot::allRemove(SceneGraphPtr list) { SceneGraphPtr p = list; while (p) { SceneGraphPtr p1 = p->next; delete p; p = p1; cnt--; } } void SceneGraphRoot::checkRemove(void) { SceneGraphPtr p = sg_available_list; SceneGraphPtr p1; while (p) { p1 = p->next; if (p->isRemoved()) { sg_exec_tree = p->realRemoveFromTree(sg_exec_tree); sg_available_list = p->realRemoveFromList(sg_available_list); } delete p; p = p1; } } SceneGraphPtr SceneGraphRoot::getExecuteSceneGraph(void) { return sg_exec_tree; } SceneGraphPtr SceneGraphRoot::getDrawSceneGraph(void) { return sg_draw_tree; } void SceneGraphRoot::updateControllerState(void) { controller->check(); } void SceneGraphRoot::setSceneData(SceneGraphPtr sg) { sg_exec_tree = sg; } Pad* SceneGraphRoot::getController(void) { return controller; } SceneGraphIteratorPtr SceneGraphRoot::getIterator(void) { iterator->set(sg_remove_list); return iterator; } SceneGraphIteratorPtr SceneGraphRoot::getIterator(SceneGraphPtr list) { iterator->set(list); return iterator; } CameraPtr SceneGraphRoot::getCamera(void) { return camera; }