Mercurial > hg > Game > Cerium
view Renderer/Engine/SceneGraph.cc @ 1319:31455d34e502 draft
collada file reader minor changes.
author | Taiki TAIRA <e095767@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 18 Dec 2011 09:39:14 +0900 |
parents | ab9b7d21b32b |
children | 3f95f61faef6 |
line wrap: on
line source
#include <iostream> #include <SDL.h> #include <SDL_opengl.h> #include <SDL_image.h> #include <libxml/parser.h> #include <string.h> #include "SceneGraph.h" #include "xml.h" #include "matrix_calc.h" #include "TextureHash.h" #include "texture.h" #include "TaskManager.h" #include "polygon_pack.h" #include <ft2build.h> #include <freetype/freetype.h> using namespace std; SceneGraphPtr scene_graph = NULL; SceneGraphPtr scene_graph_viewer = NULL; static TextureHash texture_hash; texture_list list[TABLE_SIZE]; extern int decode(char *cont, FILE *outfile); static void no_move(SceneGraphPtr self, void *sgroot_, int screen_w, int screen_h) {} static void no_collision(SceneGraphPtr self, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree) {} /** * 事前に計算したテクスチャの最大縮小率 scale まで、 * テクスチャを 1/2 縮小していく。 * このとき、テクスチャは TEXTURE_SPLIT_PIXELx2 のブロック (Tile) で分割し、 * これらを連続したメモリ領域に格納していく。 * 以下の (1), (2), (3) を Tapestry と呼ぶ * * 例 scale = 4 の場合 * * Tapestry(1) 1/1 * +---+---+---+---+ * | 0 | 1 | 2 | 3 | * +---+---+---+---+ * | 4 | 5 | 6 | 7 | (2) 1/2 * +---+---+---+---+ +---+---+ * | 8 | 9 | 10| 11| | 16| 17| (3) 1/4 * +---+---+---+---+ +---+---+ +---+ * | 12| 13| 14| 15| | 18| 19| | 20| * +---+---+---+---+ +---+---+ +---| * * (1) (2) (3) * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20| * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ * * @param[in] tex_w Width of orignal texture * @param[in] tex_h Height of orignal texture * @param[in] tex_src Original texture * @param[in] all_pixel_num Tapestry の合計 pixel 数 * @param[in] scale テクスチャの最大縮小率 (= 2^n) * @return (1) のアドレス */ uint32 white[256] __attribute__((aligned(16))); static uint32* makeTapestry(TaskManager *manager, uint32 tex_w, uint32 tex_h, uint32 *tex_src, int all_pixel_num, int scale_cnt) { if (tex_w==0 && tex_h==0) { // non texture case uint32 pattern = SDL_BYTEORDER == SDL_LIL_ENDIAN? 0x00ffffff : 0xffffff00; /* OpenGL RGBA masks */ if (white[0]!=pattern) { // dumb! #if 1 for(int i=0;i<256;i++) white[i] = pattern; #else memset_pattern4(white,&pattern,256); #endif } return white; } uint32 t = 0; uint32 diff = TEXTURE_SPLIT_PIXEL; uint32 p_diff = 1; uint32 *tex_dest = (uint32*)manager->allocate(sizeof(int)*all_pixel_num); // uint32 *tex_src_max = (uint32*)( tex_src + tex_h*tex_w); // uint32 alpha = SDL_BYTEORDER == SDL_LIL_ENDIAN? 0xff000000 : 0xff; /* OpenGL RGBA masks */ uint32 alpha = tex_src[0]; while (scale_cnt) { // we should use average, except clear one for (uint32 y = 0; y < align(tex_h,diff); y += diff) { for (uint32 x = 0; x < align(tex_w,diff); x += diff) { for (uint32 j = 0; j < diff; j += p_diff) { for (uint32 i = 0; i < diff; i += p_diff) { tex_dest[t++] = (x+i<tex_w && y+j<tex_h) ? tex_src[(x+i) + tex_w*(y+j)]: alpha; } } } } diff <<= 1; p_diff <<= 1; scale_cnt >>= 1; } return tex_dest; } /** * 何の情報も持ってない SceneGraph の生成 * 今のところ、とりあえず木構造の繋がりに使うぐらい */ SceneGraph::SceneGraph(TaskManager *manager) { init(); matrix = (float*)manager->allocate(sizeof(float)*16); texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); texture_info->texture_id = -1; for (int i = 0; i < 16; i++) { matrix[i] = 0; } for (int i = 0; i < 4; i++) { matrix[i*4+i] = 1; } finalize = &SceneGraph::finalize_copy; this->name = "NULLPO"; } /** * orig のコピーとして SceneGraph を生成する */ SceneGraph::SceneGraph( TaskManager *manager, SceneGraphPtr orig) { init(); memcpy(this, orig, sizeof(SceneGraph)); matrix = (float*)manager->allocate(sizeof(float)*16); texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); for (int i = 0; i < 16; i++) { matrix[i] = orig->matrix[i]; } memcpy(texture_info, orig->texture_info, sizeof(texture_list)); // コピーしない //flag_remove = 0; //flag_drawable = 1; next = NULL; prev = NULL; last = NULL; parent = NULL; brother = NULL; children = NULL; lastChild = NULL; finalize = &SceneGraph::finalize_copy; frame = 0; } /* construct polygon from xmlNode. */ SceneGraph::SceneGraph(TaskManager *manager, xmlNodePtr surface) { init(); matrix = (float*)manager->allocate(sizeof(float)*16*2); texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); texture_info->texture_id = -1; //size : 頂点の数かな size = atoi((char *)xmlGetProp(surface,(xmlChar *)"size")); name = (char *)xmlGetProp(surface,(xmlChar *)"name"); parent_name = (char *)xmlGetProp(surface,(xmlChar *)"parent"); for (int i = 0; i < 16; i++) { matrix[i] = 0; } for (int i = 0; i < 4; i++) { matrix[i*4+i] = 1; } if (size % 3 != 0) { printf("vertex size is error. size %% 3 = %lld\n", size % 3); } /* * MAX_SIZE_TRIANGLE:128 */ if (size > 0) { /* * size/3 : 三角形の数 * MAX_SIZE_TRIANGLE : 128 * polygon の数から、PolygonPackの数を決定する */ pp_num = (size/3 + MAX_SIZE_TRIANGLE - 1) / MAX_SIZE_TRIANGLE; pp = (PolygonPack*)manager->allocate(sizeof(PolygonPack)*pp_num); } else { pp_num = 0; pp = NULL; } get_data(manager, surface->children); finalize = &SceneGraph::finalize_original; } SceneGraph::SceneGraph(TaskManager *manager,const char *font,int pixels,Uint32 color,const char *string_name) { init(); this->matrix = (float*)manager->allocate(sizeof(float)*16); this->texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); texture_info->texture_id = -1; //size : 頂点の数かな size = 6; parent_name = NULL; name = string_name; for (int i = 0; i < 16; i++) { matrix[i] = 0; } for (int i = 0; i < 4; i++) { matrix[i*4+i] = 1; } if (size % 3 != 0) { printf("vertex size is error. size %% 3 = %lld\n", size % 3); } if (size > 0) { pp_num = (size/3 + MAX_SIZE_TRIANGLE - 1) / MAX_SIZE_TRIANGLE; pp = (PolygonPack*)manager->allocate(sizeof(PolygonPack)*pp_num); } else { pp_num = 0; pp = NULL; } create_font_data(manager, font, pixels, color, string_name); finalize = &SceneGraph::finalize_original; } void SceneGraph::create_font_data(TaskManager *manager,const char *font ,int pixels, Uint32 color, const char *string_name) { //font_coordinate(pixels/2,pixels); font_normal(); font_model(); //font_texture(); get_font_image(manager, font, pixels, color, string_name); } void SceneGraph::get_font_image(TaskManager *manager,const char *font ,int pixels ,Uint32 color, const char *string_name) { int tex_id; if (texture_hash.hash_regist(string_name, tex_id)) { SDL_Surface *texture_image = load_font_image(font,pixels,color,string_name); if(!texture_image){ printf("Can't load image %s\n",string_name); exit(0); } texture_info->texture_id = makeTapestries(manager, texture_image,tex_id); printf("%d\n",texture_info->texture_id); tex_id = texture_info->texture_id; } else { texture_info->texture_id = tex_id; } texture_info->t_w = list[tex_id].t_w; texture_info->t_h = list[tex_id].t_h; texture_info->pixels_orig = list[tex_id].pixels_orig; texture_info->pixels = list[tex_id].pixels; texture_info->scale_max = list[tex_id].scale_max; texture_info->texture_image = list[tex_id].texture_image; } SDL_Surface* SceneGraph::load_font_image(const char *font ,int pixel,Uint32 color , const char *string_name) { //printf("laod_font_iamge"); FT_Library library; FT_Error err; err = FT_Init_FreeType(&library); if(err){ exit(1); } FT_Face face; err = FT_New_Face(library,font,0,&face);//font:フォントファイルのパス if(err){ exit(1); } err = FT_Set_Pixel_Sizes(face,pixel,pixel); if(err){ exit(1); } u_int32_t changecode[256] = {0}; conv(string_name+5,strlen(string_name+5),changecode); unsigned int characode = changecode[0]; err = FT_Load_Char(face,characode,0); if(err){ exit(1); } err = FT_Render_Glyph(face->glyph,FT_RENDER_MODE_MONO); if(err){ exit(1); } FT_Bitmap *bm = &face->glyph->bitmap; //baseline計算 y_ppem(nominal height) - bitmap_top(topからのbaseline) float baseline = face->size->metrics.y_ppem - face->glyph->bitmap_top; float row = 1; float width = 1; font_coordinate(baseline,face->glyph->bitmap.rows,face->glyph->bitmap.width); this->seq = face->glyph->bitmap.width; font_texture(row,width); int index = 0; Uint32 *pixels = (Uint32*)malloc(bm->rows*bm->pitch*8*4); for (int row = 0; row < bm->rows; row ++) { for (int col = 0; col < bm->pitch; col ++) { int c = bm->buffer[bm->pitch * row + col]; for (int bit = 7; bit >= 0; bit --) { if (((c >> bit) & 1) == 0) { //printf(" "); pixels[index++] = 0x0000000; } else { //printf("##"); //pixels[index++] = 0x00ffffff; pixels[index++] = color; } } } } SDL_Surface *texture_image = SDL_CreateRGBSurfaceFrom(pixels, bm->pitch*8, bm->rows, 32, bm->pitch*8*4, redMask, greenMask, blueMask, alphaMask); if (!texture_image) { printf("error\n"); return 0; } SDL_Surface *tmpImage = SDL_CreateRGBSurface(SDL_HWSURFACE, texture_image->w, texture_image->h, 32, redMask, greenMask, blueMask, alphaMask); SDL_Surface *converted; converted = SDL_ConvertSurface(texture_image, tmpImage->format, SDL_HWSURFACE); if (converted != NULL) { SDL_FreeSurface(texture_image); texture_image = converted; } return texture_image; } void SceneGraph::conv(const char *str, int length, u_int32_t *out) { int oindex = 0; int i = 0; while (i < length) { out[oindex] = str[i++] & 0xff; int len = 0; u_int32_t mask; for (mask = 0x80; out[oindex] & mask; mask >>= 1) { out[oindex] -= mask; len++; } int j; for (j = 1; j < len; j++) out[oindex] = (out[oindex] << 6) | (str[i++] & 0x3f); oindex++; } } /*文字のSceneGraphを生成する*/ void SceneGraph::init() { next = NULL; prev = NULL; last = NULL; parent = NULL; brother = NULL; children = NULL; lastChild = NULL; stack_xyz[0] = 0.0f; stack_xyz[2] = 0.0f; stack_xyz[1] = 0.0f; stack_angle[0] = 0.0f; stack_angle[1] = 0.0f; stack_angle[2] = 0.0f; size = 0; pp_num = 0; //data = NULL; move = no_move; collision = no_collision; flag_remove = 0; flag_drawable = 1; sgid = -1; gid = -1; frame = 0; } SceneGraph::~SceneGraph() { (this->*finalize)(); } /** * xml ファイルから生成されたオリジナル SceneGraph なので * polygon data を削除 */ void SceneGraph::finalize_original() { //delete [] data; free(pp); free(matrix); free(texture_info); } /** * SceneGraph ID から生成された、コピー SceneGraph なので * polygon data は削除しない。オリジナルの方で削除する。 */ void SceneGraph::finalize_copy() { free(matrix); free(texture_info); } /** * add Children * 親の登録と、brother のリストへ加える * * @param child new child */ SceneGraphPtr SceneGraph::addChild(SceneGraphPtr child) { /* childrenのリストの最後に加える (brother として)*/ if (this->lastChild != NULL) { SceneGraphPtr last = this->lastChild; last->brother = child; //child->parent = this; //return child; } this->lastChild = child; if (this->children == NULL) { this->children = child; } child->parent = this; return child; } /** * add Brother * addChild() でも brother の操作をしないといけないので、そっちに回す * * @param bro new Brother */ SceneGraphPtr SceneGraph::addBrother(SceneGraphPtr bro) { if (this->parent) { parent->addChild(bro); } else { fprintf(stderr, "error : SceneGraph::%s : %s doesn't have parent\n", __FUNCTION__, this->name); } return bro; } /* thisの子や子孫にnameのものが存在すればそいつを返す なければNULL. */ SceneGraphPtr SceneGraph::searchSceneGraph(const char *name) { SceneGraphPtr tmp; SceneGraphPtr result; /* 本人か */ if( 0==strcmp(this->name, name) ) return this; /* 子供から再帰的に探す */ for(tmp = this->children; tmp; tmp = tmp->next) { if ((result=tmp->searchSceneGraph(name)) != NULL) return result; } /* 無かったら NULL. */ return NULL; } void SceneGraph::tree_check() { SceneGraphPtr t = this; while(t) { cout << "my_name : " << t->name << endl; if(t->children != NULL) { cout << "--move children : " << t->children->name << endl; t = t->children; } else if(t->brother != NULL) { cout << "--move brother : " << t->brother->name << endl; t = t->brother; } else { while(t) { if(t->brother != NULL) { cout << "--move brother : " << t->brother->name << endl; t = t->brother; break; } else { if(t->parent) { cout << "--move parent : " << t->parent->name << endl; } t = t->parent; } } } } } void SceneGraph::print_member() { cout << "size = " << size << endl; cout << "name = " << name << endl; cout << "parent_name = " << parent_name << endl; if (parent != NULL) { cout << "parent->name = " << parent->name << endl; } if (children != NULL) { cout << "children->name = " << children->name << endl; } } /* * surface nodeからポリゴンの情報を読み出す 再帰しない */ void SceneGraph::get_data(TaskManager *manager, xmlNodePtr cur) { //char *image_name; for(;cur;cur=cur->next) { if(!xmlStrcmp(cur->name,(xmlChar*)"coordinate")) { char *cont = (char *)xmlNodeGetContent(cur); pickup_coordinate(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"normal")) { char *cont = (char *)xmlNodeGetContent(cur); pickup_normal(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"model")) { char *cont = (char *)xmlNodeGetContent(cur); pickup_model(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"texture")) { char *cont = (char *)xmlNodeGetContent(cur); pickup_texture(cont); } else if(!xmlStrcmp(cur->name,(xmlChar*)"imageflag")) { int id; char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name"); texture_hash.hash_regist(filename, id); } else if(!xmlStrcmp(cur->name,(xmlChar*)"image")) { get_image(manager, cur); } } } static int is_bmp(const char *name) { int bmp = 0; while(*name) { if (bmp==0 && *name=='.') bmp = 1; else if (bmp==1 && (*name=='b' || *name=='B')) bmp = 2; else if (bmp==2 && (*name=='m' || *name=='M')) bmp = 3; else if (bmp==3 && (*name=='p' || *name=='P')) bmp = 4; else bmp = 0; name++; } return bmp==4; } #if (__LITTLE_ENDIAN__) #define LITTLEENDIAN 1 #else #define LITTLEENDIAN 0 #endif static void make_black_alpha(SDL_Surface *texture_image) { int tex_w = texture_image->w; int tex_h = texture_image->h; #if LITTLEENDIAN uint32 alpha = 0x000000ff; #else uint32 alpha = 0xff000000; #endif uint32 *pixels = (uint32*)texture_image->pixels; int i; for(i=0;i<tex_w*tex_h;i++) { uint32 pixel = pixels[i] & ~alpha; if (pixel==0) { pixels[i] = 0; } } } SDL_Surface* SceneGraph::load_decode_image(const char *file_name, const char *image_name, xmlNodePtr cur) { int fd = mkstemp((char *)image_name); FILE *outfile = fdopen(fd, "wb"); if (NULL == outfile) { cout << "error open file\n"; return 0; } char *cont = (char *)xmlNodeGetContent(cur); //decode(cont, image_name); decode(cont, outfile); fclose(outfile); int alpha_black = is_bmp(file_name); /** * image を 32bit(RGBA) に変換する */ SDL_Surface *texture_image = IMG_Load(image_name); if (!texture_image) return 0; SDL_Surface *tmpImage = SDL_CreateRGBSurface(SDL_HWSURFACE, texture_image->w, texture_image->h, 32, redMask, greenMask, blueMask, alphaMask); //= SDL_CreateRGBSurface(SDL_HWSURFACE, 0, // 0, 32, redMask, // greenMask, blueMask, alphaMask); SDL_Surface *converted; converted = SDL_ConvertSurface(texture_image, tmpImage->format, SDL_HWSURFACE); //SDL_SetAlpha(converted, 0, 0); if (converted != NULL) { SDL_FreeSurface(texture_image); texture_image = converted; } if (alpha_black) { make_black_alpha(texture_image); } // this->gl_tex = SDL_GL_LoadTexture(texture_image); return texture_image; } int SceneGraph::makeTapestries(TaskManager *manager, SDL_Surface *texture_image, int id) { uint32 *tapestry; int scale = 1; int tex_w = texture_image->w; int tex_h = texture_image->h; int all_pixel_num = 0; int nw = tex_w; int nh = tex_h; /** * テクスチャの w or h が 8 pixel で分割できる間、 * 1/2 の縮小画像を作る。 * ここでは、最大の scale (1/scale) を見つける * * (ex) * (128,128) => 64,64 : 32,32: 16,16 : 8,8 * scale = 16 * (128, 64) => 64,32 : 32,16: 16,8 * scale = 8 * 8 pixcel align してない場合は、透明に 8 pixcel に拡張する * (200, 57) => 200,64 : 100,32 : 56,16: 32,8 (16,1 : 8,1 まで落すべき? 32byte) * scale = 32 */ do { tex_w = align(tex_w,8); tex_h = align(tex_h,8); all_pixel_num += tex_w * tex_h; tex_w >>= 1; /* tex_w /= 2 */ tex_h >>= 1; scale <<= 1; /* scale *= 2 */ } while( tex_w >8 || tex_h > 8 ); scale >>= 1; // 必ず 1 以上になる tapestry = makeTapestry(manager, texture_image->w, texture_image->h, (uint32*)texture_image->pixels, all_pixel_num, scale); list[id].t_w = nw; list[id].t_h = nh; list[id].pixels_orig = (Uint32*)texture_image->pixels; list[id].pixels = tapestry; list[id].scale_max = scale; list[id].texture_image = texture_image; return id; } void SceneGraph::get_image(TaskManager *manager, xmlNodePtr cur) { char image_name[20] = "/tmp/image_XXXXXX"; char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name"); if (filename == NULL || filename[0] == 0) { return; } /** * image_name を既に Load していれば何もしない */ int tex_id; if (texture_hash.sg_hash_regist(filename, tex_id) == -1) { SDL_Surface *texture_image = load_decode_image(filename, image_name, cur); if (texture_image==0) { printf("Can't load image %s\n",filename); exit(0); } texture_info->texture_id = makeTapestries(manager, texture_image, tex_id); tex_id = texture_info->texture_id; if (unlink(image_name)) { cout << "unlink error\n"; } } else { /** * 以前に Load されている Texture を共用 */ texture_info->texture_id = tex_id; } // こんなことすると list[] のいみあるのかなーと // 微妙に思う、自分で書き換えた感想 by gongo texture_info->t_w = list[tex_id].t_w; texture_info->t_h = list[tex_id].t_h;; texture_info->pixels_orig = list[tex_id].pixels_orig; texture_info->pixels = list[tex_id].pixels; texture_info->scale_max = list[tex_id].scale_max; texture_info->texture_image = list[tex_id].texture_image; } void SceneGraph::delete_data() { SceneGraphPtr n = this->next, m; //n = this; //delete [] n->data; if (next) { while (n) { m = n->next; delete n; n = m; } } } /* move_func 実行 sgroot 渡す */ void SceneGraph::move_execute(int w, int h) { (*move)(this, this->sgroot, w, h); } void SceneGraph::collision_check(int w, int h, SceneGraphPtr tree) { (*collision)(this, this->sgroot, w, h, tree); } void SceneGraph::create_sg_execute() { (*create_sg)(this->sgroot, property, update_property); } void SceneGraph::set_move_collision(move_func new_move) { this->move = new_move; } void SceneGraph::set_move_collision(collision_func new_collision) { this->collision = new_collision; } void SceneGraph::set_move_collision(move_func new_move, collision_func new_collision) { this->move = new_move; this->collision = new_collision; } void SceneGraph::set_move_collision(move_func new_move, collision_func new_collision, void *sgroot_) { this->move = new_move; this->collision = new_collision; // add this->sgroot = sgroot_; } void SceneGraph::set_move_collision(move_func new_move, collision_func new_collision, create_sg_func new_create_sg) { this->move = new_move; this->collision = new_collision; this->create_sg = new_create_sg; } void SceneGraph::add_next(SceneGraphPtr next) { /* next のリストの最後に加える */ if (this->next != NULL) { SceneGraphPtr tmp = this->last; tmp->next = next; } else { this->next = next; } this->last = next; } /** * SceneGraph の clone * @return clone SceneGraph */ SceneGraphPtr SceneGraph::clone(TaskManager *manager) { SceneGraphPtr p = new SceneGraph(manager, this); return p; } /** * SceneGraph の clone * 予め allocate されてる領域への placement new を行う * * @param buf clone 領域 * @return clone SceneGraph */ SceneGraphPtr SceneGraph::clone(TaskManager *manager, void *buf) { SceneGraphPtr p = new(buf) SceneGraph(manager, this); return p; } void SceneGraph::remove() { this->flag_remove = 1; } /** * tree から node を削除する * * @param tree SceneGraphTree * @return node削除後の SceneGraphTree */ SceneGraphPtr SceneGraph::realRemoveFromTree(SceneGraphPtr tree) { SceneGraphPtr node = this; SceneGraphPtr parent = node->parent; SceneGraphPtr ret = tree; if (parent) { SceneGraphPtr brother = parent->children; SceneGraphPtr p, p1 = NULL; p = brother; if (p) { if (p == node) { parent->children = NULL; parent->lastChild = NULL; } else { p1 = p->brother; while (p1 && p1 != node) { p1 = p1->brother; p = p->brother; } if (p1) { p->brother = p1->brother; // node が最後尾なら、lastChild を変更 if (parent->lastChild == p1) { parent->lastChild = p; } } else { // Can't find remove node } } } } else { // 親が居ない = tree root なので // NULL を返す ret = NULL; } return ret; } /** * list から node を削除する * * @param list SceneGraphList * @return node削除後の SceneGraphList */ SceneGraphPtr SceneGraph::realRemoveFromList(SceneGraphPtr list) { SceneGraphPtr node = this; SceneGraphPtr prev = node->prev; SceneGraphPtr next = node->next; SceneGraphPtr ret = list; if (prev) { prev->next = next; } else { ret = next; } if (next) { next->prev = prev; } return ret; } int SceneGraph::isRemoved() { return flag_remove; } /** * 平行移動 * * @param x Ttranslate in the x direction * @param y Ttranslate in the y direction * @param z Ttranslate in the z direction */ void SceneGraph::translate(float x, float y, float z) { this->matrix[3] += x; this->matrix[4+3] += y; this->matrix[8+3] += z; } /** * x 軸方向への平行移動 * * @param x Ttranslate in the x direction */ void SceneGraph::translateX(float x) { this->matrix[3] += x; } /** * y 軸方向への平行移動 * * @param y Ttranslate in the y direction */ void SceneGraph::translateY(float y) { this->matrix[4+3] += y; } /** * z 軸方向への平行移動 * * @param z Ttranslate in the z direction */ void SceneGraph::translateZ(float z) { this->matrix[8+3] += z; } void SceneGraph::angleIt(float *angle) { float m[16]; float t[4] = {0,0,0,0}; for(int i=0;i<16;i++) m[i] = matrix[i]; get_matrix(matrix, angle, t, m); } void SceneGraph::scaleIt(float *scale) { for(int i=0;i<4;i++) { for(int j=0;i<3;j++) { matrix[i*4+j] = matrix[i*4+j]*scale[i]; } } } /* end */