Mercurial > hg > Members > e085722 > Cerium
diff Renderer/Test_/aquarium.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_/aquarium.cc Mon Nov 29 16:42:42 2010 +0900 @@ -0,0 +1,310 @@ +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <unistd.h> +#include "SceneGraphRoot.h" +#include "lindaapi.h" +#include "aquarium.h" +#include "aquarium.pb.h" + +#define GET_SERIAL_ID 65535 + +int aquarium::last_player_id = 0; + +Viewer *aquarium::sgroot; +linda_t aquarium::linda_addr = { "localhost", 10000 }; +int aquarium::linda; +int aquarium::serial_id; +int aquarium::width; +int aquarium::start_x; +char *aquarium::xml_file_name; + +const char *usr_help_str = "Usage: ./aquarium -linda LINDA_SERVER_NAME\n"; +void TMend(TaskManager *manager); + +extern void task_initialize(); +extern int init(TaskManager *manager, int argc, char *argv[]); +extern Application * +application() { + return new aquarium(); +} + +/* +static void +null_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ +} +*/ + +static void +null_collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree) +{ +} + +void +aquarium::update_last_player_id() { + last_player_id++; + if (last_player_id == serial_id) + last_player_id++; +} + +void +aquarium::set_position(SceneGraphPtr node, unsigned char *reply) { + aqua::Position *pos = new aqua::Position(); + pos->ParseFromArray(reply + LINDA_HEADER_SIZE, psx_get_datalength(reply)); + node->xyz[0] = pos->x() - start_x; + node->xyz[1] = pos->y(); + node->angle[0] = pos->angle_x(); + node->angle[1] = pos->angle_y(); + delete pos; +} + +static void +update_position_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ + // LindaServerから座標データを取得してオブジェクトに反映させる。 + if (!node->resend_flag || node->seq_rd != node->seq) { + unsigned char *reply_rd = psx_reply(node->seq_rd); + if (reply_rd != NULL) { + aquarium::set_position(node, reply_rd); + psx_free(reply_rd); + return; + } + } + unsigned char *reply = psx_reply(node->seq); + if (reply != NULL) { +// aquarium::set_position(node, reply); + psx_free(reply); + node->seq = psx_wait_rd(aquarium::linda, node->id * 10 + 1); + node->resend_flag = true; + } else if (node->resend_flag) { + node->seq_rd = psx_rd(aquarium::linda, node->id * 10 + 1); + node->resend_flag = false; + } +} + +SceneGraphPtr +create_sg(Viewer *viewer, SceneGraphPtr par, unsigned char *data, int len, int serial_id) +{ + SceneGraphPtr child = viewer->sgroot->createSceneGraph(); + viewer->sgroot->createFromXMLmemory(viewer->sgroot->tmanager, child, (char *)data, len); + child->set_move_collision(update_position_move, null_collision); + child->id = serial_id; + child->seq = psx_wait_rd(aquarium::linda, serial_id * 10 + 1); + child->seq_rd = psx_rd(aquarium::linda, serial_id * 10 + 1); + child->resend_flag = false; + par->addChild(child); + return child; +} + +static void +check_new_player_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ + unsigned char *reply_rd = psx_reply(node->seq_rd); + if (reply_rd != NULL) { + unsigned char *xml_data = reply_rd + LINDA_HEADER_SIZE; + int xml_len = psx_get_datalength(reply_rd); + create_sg(aquarium::sgroot, node, xml_data, xml_len, aquarium::last_player_id); + psx_free(reply_rd); + aquarium::update_last_player_id(); + int tuple_id = aquarium::last_player_id * 10; + node->seq_rd = psx_rd(aquarium::linda, tuple_id); + } + // printf("rd id: %d\n", aquarium::last_player_id); +} + +void * +file_map(const char *filename, int *size) { + int fd; + void *addr; + struct stat sb; + + if ((fd = open(filename, O_RDONLY)) == -1) { + fprintf(stderr, "Can't open %s\n", filename); + perror(NULL); + } + if (fstat(fd, &sb) == -1) { + fprintf(stderr, "Can't fstat %s\n", filename); + perror(NULL); + } + *size = sb.st_size; + addr = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) { + perror("mmap error\n"); + exit(EXIT_FAILURE); + } + close(fd); + + return addr; +} + +void callback_free(unsigned char *tuple, void *arg) { + psx_free(tuple); +} + +void +aquarium::send_position(SceneGraphPtr node) { + int pos_id = serial_id * 10 + 1; + psx_callback_in(linda, pos_id, callback_free, NULL); + aqua::Position *pos = new aqua::Position(); + pos->set_x(node->xyz[0] + start_x); + pos->set_y(node->xyz[1]); + pos->set_angle_x(node->angle[0]); + pos->set_angle_y(node->angle[1]); + int size = pos->ByteSize(); + unsigned char *msg = (unsigned char *) sgroot->manager->allocate(sizeof(char) * size); + pos->SerializeToArray(msg, size); // 更新したデータを再度シリアライズ + delete pos; + psx_out(linda, pos_id, msg, size); +} + +void +my_move(SceneGraphPtr node, void *sgroot_, int w, int h) +{ + SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_; + Pad *pad = sgroot->getController(); + int flag = 0; + if (pad->right.isHold() || pad->left.isHold()) { + if (pad->right.isHold()) { + node->xyz[0] += 5.0f; + node->angle[1] = 0.0f; + flag = 1; + } else if (pad->left.isHold()) { + node->xyz[0] -= 5.0f; + node->angle[1] = 180.0f; + flag = 1; + } + } + + if (pad->down.isHold() || pad->up.isHold() ) { + if (pad->down.isHold()) { + node->xyz[1] += 5.0f; + flag = 1; + } else if (pad->up.isHold()) { + node->xyz[1] -= 5.0f; + flag = 1; + } + } + + /* ここで座標を送信 */ + if (flag || node->resend_flag) { + aquarium::send_position(node); + } +} + +void +aquarium::create_my_sg(Viewer *viewer, SceneGraphPtr par, int screen_w, int screen_h) +{ + int size; + void *addr = file_map(xml_file_name, &size); + SceneGraphPtr sgp = viewer->createSceneGraph(); + viewer->createFromXMLmemory(sgp, (char *)addr, size); + sgp->set_move_collision(my_move, null_collision); + + par->addChild(sgp); + sgp->c_xyz[0] = 0.0f; + sgp->c_xyz[1] = 0.0f; + sgp->c_xyz[2] = 0.0f; + + int xml_id = serial_id * 10; + psx_out(linda, xml_id, (unsigned char *)addr, size); + int pos_id = serial_id * 10 + 1; + + aqua::Position *pos = new aqua::Position(); + pos->set_x(0.0f + start_x); + pos->set_y(0.0f); + pos->set_angle_x(0.0f); + pos->set_angle_y(0.0f); + unsigned char *msg = (unsigned char *) viewer->manager->allocate(sizeof(unsigned char *) * size); + pos->SerializeToArray(msg, size); + psx_out(linda, pos_id, (unsigned char *)msg, pos->ByteSize()); + delete pos; + sgp->seq = 0; + sgp->resend_flag = 0; +} + +MainLoopPtr +aquarium::init(Viewer *sgroot, int screen_w, int screen_h) +{ + this->sgroot = sgroot; + width = screen_w; + linda_connect(); // 接続に合わせて serial_id も取得 + update_screen_scope(); + SceneGraphPtr parent = sgroot->createSceneGraph(); + parent->set_move_collision(check_new_player_move, null_collision); + + create_my_sg(sgroot, parent, screen_w, screen_h); + update_last_player_id(); + + int tuple_id = aquarium::last_player_id * 10; + parent->seq_rd = psx_rd(linda, tuple_id); + sgroot->setSceneData(parent); + return sgroot; +} + +void +aquarium::linda_connect() { + init_linda(); // セレクタの初期化 + linda = open_linda_java(linda_addr.hostname, linda_addr.port); + // serial_id の取得 + int seq = psx_in(linda, GET_SERIAL_ID); + unsigned char *data = NULL; + do { + psx_sync_n(); + data = psx_reply(seq); + } while (data == NULL); +// data[LINDA_HEADER_SIZE + psx_get_datalength(data)] = '\0'; + serial_id = atoi((char *)data + LINDA_HEADER_SIZE); + psx_free(data); + printf("Get serial_id: %d\n", serial_id); +} + +void +aquarium::update_screen_scope() { + int seq = psx_in(linda, 1); + unsigned char *data = NULL; + do { + psx_sync_n(); + data = psx_reply(seq); + } while (data == NULL); + aqua::Width *w = new aqua::Width(); + w->ParseFromArray(data + LINDA_HEADER_SIZE, *(int *)(data + LINDA_DATA_LENGTH_OFFSET)); + start_x = w->width(); // 現在の全長を取得 + w->set_width(start_x + width); // 自分の横幅を足す + int size = w->ByteSize(); + unsigned char *msg = (unsigned char *) sgroot->manager->allocate(sizeof(char) * size); + w->SerializeToArray(msg, size); // 更新したデータを再度シリアライズ + delete w; + psx_out(linda, 1, msg, size); + psx_sync_n(); + printf("start_x = %d, width = %d\n", start_x, width); +} + +int +TMmain(TaskManager *manager, int argc, char *argv[]) +{ + task_initialize(); + manager->set_TMend(TMend); + + for (int i = 0; i < argc; i++) { + if (strcmp(argv[i],"-linda") == 0 && i + 1 <= argc) { + aquarium::linda_addr.hostname = argv[i+1]; + } else if (strcmp(argv[i],"-port") == 0 && i + 1 <= argc) { + aquarium::linda_addr.port = atoi(argv[i+1]); + } else if (strcmp(argv[i],"-xml") == 0 && i + 1 <= argc) { + aquarium::xml_file_name = argv[i+1]; + } + } + return init(manager, argc, argv); +} + +void +TMend(TaskManager *manager) +{ + printf("aquarium end\n"); +} + +/* end */