changeset 196:932a05a7a1db

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 8143bbade40d
children 3c77b74d04ac
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);