Mercurial > hg > Game > Cerium
changeset 196:ecda783a926f draft
add SceneGraphRoot, tools/create_sglist.pl
author | gongo@gendarme.cr.ie.u-ryukyu.ac.jp |
---|---|
date | Sun, 25 Jan 2009 17:46:37 +0900 |
parents | 4e66b3327c50 |
children | a57e7ab0c888 |
files | TaskManager/Test/test_render/ChangeLog TaskManager/Test/test_render/SceneGraphRoot.cpp TaskManager/Test/test_render/SceneGraphRoot.h TaskManager/Test/test_render/tools/create_sglist.pl |
diffstat | 4 files changed, 359 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/TaskManager/Test/test_render/ChangeLog Sun Jan 25 17:44:17 2009 +0900 +++ b/TaskManager/Test/test_render/ChangeLog Sun Jan 25 17:46:37 2009 +0900 @@ -1,5 +1,10 @@ 2009-01-25 Wataru MIYAGUNI <gongo@cr.ie.u-ryukyu.ac.jp> + * add (tools/create_sglist): new + 必要な SceneGraph xml file から SceneGraph を抽出し、 + 名前と対応する ID を SGList.h に出力する。 + また、名前から ID を求める sglist_table を SGList.cpp に出力する。 + * SceneGraph.cpp (SceneGraph::remove): add User API。ここで削除するのではなく、まずはフラグを立てるだけ ここですぐに消すと、allExecute() の走査で何気に困る
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/SceneGraphRoot.cpp Sun Jan 25 17:46:37 2009 +0900 @@ -0,0 +1,191 @@ +#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" + +SceneGraphRoot::SceneGraphRoot(void) +{ + sg_src = new SceneGraphPtr[SGLIST_LENGTH]; + sg_exec_list = NULL; + sg_draw_list = NULL; + sg_available_list = NULL; +} + +SceneGraphRoot::~SceneGraphRoot(void) +{ + SceneGraphPtr p = sg_available_list; + + while (p) { + SceneGraphPtr tmp = p->next; + delete p; + p = tmp; + } + + delete [] sg_src; +} + +void +SceneGraphRoot::registSceneGraph(SceneGraphPtr sg) +{ + for (int i = 0; i < SGLIST_LENGTH; i++) { + if (strcmp(sg->name, sglist_table[i]) == 0) { + sg_src[i] = sg; + return; + } + } + + fprintf(stderr, "error: (%s:%3d) Can't find Scene \"%s\"\n", + __FUNCTION__, __LINE__, sg->name); +} + +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; + } +} + +/* XMLファイルからポリゴンを作成 */ +void +SceneGraphRoot::createFromXMLfile(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(cur); + + registSceneGraph(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; +} + +void +SceneGraphRoot::allExecute(int screen_w, int screen_h) +{ + SceneGraphPtr top = sg_exec_list; + SceneGraphPtr t = top; + + while (t) { + t->move_execute(screen_w, screen_h); + t->collision_check(screen_w, screen_h, top); + + t->frame++; + + if (t->parent != NULL) { + get_matrix(t->matrix, t->angle, t->xyz, t->parent->matrix); + } else { + get_matrix(t->matrix, t->angle, t->xyz, NULL); + } + + if (t->children != NULL) { + 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 { + t = t->parent; + } + } + } + } + } +} + +void +SceneGraphRoot::checkRemove(void) +{ + SceneGraphPtr p = sg_available_list; + SceneGraphPtr p1; + + while (p) { + p1 = p->next; + if (p->isRemoved()) { + p->realRemove(); + } + p = p1; + } +} + +SceneGraphPtr +SceneGraphRoot::getExecuteSceneGraph(void) +{ + return sg_exec_list; +} + +SceneGraphPtr +SceneGraphRoot::getDrawSceneGraph(void) +{ + return sg_draw_list; +} + +void +SceneGraphRoot::updateControllerState(void) +{ + controller->check(); +} + +void +SceneGraphRoot::setSceneData(SceneGraphPtr sg) +{ + sg_draw_list = sg_exec_list = sg; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/SceneGraphRoot.h Sun Jan 25 17:46:37 2009 +0900 @@ -0,0 +1,52 @@ +#ifndef INCLUDED_SCENE_GRAPH_ROOT +#define INCLUDED_SCENE_GRAPH_ROOT + +#ifndef INCLUDED_SCENE_GRAPH +# include "SceneGraph.h" +#endif + +class SceneGraphRoot { +public: + /* Constructor, Destructor */ + SceneGraphRoot(void); + ~SceneGraphRoot(void); + + /* Variables */ + // xml から読み込んだ、オリジナルの SceneGraph + SceneGraphPtr *sg_src; + + // move, collision 用の SceneGraph (tree) + SceneGraphPtr sg_exec_list; + + // 描画用の SceneGraph List (tree) + SceneGraphPtr sg_draw_list; + + // 現在存在する SceneGraph (double linked list) + SceneGraphPtr sg_available_list; + + // コントローラーオブジェクト (Keyboard, Joystick, ..) + Pad *controller; + + /** + * Functions + */ + /* User API */ + void createFromXMLfile(const char *); + SceneGraphPtr createSceneGraph(int id); + void setSceneData(SceneGraphPtr sg); + + /* Other System API */ + void allExecute(int screen_w, int screen_h); + void checkRemove(void); + SceneGraphPtr getExecuteSceneGraph(void); + SceneGraphPtr getDrawSceneGraph(void); + void updateControllerState(void); + + /* System API */ + void registSceneGraph(SceneGraphPtr sg); + void addNext(SceneGraphPtr sg); +}; + +typedef SceneGraphRoot *SceneGraphRootPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/Test/test_render/tools/create_sglist.pl Sun Jan 25 17:46:37 2009 +0900 @@ -0,0 +1,111 @@ +#!/opt/local/bin/perl + +# TODO +# 同じ名前の SceneGraph が来た時の処理 +# まあ Blender の時点でそうならないように書くべきなんだが + +#################################### +# +# Create SceneGraph List +# +# SceneGraph が記載された xml ファイルを読み込み、 +# 名前に対応するID列が記述された SGList.h を生成する。 +# また、名前から ID を取得するために sglist_table を生成しておく。 +# sglist_table は SGList.cpp に記述する +# +# xml に ID を入れれば table は要らないんだが、 +# xml の読み込む順番、その時々に応じて使うものと使わないもので +# ID にズレが出てくるので、Blender からの出力時点では決定できない。 +# このスクリプトで xml に上書きするって手もあるけど、微妙じゃない? +# +# xml ファイルは複数指定可能。 +# 実際に使うやつ全て指定する感じでおk +# +# (例) +# +# % cat ../xml_file/universe.xml +# +# <?xml version="1.0"?> +# <OBJECT-3D> +# <surface name="Earth" size="5952" prim="Triangle" parent="NULL"> +# (省略) +# </surface> +# +# <surface name="Moon" size="3312" prim="Triangle" parent="Earth"> +# (省略) +# </surface> +# <OBJECT-3D> +# +# % ./create_sglist.pl ../xml_file/universe.xml +# % cat SGList.h +# +# /* ../xml_file/universe.xml */ +# #define Earth 0 +# #define Moon 1 +# +# /* Number of Scene */ +# #define SGLIST_LENGTH 2 +# +# /* Scene Table */ +# const char *sglist_table[SGLIST_LENGTH] = { +# "Earth", "Moon" +# }; +# +#################################### + +use strict; +use XML::LibXML; + +my $outfile_h = "../SGList.h"; +my $outfile_c = "../SGList.cpp"; +my $id = 0; +my @table; + +################### +# cretae SGList.h # +################### +open(FH, ">$outfile_h") || die "Error: Can't open file : $outfile_h\n"; + +print FH "#ifndef INCLUDE_SGLIST\n"; +print FH "#define INCLUDE_SGLIST\n\n"; + +foreach (@ARGV) { + my $parser = XML::LibXML->new(); + my $doc = $parser->parse_file($_); + my @nodes = $doc->findnodes('//surface'); + + print FH "/* $_ */\n"; + + foreach my $surface (@nodes) { + my $name = $surface->findvalue('@name'); + + $table[$id] = $name; + + print FH "#define $name\t $id\n"; + $id++; + } + + print FH "\n"; +} + +print FH "/* Number of Scene */\n"; +print FH "#define SGLIST_LENGTH $id\n\n"; + +print FH "/* Scene Table */\n"; +print FH "extern const char *sglist_table[SGLIST_LENGTH];\n\n"; +print FH "#endif\n"; + +close(FH); + +##################### +# cretae SGList.cpp # +##################### +open(FH, ">$outfile_c") || die "Error: Can't open file : $outfile_c\n"; + +print FH "#include \"SGList.h\"\n\n"; +print FH "const char *sglist_table[SGLIST_LENGTH] = {\n"; +print FH " \""; +print FH join("\", \"", @table); +print FH "\"\n};\n"; + +close(FH);