0
|
1 #include <iostream>
|
|
2 #include <SDL.h>
|
|
3 #include <SDL_opengl.h>
|
|
4 #include <SDL_image.h>
|
|
5 #include <libxml/parser.h>
|
|
6 #include "SceneGraph.h"
|
|
7 #include "xml.h"
|
|
8 #include "sys.h"
|
|
9 #include "TextureHash.h"
|
|
10 #include "texture.h"
|
|
11 #include "TaskManager.h"
|
|
12
|
|
13 using namespace std;
|
|
14
|
|
15 SceneGraphPtr scene_graph = NULL;
|
|
16 SceneGraphPtr scene_graph_viewer = NULL;
|
|
17
|
|
18 static TextureHash texture_hash;
|
|
19 texture_list list[TABLE_SIZE];
|
|
20
|
|
21
|
|
22 extern int decode(char *cont, FILE *outfile);
|
|
23
|
|
24 static void
|
|
25 no_move(SceneGraphPtr self, void *sgroot_, int screen_w, int screen_h) {}
|
|
26
|
|
27 static void
|
|
28 no_collision(SceneGraphPtr self, void *sgroot_, int screen_w, int screen_h,
|
|
29 SceneGraphPtr tree) {}
|
|
30
|
|
31 /**
|
|
32 * 事前に計算したテクスチャの最大縮小率 scale まで、
|
|
33 * テクスチャを 1/2 縮小していく。
|
|
34 * このとき、テクスチャは TEXTURE_SPLIT_PIXELx2 のブロック (Tile) で分割し、
|
|
35 * これらを連続したメモリ領域に格納していく。
|
|
36 * 以下の (1), (2), (3) を Tapestry と呼ぶ
|
|
37 *
|
|
38 * 例 scale = 4 の場合
|
|
39 *
|
|
40 * Tapestry(1) 1/1
|
|
41 * +---+---+---+---+
|
|
42 * | 0 | 1 | 2 | 3 |
|
|
43 * +---+---+---+---+
|
|
44 * | 4 | 5 | 6 | 7 | (2) 1/2
|
|
45 * +---+---+---+---+ +---+---+
|
|
46 * | 8 | 9 | 10| 11| | 16| 17| (3) 1/4
|
|
47 * +---+---+---+---+ +---+---+ +---+
|
|
48 * | 12| 13| 14| 15| | 18| 19| | 20|
|
|
49 * +---+---+---+---+ +---+---+ +---|
|
|
50 *
|
|
51 * (1) (2) (3)
|
|
52 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
53 * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20|
|
|
54 * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
55 *
|
|
56 * @param[in] tex_w Width of orignal texture
|
|
57 * @param[in] tex_h Height of orignal texture
|
|
58 * @param[in] tex_src Original texture
|
|
59 * @param[in] all_pixel_num Tapestry の合計 pixel 数
|
|
60 * @param[in] scale テクスチャの最大縮小率 (= 2^n)
|
|
61 * @return (1) のアドレス
|
|
62 */
|
|
63 static uint32*
|
|
64 makeTapestry(TaskManager *manager, int tex_w, int tex_h, uint32 *tex_src,
|
|
65 int all_pixel_num, int scale_cnt)
|
|
66 {
|
|
67
|
|
68 int t = 0;
|
|
69 int diff = TEXTURE_SPLIT_PIXEL;
|
|
70 int p_diff = 1;
|
|
71
|
|
72 uint32 *tex_dest = (uint32*)manager->allocate(sizeof(int)*all_pixel_num);
|
|
73
|
|
74 while (scale_cnt) {
|
|
75 for (int y = 0; y < tex_h; y += diff) {
|
|
76 for (int x = 0; x < tex_w; x += diff) {
|
|
77 for (int j = 0; j < diff; j += p_diff) {
|
|
78 for (int i = 0; i < diff; i += p_diff) {
|
|
79 tex_dest[t++]
|
|
80 = tex_src[(x+i) + tex_w*(y+j)];
|
|
81 }
|
|
82 }
|
|
83 }
|
|
84 }
|
|
85
|
|
86 diff <<= 1;
|
|
87 p_diff <<= 1;
|
|
88 scale_cnt >>= 1;
|
|
89 }
|
|
90
|
|
91 return tex_dest;
|
|
92 }
|
|
93
|
|
94
|
|
95 /**
|
|
96 * 何の情報も持ってない SceneGraph の生成
|
|
97 * 今のところ、とりあえず木構造の繋がりに使うぐらい
|
|
98 */
|
|
99 SceneGraph::SceneGraph()
|
|
100 {
|
|
101 init();
|
|
102 finalize = &SceneGraph::finalize_copy;
|
|
103
|
|
104 this->name = "NULLPO";
|
|
105 }
|
|
106
|
|
107 /**
|
|
108 * orig のコピーとして SceneGraph を生成する
|
|
109 */
|
|
110 SceneGraph::SceneGraph(SceneGraphPtr orig)
|
|
111 {
|
|
112
|
|
113 init();
|
|
114 memcpy(this, orig, sizeof(SceneGraph));
|
|
115
|
|
116 // コピーしない
|
|
117 //flag_remove = 0;
|
|
118 //flag_drawable = 1;
|
|
119 next = NULL;
|
|
120 prev = NULL;
|
|
121 last = NULL;
|
|
122
|
|
123 parent = NULL;
|
|
124 brother = NULL;
|
|
125 children = NULL;
|
|
126 lastChild = NULL;
|
|
127
|
|
128 finalize = &SceneGraph::finalize_copy;
|
|
129
|
|
130
|
|
131 frame = 0;
|
|
132 }
|
|
133
|
|
134
|
|
135 /* construct polygon from xmlNode. */
|
|
136 SceneGraph::SceneGraph(TaskManager *manager, xmlNodePtr surface)
|
|
137 {
|
|
138 init();
|
|
139
|
|
140 size = atoi((char *)xmlGetProp(surface,(xmlChar *)"size"));
|
|
141 name = (char *)xmlGetProp(surface,(xmlChar *)"name");
|
|
142 parent_name = (char *)xmlGetProp(surface,(xmlChar *)"parent");
|
|
143 //texture_info = (texture_list_ptr)manager->allocate(sizeof(texture_list));
|
|
144 //data = new float[size*3*3];
|
|
145
|
|
146 for (int i = 0; i < 16; i++) {
|
|
147 matrix[i] = 0;
|
|
148 real_matrix[i] = 0;
|
|
149 }
|
|
150
|
|
151 #if SPE_CREATE_POLYGON_CHECK
|
|
152
|
|
153 for (int i = 0; i < 16; i++) {
|
|
154 printf("%f\n",matrix[i]);
|
|
155 printf("r %f\n",real_matrix[i]);
|
|
156 }
|
|
157
|
|
158 #endif
|
|
159
|
|
160 coord_xyz = (float*)manager->allocate(sizeof(float)*size*3);
|
|
161 coord_tex = (float*)manager->allocate(sizeof(float)*size*3);
|
|
162 normal = (float*)manager->allocate(sizeof(float)*size*3);
|
|
163
|
|
164 coord_pack_size = sizeof(float)*8*size*3; // coord_pack_vertex size is 32byte. vertex num 3.
|
|
165 coord_pack = (float*)manager->allocate(coord_pack_size);
|
|
166
|
|
167 get_data(manager, surface->children);
|
|
168
|
|
169 finalize = &SceneGraph::finalize_original;
|
|
170 }
|
|
171
|
|
172 void
|
|
173 SceneGraph::init()
|
|
174 {
|
|
175 next = NULL;
|
|
176 prev = NULL;
|
|
177 last = NULL;
|
|
178
|
|
179 parent = NULL;
|
|
180 brother = NULL;
|
|
181 children = NULL;
|
|
182 lastChild = NULL;
|
|
183
|
|
184 stack_xyz[0] = 0.0f;
|
|
185 stack_xyz[2] = 0.0f;
|
|
186 stack_xyz[1] = 0.0f;
|
|
187 stack_angle[0] = 0.0f;
|
|
188 stack_angle[1] = 0.0f;
|
|
189 stack_angle[2] = 0.0f;
|
|
190
|
|
191 size = 0;
|
|
192 //data = NULL;
|
|
193
|
|
194 #if SPE_CREATE_POLYGON
|
|
195
|
|
196 //tri_pack = NULL;
|
|
197 //sg_matrix = NULL;
|
|
198 //matrix = NULL;
|
|
199 //real_matrix = NULL;
|
|
200 //texture_info = NULL;
|
|
201
|
|
202 #else
|
|
203
|
|
204 coord_xyz = NULL;
|
|
205 normal = NULL;
|
|
206 coord_tex = NULL;
|
|
207
|
|
208 #endif
|
|
209
|
|
210 texture_id = -1;
|
|
211 move = no_move;
|
|
212 collision = no_collision;
|
|
213
|
|
214 flag_remove = 0;
|
|
215 flag_drawable = 1;
|
|
216 sgid = -1;
|
|
217 gid = -1;
|
|
218
|
|
219 frame = 0;
|
|
220 }
|
|
221
|
|
222 SceneGraph::~SceneGraph()
|
|
223 {
|
|
224 (this->*finalize)();
|
|
225 }
|
|
226
|
|
227 /**
|
|
228 * xml ファイルから生成されたオリジナル SceneGraph なので
|
|
229 * polygon data を削除
|
|
230 */
|
|
231 void
|
|
232 SceneGraph::finalize_original()
|
|
233 {
|
|
234 //delete [] data;
|
|
235
|
|
236 #if SPE_CREATE_POLYGON
|
|
237
|
|
238 free(coord_pack);
|
|
239 free(coord_xyz);
|
|
240 free(coord_tex);
|
|
241 free(normal);
|
|
242
|
|
243 #else
|
|
244
|
|
245 free(coord_xyz);
|
|
246 free(coord_tex);
|
|
247 free(normal);
|
|
248
|
|
249 #endif
|
|
250
|
|
251 }
|
|
252
|
|
253 /**
|
|
254 * SceneGraph ID から生成された、コピー SceneGraph なので
|
|
255 * polygon data は削除しない。オリジナルの方で削除する。
|
|
256 */
|
|
257 void
|
|
258 SceneGraph::finalize_copy()
|
|
259 {
|
|
260 }
|
|
261
|
|
262
|
|
263 /**
|
|
264 * add Children
|
|
265 * 親の登録と、brother のリストへ加える
|
|
266 *
|
|
267 * @param child new child
|
|
268 */
|
|
269 SceneGraphPtr
|
|
270 SceneGraph::addChild(SceneGraphPtr child)
|
|
271 {
|
|
272 /* childrenのリストの最後に加える (brother として)*/
|
|
273 if (this->lastChild != NULL) {
|
|
274 SceneGraphPtr last = this->lastChild;
|
|
275 last->brother = child;
|
|
276 //child->parent = this;
|
|
277 //return child;
|
|
278 }
|
|
279
|
|
280 this->lastChild = child;
|
|
281
|
|
282 if (this->children == NULL) {
|
|
283 this->children = child;
|
|
284 }
|
|
285
|
|
286 child->parent = this;
|
|
287
|
|
288 return child;
|
|
289 }
|
|
290
|
|
291
|
|
292 /**
|
|
293 * add Brother
|
|
294 * addChild() でも brother の操作をしないといけないので、そっちに回す
|
|
295 *
|
|
296 * @param bro new Brother
|
|
297 */
|
|
298 SceneGraphPtr
|
|
299 SceneGraph::addBrother(SceneGraphPtr bro)
|
|
300 {
|
|
301 if (this->parent) {
|
|
302 parent->addChild(bro);
|
|
303 } else {
|
|
304 fprintf(stderr, "error : SceneGraph::%s : %s doesn't have parent\n",
|
|
305 __FUNCTION__, this->name);
|
|
306 }
|
|
307
|
|
308 return bro;
|
|
309 }
|
|
310
|
|
311 /* thisの子や子孫にnameのものが存在すればそいつを返す なければNULL. */
|
|
312 SceneGraphPtr
|
|
313 SceneGraph::searchSceneGraph(const char *name)
|
|
314 {
|
|
315 SceneGraphPtr tmp;
|
|
316 SceneGraphPtr result;
|
|
317
|
|
318 /* 本人か */
|
|
319 if( 0==strcmp(this->name, name) ) return this;
|
|
320
|
|
321 /* 子供から再帰的に探す */
|
|
322 for(tmp = this->children; tmp; tmp = tmp->next) {
|
|
323 if ((result=tmp->searchSceneGraph(name)) != NULL)
|
|
324 return result;
|
|
325 }
|
|
326
|
|
327 /* 無かったら NULL. */
|
|
328 return NULL;
|
|
329 }
|
|
330
|
|
331 void
|
|
332 SceneGraph::tree_check()
|
|
333 {
|
|
334 SceneGraphPtr t = this;
|
|
335
|
|
336 while(t)
|
|
337 {
|
|
338 cout << "my_name : " << t->name << endl;
|
|
339 if(t->children != NULL)
|
|
340 {
|
|
341 cout << "--move children : " << t->children->name << endl;
|
|
342 t = t->children;
|
|
343 }
|
|
344 else if(t->brother != NULL)
|
|
345 {
|
|
346 cout << "--move brother : " << t->brother->name << endl;
|
|
347 t = t->brother;
|
|
348 }
|
|
349 else
|
|
350 {
|
|
351 while(t)
|
|
352 {
|
|
353 if(t->brother != NULL)
|
|
354 {
|
|
355 cout << "--move brother : " << t->brother->name << endl;
|
|
356 t = t->brother;
|
|
357 break;
|
|
358 }
|
|
359 else
|
|
360 {
|
|
361 if(t->parent)
|
|
362 {
|
|
363 cout << "--move parent : " << t->parent->name << endl;
|
|
364 }
|
|
365 t = t->parent;
|
|
366 }
|
|
367 }
|
|
368 }
|
|
369 }
|
|
370 }
|
|
371
|
|
372
|
|
373 void
|
|
374 SceneGraph::print_member()
|
|
375 {
|
|
376 cout << "size = " << size << endl;
|
|
377 cout << "name = " << name << endl;
|
|
378 cout << "parent_name = " << parent_name << endl;
|
|
379
|
|
380 if (parent != NULL) {
|
|
381 cout << "parent->name = " << parent->name << endl;
|
|
382 }
|
|
383
|
|
384 if (children != NULL) {
|
|
385 cout << "children->name = " << children->name << endl;
|
|
386 }
|
|
387 }
|
|
388
|
|
389
|
|
390 /*
|
|
391 * surface nodeからポリゴンの情報を読み出す 再帰しない
|
|
392 */
|
|
393 void
|
|
394 SceneGraph::get_data(TaskManager *manager, xmlNodePtr cur)
|
|
395 {
|
|
396 //char *image_name;
|
|
397
|
|
398 for(;cur;cur=cur->next)
|
|
399 {
|
|
400 if(!xmlStrcmp(cur->name,(xmlChar*)"coordinate"))
|
|
401 {
|
|
402 char *cont = (char *)xmlNodeGetContent(cur);
|
|
403 pickup_coordinate(cont);
|
|
404 }
|
|
405 else if(!xmlStrcmp(cur->name,(xmlChar*)"normal"))
|
|
406 {
|
|
407 char *cont = (char *)xmlNodeGetContent(cur);
|
|
408 pickup_normal(cont);
|
|
409 }
|
|
410 else if(!xmlStrcmp(cur->name,(xmlChar*)"model"))
|
|
411 {
|
|
412 char *cont = (char *)xmlNodeGetContent(cur);
|
|
413 pickup_model(cont);
|
|
414 }
|
|
415 else if(!xmlStrcmp(cur->name,(xmlChar*)"texture"))
|
|
416 {
|
|
417 char *cont = (char *)xmlNodeGetContent(cur);
|
|
418 pickup_texture(cont);
|
|
419 }
|
|
420 else if(!xmlStrcmp(cur->name,(xmlChar*)"imageflag"))
|
|
421 {
|
|
422 int id;
|
|
423 char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name");
|
|
424 texture_hash.hash_regist(filename, id);
|
|
425 }
|
|
426 else if(!xmlStrcmp(cur->name,(xmlChar*)"image"))
|
|
427 {
|
|
428 get_image(manager, cur);
|
|
429 }
|
|
430 }
|
|
431 }
|
|
432
|
|
433 SDL_Surface*
|
|
434 SceneGraph::load_decode_image(char *image_name, xmlNodePtr cur)
|
|
435 {
|
|
436 int fd = mkstemp(image_name);
|
|
437 FILE *outfile = fdopen(fd, "wb");
|
|
438
|
|
439 if (NULL == outfile) {
|
|
440 cout << "error open file\n";
|
|
441 return 0;
|
|
442 }
|
|
443
|
|
444 char *cont = (char *)xmlNodeGetContent(cur);
|
|
445 //decode(cont, image_name);
|
|
446 decode(cont, outfile);
|
|
447 fclose(outfile);
|
|
448
|
|
449
|
|
450 /**
|
|
451 * image を 32bit(RGBA) に変換する
|
|
452 */
|
|
453 SDL_Surface *texture_image = IMG_Load(image_name);
|
|
454 if (!texture_image) return 0;
|
|
455 SDL_Surface *tmpImage
|
|
456 = SDL_CreateRGBSurface(SDL_SWSURFACE, texture_image->w,
|
|
457 texture_image->h, 32, redMask,
|
|
458 greenMask, blueMask, alphaMask);
|
|
459
|
|
460 //= SDL_CreateRGBSurface(SDL_HWSURFACE, 0,
|
|
461 // 0, 32, redMask,
|
|
462 // greenMask, blueMask, alphaMask);
|
|
463
|
|
464 SDL_Surface *converted;
|
|
465 converted = SDL_ConvertSurface(texture_image, tmpImage->format,
|
|
466 SDL_HWSURFACE);
|
|
467
|
|
468 //SDL_SetAlpha(converted, 0, 0);
|
|
469
|
|
470 if (converted != NULL) {
|
|
471 SDL_FreeSurface(texture_image);
|
|
472 texture_image = converted;
|
|
473 }
|
|
474
|
|
475 // this->gl_tex = SDL_GL_LoadTexture(texture_image);
|
|
476 return texture_image;
|
|
477 }
|
|
478
|
|
479 int
|
|
480 SceneGraph::makeTapestries(TaskManager *manager, SDL_Surface *texture_image, int id) {
|
|
481 uint32 *tapestry;
|
|
482 int scale = 1;
|
|
483 int tex_w = texture_image->w;
|
|
484 int tex_h = texture_image->h;
|
|
485 int all_pixel_num = 0;
|
|
486
|
|
487 /**
|
|
488 * テクスチャの w or h が 8 pixel で分割できる間、
|
|
489 * 1/2 の縮小画像を作る。
|
|
490 * ここでは、最大の scale (1/scale) を見つける
|
|
491 *
|
|
492 * (ex)
|
|
493 * (128,128) => 64,64 : 32,32: 16,16 : 8,8
|
|
494 * scale = 16
|
|
495 * (128, 64) => 64,32 : 32,16: 16,8
|
|
496 * scale = 8
|
|
497 */
|
|
498 while (tex_w % TEXTURE_SPLIT_PIXEL == 0 &&
|
|
499 tex_h % TEXTURE_SPLIT_PIXEL == 0) {
|
|
500 all_pixel_num += tex_w*tex_h;
|
|
501 tex_w >>= 1; /* tex_w /= 2 */
|
|
502 tex_h >>= 1;
|
|
503 scale <<= 1; /* scale *= 2 */
|
|
504 }
|
|
505
|
|
506 scale >>= 1;
|
|
507
|
|
508 tapestry = makeTapestry(manager, texture_image->w, texture_image->h,
|
|
509 (uint32*)texture_image->pixels,
|
|
510 all_pixel_num, scale);
|
|
511
|
|
512 list[id].t_w = texture_image->w;
|
|
513 list[id].t_h = texture_image->h;
|
|
514 list[id].pixels_orig = (Uint32*)texture_image->pixels;
|
|
515 list[id].pixels = tapestry;
|
|
516 list[id].scale_max = scale;
|
|
517 list[id].texture_image = texture_image;
|
|
518
|
|
519 return id;
|
|
520 }
|
|
521
|
|
522 void
|
|
523 SceneGraph::get_image(TaskManager *manager, xmlNodePtr cur)
|
|
524 {
|
|
525 char image_name[20] = "/tmp/image_XXXXXX";
|
|
526 char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name");
|
|
527
|
|
528 if (filename == NULL || filename[0] == 0) {
|
|
529 return;
|
|
530 }
|
|
531
|
|
532 /**
|
|
533 * image_name を既に Load していれば何もしない
|
|
534 */
|
|
535 int tex_id;
|
|
536 if (!texture_hash.hash_regist(filename, tex_id)) {
|
|
537
|
|
538 SDL_Surface *texture_image = load_decode_image(image_name, cur);
|
|
539 if (texture_image==0) {
|
|
540 printf("Can't load image %s\n",filename);
|
|
541 exit(0);
|
|
542 }
|
|
543
|
|
544 texture_id = makeTapestries(manager, texture_image, tex_id);
|
|
545
|
|
546 if (unlink(image_name)) {
|
|
547 cout << "unlink error\n";
|
|
548 }
|
|
549 } else {
|
|
550 /**
|
|
551 * 以前に Load されている Texture を共用
|
|
552 */
|
|
553 texture_id = tex_id;
|
|
554 }
|
|
555
|
|
556 // こんなことすると list[] のいみあるのかなーと
|
|
557 // 微妙に思う、自分で書き換えた感想 by gongo
|
|
558 texture_info.t_w = list[texture_id].t_w;
|
|
559 texture_info.t_h = list[texture_id].t_h;;
|
|
560 texture_info.pixels_orig = list[texture_id].pixels_orig;
|
|
561 texture_info.pixels = list[texture_id].pixels;
|
|
562 texture_info.scale_max = list[texture_id].scale_max;
|
|
563 texture_info.texture_image = list[texture_id].texture_image;
|
|
564
|
|
565 }
|
|
566
|
|
567
|
|
568 void
|
|
569 SceneGraph::delete_data()
|
|
570 {
|
|
571 SceneGraphPtr n = this->next, m;
|
|
572
|
|
573 //n = this;
|
|
574 //delete [] n->data;
|
|
575
|
|
576 if (next) {
|
|
577 while (n) {
|
|
578 m = n->next;
|
|
579 delete n;
|
|
580 n = m;
|
|
581 }
|
|
582 }
|
|
583 }
|
|
584
|
|
585 /* move_func 実行 sgroot 渡す */
|
|
586 void
|
|
587 SceneGraph::move_execute(int w, int h)
|
|
588 {
|
|
589 (*move)(this, this->sgroot, w, h);
|
|
590 }
|
|
591
|
|
592 void
|
|
593 SceneGraph::collision_check(int w, int h, SceneGraphPtr tree)
|
|
594 {
|
|
595 (*collision)(this, this->sgroot, w, h, tree);
|
|
596 }
|
|
597
|
|
598 void
|
|
599 SceneGraph::create_sg_execute()
|
|
600 {
|
|
601 (*create_sg)(this->sgroot, property, update_property);
|
|
602 }
|
|
603
|
|
604
|
|
605 void
|
|
606 SceneGraph::set_move_collision(move_func new_move,
|
|
607 collision_func new_collision)
|
|
608 {
|
|
609 this->move = new_move;
|
|
610 this->collision = new_collision;
|
|
611 }
|
|
612
|
|
613
|
|
614 void
|
|
615 SceneGraph::set_move_collision(move_func new_move,
|
|
616 collision_func new_collision, void *sgroot_)
|
|
617 {
|
|
618 this->move = new_move;
|
|
619 this->collision = new_collision;
|
|
620 // add
|
|
621 this->sgroot = sgroot_;
|
|
622 }
|
|
623
|
|
624 void
|
|
625 SceneGraph::set_move_collision(move_func new_move,
|
|
626 collision_func new_collision, create_sg_func new_create_sg)
|
|
627 {
|
|
628 this->move = new_move;
|
|
629 this->collision = new_collision;
|
|
630 this->create_sg = new_create_sg;
|
|
631 }
|
|
632
|
|
633 void
|
|
634 SceneGraph::add_next(SceneGraphPtr next)
|
|
635 {
|
|
636 /* next のリストの最後に加える */
|
|
637 if (this->next != NULL) {
|
|
638 SceneGraphPtr tmp = this->last;
|
|
639 tmp->next = next;
|
|
640 } else {
|
|
641 this->next = next;
|
|
642 }
|
|
643
|
|
644 this->last = next;
|
|
645 }
|
|
646
|
|
647 /**
|
|
648 * SceneGraph の clone
|
|
649 * @return clone SceneGraph
|
|
650 */
|
|
651 SceneGraphPtr
|
|
652 SceneGraph::clone() {
|
|
653 SceneGraphPtr p = new SceneGraph(this);
|
|
654 return p;
|
|
655 }
|
|
656
|
|
657 /**
|
|
658 * SceneGraph の clone
|
|
659 * 予め allocate されてる領域への placement new を行う
|
|
660 *
|
|
661 * @param buf clone 領域
|
|
662 * @return clone SceneGraph
|
|
663 */
|
|
664 SceneGraphPtr
|
|
665 SceneGraph::clone(void *buf) {
|
|
666 SceneGraphPtr p = new(buf) SceneGraph(this);
|
|
667 return p;
|
|
668 }
|
|
669
|
|
670 void
|
|
671 SceneGraph::remove()
|
|
672 {
|
|
673 this->flag_remove = 1;
|
|
674 }
|
|
675
|
|
676 /**
|
|
677 * tree から node を削除する
|
|
678 *
|
|
679 * @param tree SceneGraphTree
|
|
680 * @return node削除後の SceneGraphTree
|
|
681 */
|
|
682 SceneGraphPtr
|
|
683 SceneGraph::realRemoveFromTree(SceneGraphPtr tree)
|
|
684 {
|
|
685 SceneGraphPtr node = this;
|
|
686 SceneGraphPtr parent = node->parent;
|
|
687 SceneGraphPtr ret = tree;
|
|
688
|
|
689 if (parent) {
|
|
690 SceneGraphPtr brother = parent->children;
|
|
691 SceneGraphPtr p, p1 = NULL;
|
|
692
|
|
693 p = brother;
|
|
694 if (p) {
|
|
695 if (p == node) {
|
|
696 parent->children = NULL;
|
|
697 parent->lastChild = NULL;
|
|
698 } else {
|
|
699 p1 = p->brother;
|
|
700
|
|
701 while (p1 && p1 != node) {
|
|
702 p1 = p1->brother;
|
|
703 p = p->brother;
|
|
704 }
|
|
705
|
|
706 if (p1) {
|
|
707 p->brother = p1->brother;
|
|
708
|
|
709 // node が最後尾なら、lastChild を変更
|
|
710 if (parent->lastChild == p1) {
|
|
711 parent->lastChild = p;
|
|
712 }
|
|
713 } else {
|
|
714 // Can't find remove node
|
|
715 }
|
|
716 }
|
|
717 }
|
|
718 } else {
|
|
719 // 親が居ない = tree root なので
|
|
720 // NULL を返す
|
|
721 ret = NULL;
|
|
722 }
|
|
723
|
|
724 return ret;
|
|
725 }
|
|
726
|
|
727 /**
|
|
728 * list から node を削除する
|
|
729 *
|
|
730 * @param list SceneGraphList
|
|
731 * @return node削除後の SceneGraphList
|
|
732 */
|
|
733 SceneGraphPtr
|
|
734 SceneGraph::realRemoveFromList(SceneGraphPtr list)
|
|
735 {
|
|
736 SceneGraphPtr node = this;
|
|
737 SceneGraphPtr prev = node->prev;
|
|
738 SceneGraphPtr next = node->next;
|
|
739 SceneGraphPtr ret = list;
|
|
740
|
|
741 if (prev) {
|
|
742 prev->next = next;
|
|
743 } else {
|
|
744 ret = next;
|
|
745 }
|
|
746
|
|
747 if (next) {
|
|
748 next->prev = prev;
|
|
749 }
|
|
750
|
|
751 return ret;
|
|
752 }
|
|
753
|
|
754 int
|
|
755 SceneGraph::isRemoved()
|
|
756 {
|
|
757 return flag_remove;
|
|
758 }
|
|
759
|
|
760 /**
|
|
761 * 平行移動
|
|
762 *
|
|
763 * @param x Ttranslate in the x direction
|
|
764 * @param y Ttranslate in the y direction
|
|
765 * @param z Ttranslate in the z direction
|
|
766 */
|
|
767 void
|
|
768 SceneGraph::translate(float x, float y, float z)
|
|
769 {
|
|
770 this->xyz[0] = x;
|
|
771 this->xyz[1] = y;
|
|
772 this->xyz[2] = z;
|
|
773 }
|
|
774
|
|
775 /**
|
|
776 * x 軸方向への平行移動
|
|
777 *
|
|
778 * @param x Ttranslate in the x direction
|
|
779 */
|
|
780 void
|
|
781 SceneGraph::translateX(float x)
|
|
782 {
|
|
783 this->xyz[0] = x;
|
|
784 }
|
|
785
|
|
786 /**
|
|
787 * y 軸方向への平行移動
|
|
788 *
|
|
789 * @param y Ttranslate in the y direction
|
|
790 */
|
|
791 void
|
|
792 SceneGraph::translateY(float y)
|
|
793 {
|
|
794 this->xyz[1] = y;
|
|
795 }
|
|
796
|
|
797 /**
|
|
798 * z 軸方向への平行移動
|
|
799 *
|
|
800 * @param z Ttranslate in the z direction
|
|
801 */
|
|
802 void
|
|
803 SceneGraph::translateZ(float z)
|
|
804 {
|
|
805 this->xyz[2] = z;
|
|
806 }
|
|
807
|
|
808 /* end */
|