diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Engine/SceneGraphRoot.cc	Mon Oct 12 09:39:35 2009 +0900
@@ -0,0 +1,389 @@
+#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"
+
+int cnt = 0;
+
+SceneGraphRoot::SceneGraphRoot(float w, float h)
+{
+    sg_src = new SceneGraphPtr[SGLIST_LENGTH];
+    camera = new Camera(w, h);
+    iterator = new SceneGraphIterator;
+    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)
+{
+    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);
+}
+
+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);
+
+		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;
+}
+
+/**
+ * 何も表示しない、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[0]; is_end(t); t++){
+	  SceneGraphPtr s = application->scenegraph_factory(t); // SceneGraphNode を作る
+	  t->scenegraph = s; // property list には SceneGraphへのポインタが入っている
+	  application->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;
+}