diff Renderer/Test_/property_chain.cc @ 4:b5b462ac9b3b

Cerium Blender ball_bound
author Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
date Mon, 29 Nov 2010 16:42:42 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Renderer/Test_/property_chain.cc	Mon Nov 29 16:42:42 2010 +0900
@@ -0,0 +1,258 @@
+#include <math.h>
+#include <stdlib.h>
+#include "SceneGraphRoot.h"
+#include "MainLoop.h"
+#include "property_chain.h"
+#include "types.h"
+#include "Func.h"
+#include "sys.h"
+#include "SgChange.h"
+
+#define FALSE 0
+#define TRUE !FALSE
+static const int PROPERTY_LENGTH = 50;
+static double chain_width = 10;
+
+typedef struct {
+    float xyz[3];
+    float angle[3];
+    float stack_xyz[3];
+    float next_xyz[3];
+    float v_xyz[3];
+    float next_v_xyz[3];
+    int property_index;
+    int parent_index;
+    int have_parent;
+    int can_move;
+    memaddr parent;
+    memaddr children;
+    memaddr node;
+    int sgid;
+} *PropertyPtr, Property;
+
+
+Property *property, *update_property;
+
+// prototype
+static void collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree);
+static void move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h);
+static void createSceneGraphFromProperty(SchedTask *s, void *sgroot, void *arg1);
+static void set_property(Property *p, SceneGraphPtr sg, int index);
+static void apply_property(SceneGraphPtr sg, Property *p);
+static void regist_task(SceneGraphRoot *sgroot);
+static void set_relation(SceneGraphPtr parent, SceneGraphPtr child);
+
+static void
+init_chain(Property *p) {
+    for (int i = 0; i < 3; i++) {
+	p->xyz[i] = 0;
+	p->angle[i] = 0;
+	p->stack_xyz[i] = 0;
+	p->next_xyz[i] = 0;
+	p->v_xyz[i] = 0;
+	p->next_v_xyz[i] = 0;
+    }
+
+    p->property_index = 0;
+    p->parent_index = 0;
+    p->have_parent = 0;
+    p->can_move = TRUE;
+    p->parent = NULL;
+    p->children = NULL;
+    p->node = NULL;
+}
+
+static void
+move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
+{
+    SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_;
+    HTaskPtr property_task = sgroot->move_exec_task;
+
+    property_task->add_inData(property, sizeof(Property)*PROPERTY_LENGTH);
+    property_task->add_outData(update_property, sizeof(Property)*PROPERTY_LENGTH);
+    property_task->set_cpu(SPE_ANY);
+    property_task->set_post(createSceneGraphFromProperty, (void *)sgroot, 0);
+    property_task->spawn();
+}
+
+static void
+collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h,
+	  SceneGraphPtr tree)
+{
+}
+
+static void
+createSceneGraphFromProperty(SchedTask *s, void *sgroot_, void *arg1)
+{
+    SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_;
+    SceneGraphPtr camera = sgroot->camera;
+    SceneGraphPtr p_node;
+    SceneGraphPtr root;
+    
+    // ここが allExecute の tree をたどって clone して行くところに相当する
+    Property *p;
+    
+    for (int i = 0; i < PROPERTY_LENGTH; i++) {
+	p = &update_property[i];
+	SceneGraphPtr node = sgroot->createSceneGraph(p->sgid);
+	apply_property(node, p);    
+    }
+	
+    for (int j = 0; j < PROPERTY_LENGTH; j++) {
+	p = &update_property[j];
+	p_node = (SceneGraphPtr)p->node;
+	if (p->have_parent) {
+	    SceneGraphPtr parent = (SceneGraphPtr)update_property[p->parent_index].node;
+	    parent->addChild(p_node);
+	    get_matrix(p_node->matrix, p_node->angle, p_node->xyz, parent->matrix);
+	    get_matrix(p_node->real_matrix, p_node->angle, p_node->xyz, parent->real_matrix);
+	} else {
+	    get_matrix(p_node->matrix, p_node->angle, p_node->xyz, camera->matrix);
+	    get_matrix(p_node->real_matrix, p_node->angle, p_node->xyz, camera->real_matrix);
+	}
+    }
+
+    root = (SceneGraphPtr)update_property[0].node;
+    root->set_move_collision(move, collision);
+    sgroot->setSceneData(root);
+
+    Property *tmp = property;
+    property = update_property;
+    update_property = tmp;
+
+    sgroot->move_finish();
+}
+
+static void
+apply_property(SceneGraphPtr node, Property *p)
+{
+    for (int i = 0; i < 3; i++) {
+	node->xyz[i] = p->xyz[i];
+	node->angle[i] = p->angle[i];
+	node->stack_xyz[i] = p->stack_xyz[i];
+    }
+    p->node = (memaddr)node;
+    node->property = (memaddr)p;
+}
+
+/*
+  ここで必要な値をプロパティに格納
+ */
+static void
+set_property(Property *p, SceneGraphPtr node, int index)
+{
+    for (int i = 0; i < 3; i++) {
+	p->xyz[i] = node->xyz[i];
+	p->angle[i] = node->angle[i];
+	p->stack_xyz[i] = node->stack_xyz[i];
+    }
+    p->parent = (memaddr)node->parent;
+    p->children = (memaddr)node->children;
+    p->property_index = index;    
+    p->sgid = node->sgid;
+    p->node = (memaddr)node;
+    node->property = (memaddr)p;
+}
+
+static void
+regist_task(SceneGraphRoot *sgroot)
+{
+    TaskManager *manager = sgroot->tmanager;
+    HTaskPtr task = manager->create_task(ChainTask);
+    // sgroot->setExecTask(task); とやるべき?
+    sgroot->move_exec_task = task;
+}
+
+/*
+  Property に親子関係を書き込む
+  これも API に入れちゃっていいかな
+ */
+static void
+set_relation(SceneGraphPtr parent, SceneGraphPtr child)
+{
+    Property *p = (Property *)parent->property;
+    Property *c = (Property *)child->property;
+    p->children = (memaddr)child;
+    c->parent = (memaddr)parent;
+    c->parent_index = p->property_index;
+    c->have_parent = 1;
+}
+
+MainLoopPtr 
+property_chain::init(Viewer *viewer, int screen_w, int screen_h)
+{
+    // SgChange を使うための2行
+    SgChange *sgroot = new SgChange(viewer);
+    sgroot->run_init();
+    // 上で書いた regist_task() を登録
+    // sgroot->appTaskRegist(regist_task); がいいかな
+    sgroot->sgroot_A->appTaskRegist(regist_task);
+
+    property        = (Property *)sgroot->manager->allocate(sizeof(Property)*PROPERTY_LENGTH);
+    update_property = (Property *)sgroot->manager->allocate(sizeof(Property)*PROPERTY_LENGTH);
+
+    // property の初期化 application ごとに固有
+    for(int i = 0; i < PROPERTY_LENGTH; i++) {
+	init_chain(&property[i]);
+    }
+
+    SceneGraphPtr root_chain, chain;
+    sgroot->createFromXMLfile("xml_file/chain.xml");
+    root_chain = sgroot->createSceneGraph("CHAIN");
+    //root_chain->xyz[0] = screen_w / 2;
+    //root_chain->xyz[0] = screen_w / 4;
+    root_chain->xyz[0] = 300.0f;
+    root_chain->xyz[1] = 0.0f;
+    root_chain->set_move_collision(move, collision);
+    set_property(&property[0], root_chain, 0);
+    
+    for (int i = 1; i < PROPERTY_LENGTH; i++) {
+	chain = sgroot->createSceneGraph("CHAIN");
+	chain->xyz[0] = 0;
+	chain->xyz[1] = chain_width * i;
+	chain->angle[1] = -90 * (i % 2);
+	root_chain->addChild(chain);
+	set_property(&property[i], chain, i);
+	set_relation(root_chain, chain);
+    }
+
+    // root の set_property は SceneGraph を作成してから実行
+    // addChild したら set_relation しないとだめ、あんまりにもあんまり
+
+    /*
+      apply_property は post_func の createSceneGraphFromProperty 中で使う
+      apply_property は sgroot に持たせてもいいと思います○
+    */
+    
+    sgroot->setSceneData(root_chain);
+
+    return sgroot;
+}
+
+extern Application *
+application() {
+    return new property_chain();
+}
+
+const char *usr_help_str = "Usage: ./test_nogl [OPTION]\n";
+
+extern int init(TaskManager *manager, int argc, char *argv[]);
+extern void task_initialize();
+static void TMend(TaskManager *manager);
+
+int
+TMmain(TaskManager *manager, int argc, char *argv[])
+{
+    task_initialize();
+    manager->set_TMend(TMend);
+    return init(manager, argc, argv);
+
+}
+
+void
+TMend(TaskManager *manager)
+{
+    printf("test_nogl end\n");
+}
+
+/* end */