comparison 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
comparison
equal deleted inserted replaced
3:3f6fe22ac669 4:b5b462ac9b3b
1 #include <stdio.h>
2 #include <string.h>
3 #include <fcntl.h>
4 #include <sys/types.h>
5 #include <sys/mman.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
8 #include "SceneGraphRoot.h"
9 #include "lindaapi.h"
10 #include "aquarium.h"
11 #include "aquarium.pb.h"
12
13 #define GET_SERIAL_ID 65535
14
15 int aquarium::last_player_id = 0;
16
17 Viewer *aquarium::sgroot;
18 linda_t aquarium::linda_addr = { "localhost", 10000 };
19 int aquarium::linda;
20 int aquarium::serial_id;
21 int aquarium::width;
22 int aquarium::start_x;
23 char *aquarium::xml_file_name;
24
25 const char *usr_help_str = "Usage: ./aquarium -linda LINDA_SERVER_NAME\n";
26 void TMend(TaskManager *manager);
27
28 extern void task_initialize();
29 extern int init(TaskManager *manager, int argc, char *argv[]);
30 extern Application *
31 application() {
32 return new aquarium();
33 }
34
35 /*
36 static void
37 null_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
38 {
39 }
40 */
41
42 static void
43 null_collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree)
44 {
45 }
46
47 void
48 aquarium::update_last_player_id() {
49 last_player_id++;
50 if (last_player_id == serial_id)
51 last_player_id++;
52 }
53
54 void
55 aquarium::set_position(SceneGraphPtr node, unsigned char *reply) {
56 aqua::Position *pos = new aqua::Position();
57 pos->ParseFromArray(reply + LINDA_HEADER_SIZE, psx_get_datalength(reply));
58 node->xyz[0] = pos->x() - start_x;
59 node->xyz[1] = pos->y();
60 node->angle[0] = pos->angle_x();
61 node->angle[1] = pos->angle_y();
62 delete pos;
63 }
64
65 static void
66 update_position_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
67 {
68 // LindaServerから座標データを取得してオブジェクトに反映させる。
69 if (!node->resend_flag || node->seq_rd != node->seq) {
70 unsigned char *reply_rd = psx_reply(node->seq_rd);
71 if (reply_rd != NULL) {
72 aquarium::set_position(node, reply_rd);
73 psx_free(reply_rd);
74 return;
75 }
76 }
77 unsigned char *reply = psx_reply(node->seq);
78 if (reply != NULL) {
79 // aquarium::set_position(node, reply);
80 psx_free(reply);
81 node->seq = psx_wait_rd(aquarium::linda, node->id * 10 + 1);
82 node->resend_flag = true;
83 } else if (node->resend_flag) {
84 node->seq_rd = psx_rd(aquarium::linda, node->id * 10 + 1);
85 node->resend_flag = false;
86 }
87 }
88
89 SceneGraphPtr
90 create_sg(Viewer *viewer, SceneGraphPtr par, unsigned char *data, int len, int serial_id)
91 {
92 SceneGraphPtr child = viewer->sgroot->createSceneGraph();
93 viewer->sgroot->createFromXMLmemory(viewer->sgroot->tmanager, child, (char *)data, len);
94 child->set_move_collision(update_position_move, null_collision);
95 child->id = serial_id;
96 child->seq = psx_wait_rd(aquarium::linda, serial_id * 10 + 1);
97 child->seq_rd = psx_rd(aquarium::linda, serial_id * 10 + 1);
98 child->resend_flag = false;
99 par->addChild(child);
100 return child;
101 }
102
103 static void
104 check_new_player_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h)
105 {
106 unsigned char *reply_rd = psx_reply(node->seq_rd);
107 if (reply_rd != NULL) {
108 unsigned char *xml_data = reply_rd + LINDA_HEADER_SIZE;
109 int xml_len = psx_get_datalength(reply_rd);
110 create_sg(aquarium::sgroot, node, xml_data, xml_len, aquarium::last_player_id);
111 psx_free(reply_rd);
112 aquarium::update_last_player_id();
113 int tuple_id = aquarium::last_player_id * 10;
114 node->seq_rd = psx_rd(aquarium::linda, tuple_id);
115 }
116 // printf("rd id: %d\n", aquarium::last_player_id);
117 }
118
119 void *
120 file_map(const char *filename, int *size) {
121 int fd;
122 void *addr;
123 struct stat sb;
124
125 if ((fd = open(filename, O_RDONLY)) == -1) {
126 fprintf(stderr, "Can't open %s\n", filename);
127 perror(NULL);
128 }
129 if (fstat(fd, &sb) == -1) {
130 fprintf(stderr, "Can't fstat %s\n", filename);
131 perror(NULL);
132 }
133 *size = sb.st_size;
134 addr = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0);
135 if (addr == MAP_FAILED) {
136 perror("mmap error\n");
137 exit(EXIT_FAILURE);
138 }
139 close(fd);
140
141 return addr;
142 }
143
144 void callback_free(unsigned char *tuple, void *arg) {
145 psx_free(tuple);
146 }
147
148 void
149 aquarium::send_position(SceneGraphPtr node) {
150 int pos_id = serial_id * 10 + 1;
151 psx_callback_in(linda, pos_id, callback_free, NULL);
152 aqua::Position *pos = new aqua::Position();
153 pos->set_x(node->xyz[0] + start_x);
154 pos->set_y(node->xyz[1]);
155 pos->set_angle_x(node->angle[0]);
156 pos->set_angle_y(node->angle[1]);
157 int size = pos->ByteSize();
158 unsigned char *msg = (unsigned char *) sgroot->manager->allocate(sizeof(char) * size);
159 pos->SerializeToArray(msg, size); // 更新したデータを再度シリアライズ
160 delete pos;
161 psx_out(linda, pos_id, msg, size);
162 }
163
164 void
165 my_move(SceneGraphPtr node, void *sgroot_, int w, int h)
166 {
167 SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_;
168 Pad *pad = sgroot->getController();
169 int flag = 0;
170 if (pad->right.isHold() || pad->left.isHold()) {
171 if (pad->right.isHold()) {
172 node->xyz[0] += 5.0f;
173 node->angle[1] = 0.0f;
174 flag = 1;
175 } else if (pad->left.isHold()) {
176 node->xyz[0] -= 5.0f;
177 node->angle[1] = 180.0f;
178 flag = 1;
179 }
180 }
181
182 if (pad->down.isHold() || pad->up.isHold() ) {
183 if (pad->down.isHold()) {
184 node->xyz[1] += 5.0f;
185 flag = 1;
186 } else if (pad->up.isHold()) {
187 node->xyz[1] -= 5.0f;
188 flag = 1;
189 }
190 }
191
192 /* ここで座標を送信 */
193 if (flag || node->resend_flag) {
194 aquarium::send_position(node);
195 }
196 }
197
198 void
199 aquarium::create_my_sg(Viewer *viewer, SceneGraphPtr par, int screen_w, int screen_h)
200 {
201 int size;
202 void *addr = file_map(xml_file_name, &size);
203 SceneGraphPtr sgp = viewer->createSceneGraph();
204 viewer->createFromXMLmemory(sgp, (char *)addr, size);
205 sgp->set_move_collision(my_move, null_collision);
206
207 par->addChild(sgp);
208 sgp->c_xyz[0] = 0.0f;
209 sgp->c_xyz[1] = 0.0f;
210 sgp->c_xyz[2] = 0.0f;
211
212 int xml_id = serial_id * 10;
213 psx_out(linda, xml_id, (unsigned char *)addr, size);
214 int pos_id = serial_id * 10 + 1;
215
216 aqua::Position *pos = new aqua::Position();
217 pos->set_x(0.0f + start_x);
218 pos->set_y(0.0f);
219 pos->set_angle_x(0.0f);
220 pos->set_angle_y(0.0f);
221 unsigned char *msg = (unsigned char *) viewer->manager->allocate(sizeof(unsigned char *) * size);
222 pos->SerializeToArray(msg, size);
223 psx_out(linda, pos_id, (unsigned char *)msg, pos->ByteSize());
224 delete pos;
225 sgp->seq = 0;
226 sgp->resend_flag = 0;
227 }
228
229 MainLoopPtr
230 aquarium::init(Viewer *sgroot, int screen_w, int screen_h)
231 {
232 this->sgroot = sgroot;
233 width = screen_w;
234 linda_connect(); // 接続に合わせて serial_id も取得
235 update_screen_scope();
236 SceneGraphPtr parent = sgroot->createSceneGraph();
237 parent->set_move_collision(check_new_player_move, null_collision);
238
239 create_my_sg(sgroot, parent, screen_w, screen_h);
240 update_last_player_id();
241
242 int tuple_id = aquarium::last_player_id * 10;
243 parent->seq_rd = psx_rd(linda, tuple_id);
244 sgroot->setSceneData(parent);
245 return sgroot;
246 }
247
248 void
249 aquarium::linda_connect() {
250 init_linda(); // セレクタの初期化
251 linda = open_linda_java(linda_addr.hostname, linda_addr.port);
252 // serial_id の取得
253 int seq = psx_in(linda, GET_SERIAL_ID);
254 unsigned char *data = NULL;
255 do {
256 psx_sync_n();
257 data = psx_reply(seq);
258 } while (data == NULL);
259 // data[LINDA_HEADER_SIZE + psx_get_datalength(data)] = '\0';
260 serial_id = atoi((char *)data + LINDA_HEADER_SIZE);
261 psx_free(data);
262 printf("Get serial_id: %d\n", serial_id);
263 }
264
265 void
266 aquarium::update_screen_scope() {
267 int seq = psx_in(linda, 1);
268 unsigned char *data = NULL;
269 do {
270 psx_sync_n();
271 data = psx_reply(seq);
272 } while (data == NULL);
273 aqua::Width *w = new aqua::Width();
274 w->ParseFromArray(data + LINDA_HEADER_SIZE, *(int *)(data + LINDA_DATA_LENGTH_OFFSET));
275 start_x = w->width(); // 現在の全長を取得
276 w->set_width(start_x + width); // 自分の横幅を足す
277 int size = w->ByteSize();
278 unsigned char *msg = (unsigned char *) sgroot->manager->allocate(sizeof(char) * size);
279 w->SerializeToArray(msg, size); // 更新したデータを再度シリアライズ
280 delete w;
281 psx_out(linda, 1, msg, size);
282 psx_sync_n();
283 printf("start_x = %d, width = %d\n", start_x, width);
284 }
285
286 int
287 TMmain(TaskManager *manager, int argc, char *argv[])
288 {
289 task_initialize();
290 manager->set_TMend(TMend);
291
292 for (int i = 0; i < argc; i++) {
293 if (strcmp(argv[i],"-linda") == 0 && i + 1 <= argc) {
294 aquarium::linda_addr.hostname = argv[i+1];
295 } else if (strcmp(argv[i],"-port") == 0 && i + 1 <= argc) {
296 aquarium::linda_addr.port = atoi(argv[i+1]);
297 } else if (strcmp(argv[i],"-xml") == 0 && i + 1 <= argc) {
298 aquarium::xml_file_name = argv[i+1];
299 }
300 }
301 return init(manager, argc, argv);
302 }
303
304 void
305 TMend(TaskManager *manager)
306 {
307 printf("aquarium end\n");
308 }
309
310 /* end */