Mercurial > hg > Game > Cerium
changeset 1381:3e303369c44b draft
merge
author | Kakeru TAMASIRO <e095736@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 26 Jan 2012 22:30:32 +0900 |
parents | dd3b8f54e3e3 (current diff) 13065ad17328 (diff) |
children | de990f3e0a21 |
files | |
diffstat | 26 files changed, 950 insertions(+), 586 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Engine/Collada.cc Thu Jan 26 22:30:32 2012 +0900 @@ -0,0 +1,506 @@ +#include "polygon.h" +#include "SceneGraph.h" +#include "SceneGraph.cc" +#include "TextureHash.h" +#include "xml.h" +#include "SceneGraphRoot.h" +#include <iostream> +#include <SDL_image.h> + +using namespace std; +static TextureHash sgid_hash; + +extern int is_bmp(const char* name); +extern void make_black_alpha(SDL_Surface *texture_image); + +typedef struct source { + char *id; + union { + float *array; + char *alias; + }u; + int count; + struct source *next; +} SOURCE; +typedef SOURCE *SOURCE_P; + +typedef struct list { + SOURCE_P first; + SOURCE_P end; +} LIST; +typedef LIST *LIST_P; + +struct collada_state { + collada_state(){ + polylist = 0; + + vertex_offset = -1; + vertex_count = 0; + + normal_offset = -1; + normal_count = 0; + + texcoord_offset = -1; + texcoord_count = 0; + + polylist_count = 0; + vcsum = 0; + + limit = 0; + vmember = 0; + + images_flag=0; + } + int polylist; + int library_images; + xmlChar *vertices_id; + + char *vertex_src; + int vertex_offset; + int vertex_count; + + char *normal_src; + int normal_offset; + int normal_count; + + char *texcoord_src; + int texcoord_offset; + int texcoord_count; + + float *vcount; + float *pcount; + + SOURCE_P normal_float; + SOURCE_P vertex_float; + SOURCE_P texcoord_float; + + char *vertices_src; + int polylist_count; + + char *name; + char *tex_picname; + + int images_flag; + + int vcsum; + int limit; + int vmember; +}; + +/*static const char* +get_property(const char *name, xmlNodePtr cur){ + xmlAttr *p=cur->properties; + if (p==0) return ""; + for ( ;p; p=p->next) { + if ( xmlStrcmp(p->name, (xmlChar*)name) !=0 ) { + xmlNode* n=p->children; + if ( n==NULL ) return ""; + const char * v=(const char*)n->content; + if ( v==NULL ) return ""; + return v; + } + } + return ""; +}*/ + +SDL_Surface* +load_image(const char *file_name, const char *image_name) +{ + int alpha_black = is_bmp(file_name); +/** + * image を 32bit(RGBA) に変換する + */ + SDL_Surface *texture_image = IMG_Load(file_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; +} + +/* add source list */ +static void +addSource(LIST_P list, SOURCE_P src) { + if (list->first == NULL && list->end == NULL) { + list->first = list->end = src; + return; + } + list->end->next = src; + list->end = src; +} + +/* compare a with b. Using to compare id */ +/* +static int +strcmp_a(const char *a, const char *b) +{ + while (*a && *a++ == *b++); + if (*a) return 0; + return a[-1] > b[-1] ? 1:-1; +} +static float +get_point(char *id, int position, LIST_P list) +{ + SOURCE_P cur = list->first; + for (;cur ; cur=cur->next) { + if (!strcmp_a(id, cur->id)) { + if (cur->count == 0) //alias + return get_point(cur->u.alias, position, list); + float *a = cur->u.array; + if (position <= cur->count) { + return a[position]; + } + } + } +} +*/ + +static SOURCE_P +most_match(const char *id , LIST_P list) +{ + SOURCE_P src = NULL; + SOURCE_P cur = NULL; + int tmplength = 0; + int strlength; + + for (cur=list->first ;cur!=list->end ;cur=cur->next) { + for (strlength=0;id[strlength]==cur->id[strlength];strlength++); + if (tmplength < strlength) { + tmplength = strlength; + src = cur; + } + } + if (src == NULL){ + fprintf(stderr,"not match"); + } + return src; +} + +void get_texture_image(char *filename, SceneGraphPtr sg, xmlNodePtr cur, TaskManager *manager) +{ + char image_name[20] = "/tmp/image_XXXXXX"; + if (filename == NULL || filename[0] == 0) { + return; + } + /** + * image_name を既に Load していれば何もしない + */ + int tex_id; + /* ball test */ + if (sgid_hash.sg_hash_regist(/*filename*/"Ball", tex_id) == -1) { + SDL_Surface *texture_image = load_image(filename, image_name); + if (texture_image==0) { + printf("Can't load image %s\n",filename); + exit(0); + } + sg->texture_info->texture_id = sg->makeTapestries(manager, texture_image, tex_id); + tex_id = sg->texture_info->texture_id; + if (unlink(image_name)) { + printf("unlink error\n"); + } + } else { + /** + * 以前に Load されている Texture を共用 + */ + sg->texture_info->texture_id = tex_id; + } + // 微妙に思う、自分で書き換えた感想 by gongo + sg->texture_info->t_w = list[tex_id].t_w; + sg->texture_info->t_h = list[tex_id].t_h;; + sg->texture_info->pixels_orig = list[tex_id].pixels_orig; + sg->texture_info->pixels = list[tex_id].pixels; + sg->texture_info->scale_max = list[tex_id].scale_max; + sg->texture_info->texture_image = list[tex_id].texture_image; +} + +void decode_float_array(xmlNodePtr cur,LIST_P list){ + SOURCE_P src = (SOURCE_P)malloc(sizeof(SOURCE)); + char *id = (char*)xmlGetProp(cur, (xmlChar*)"id"); + src->id = (char*)xmlGetProp(cur, (xmlChar*)"id"); + + int count = atoi((char*)xmlGetProp(cur, (xmlChar*)"count")); + src->count = atoi((char*)xmlGetProp(cur, (xmlChar*)"count")); + src->u.array = new float[src->count]; + char *cont =(char*)xmlNodeGetContent(cur); + //const char *id = get_property("id", cur); + //int count = atoi(get_property("count", cur)); + + /* store float inpoint list */ + for (int i = 0; cont != NULL; i++) { + cont = pickup_float(cont, src->u.array+i); + } + + src->next = NULL; + addSource(list, src); + printf("id:%s count:%d cont:%s\n", id, count, cont); +} + + +void +get_points(xmlNodePtr cur, collada_state *s, TaskManager *manager){ + char *pcont = (char*)xmlNodeGetContent(cur); + for (int i = 0;i < s->polylist_count;i++){ + s->vcsum += s->vcount[i]; + s->vmember = i; + } + s->limit = s->vcsum * 2; + if (s->texcoord_offset == 2){ + s->limit = s->vcsum * 3; + } + s->pcount = new float[s->limit]; + for (int i=0;i<s->limit;i++){ + s->pcount[i] = 0; + } + for (int i=0; pcont != NULL; i++) { + pcont = pickup_float(pcont, s->pcount+i); + } +} +SceneGraph* +decode_points(collada_state *s, TaskManager *manager, SceneGraphPtr sg){ + int *vertexp; + vertexp = new int[s->vcsum]; + for (int i=0;i<s->vcsum;i++){ + vertexp[i]=0; + } + /* + * vertex_tableだけはpolygonを作る際にvcountが4の場合重複する点が + * 出てくるのでサイズを2倍用意しておく + */ + float *vertex_table; + float *normal_table; + float *texcoord_table; + vertex_table = new float[(s->vcsum)*2]; + normal_table = new float[s->vcsum]; + texcoord_table = new float[s->vcsum]; + for (int i=0;i < s->vcsum;i++){ + vertex_table[i] = 0; + normal_table[i] = 0; + texcoord_table[i] = 0; + } + + /** + * s->vcsum と s->vertex_float->countの値が違うので大きい方をとりあえず使っておく + */ + + /* p separate vertex position and nomal position. */ + if (s->texcoord_offset == 2){ + for (int i=0,j=0; i < s->limit; i+=3,j++) { + vertexp[j] = (int)s->pcount[i]; + normal_table[j] = s->normal_float->u.array[(int)s->pcount[i+1]]; + texcoord_table[j] = s->texcoord_float->u.array[(int)s->pcount[i+2]]; + } + } else{ + for (int i=0,j=0; i < s->limit; i+=2,j++) { + vertexp[j] = (int)s->pcount[i]; + normal_table[j] = s->normal_float->u.array[(int)s->pcount[i+1]]; + } + } + + /* make triangle */ + int k=0,l=0,size=0; + for (int i=0;i<s->vmember;i++) { + if (s->vcount[i] == 4) { + vertex_table[k++] = s->vertex_float->u.array[vertexp[l]]; + vertex_table[k++] = s->vertex_float->u.array[vertexp[l+1]]; + vertex_table[k++] = s->vertex_float->u.array[vertexp[l+2]]; + vertex_table[k++] = s->vertex_float->u.array[vertexp[l+1]]; + vertex_table[k++] = s->vertex_float->u.array[vertexp[l+2]]; + vertex_table[k++] = s->vertex_float->u.array[vertexp[l+3]]; + l+=4; + size +=2; + } else if (s->vcount[i]==3) { + vertex_table[k++] = s->vertex_float->u.array[vertexp[l++]]; + vertex_table[k++] = s->vertex_float->u.array[vertexp[l++]]; + vertex_table[k++] = s->vertex_float->u.array[vertexp[l++]]; + size++; + } + } + + /** + * (SceneGraph.cc) + * pickup_normal,pickup_coordinate,pickup_textureの処理 + * vcsumは頂点の数,countは面の数 + */ + //int count = s->vcsum / 3; + int count = size / 3; + //polygonの作成 + sg->pp_num = (count + MAX_SIZE_TRIANGLE - 1) / MAX_SIZE_TRIANGLE; + sg->pp = new PolygonPack[sg->pp_num]; + sg->name = s->name; + sg->parent_name = "NULL"; + sg->size = size; + for (int i = 0;i < sg->pp_num; i++ ){ + PolygonPackPtr pp = sg->pp; + TrianglePackPtr tri = pp[i].tri; + // TrianglePack の size のチェック + int tri_size = (count < MAX_SIZE_TRIANGLE) ? count : MAX_SIZE_TRIANGLE ; + pp[i].info.size = tri_size; + /* default texture peste */ + if (s->images_flag==0) { + get_texture_image("/Users/YuSUGIMOTO/Cerium/Renderer/Test/xml_file/blend/images/ball.jpg", sg, (xmlNodePtr)NULL, manager); + } + int k = 0; + int m = 0; + int n = 0; + for (int j = 0; j < tri_size; j++) { + tri[j].normal1.x = normal_table[k++]; + tri[j].normal1.y = normal_table[k++]; + tri[j].normal1.z = normal_table[k++]; + + tri[j].normal2.x = normal_table[k++]; + tri[j].normal2.y = normal_table[k++]; + tri[j].normal2.z = normal_table[k++]; + + tri[j].normal3.x = normal_table[k++]; + tri[j].normal3.y = normal_table[k++]; + tri[j].normal3.z = normal_table[k++]; + + tri[j].ver1.tex_x = texcoord_table[m++]; + tri[j].ver1.tex_y = texcoord_table[m++]; + + tri[j].ver2.tex_x = texcoord_table[m++]; + tri[j].ver2.tex_y = texcoord_table[m++]; + + tri[j].ver3.tex_x = texcoord_table[m++]; + tri[j].ver3.tex_y = texcoord_table[m++]; + + tri[j].ver1.x = vertex_table[n++]; + tri[j].ver1.y = vertex_table[n++]; + tri[j].ver1.z = vertex_table[n++]; + + tri[j].ver2.x = vertex_table[n++]; + tri[j].ver2.y = vertex_table[n++]; + tri[j].ver2.z = vertex_table[n++]; + + tri[j].ver3.x = vertex_table[n++]; + tri[j].ver3.y = vertex_table[n++]; + tri[j].ver3.z = vertex_table[n++]; + + } + + } + sg->c_xyz[0] = sg->c_xyz[1] = sg->c_xyz[2] = 0; + + //int tex_id = 0; + //sgid_hash.sg_hash_regist(s->name, tex_id); + + delete []vertexp; + delete []vertex_table; + delete []normal_table; + delete []texcoord_table; + + /* got out of polylist */ + s->polylist = 0; + return sg; +} + +static void +xml_walk(xmlNodePtr cur, struct collada_state *s, LIST_P list,SceneGraphPtr sg, SceneGraphRoot *root) +{ + int in_polylist=0; + //printf("name = %s, child:%s\n", (char *)cur->name, (char *)cur->children); + //printf("s->polylist = %d\n",s->polylist); + if (!xmlStrcmp(cur->name, (xmlChar*)"polylist")) { + s->polylist_count = atoi((char*)xmlGetProp(cur, (xmlChar*)"count")); + s->polylist=1; + in_polylist=1; + } else if (!xmlStrcmp(cur->name, (xmlChar*)"vertices")) { + s->vertices_id = xmlGetProp(cur, (xmlChar*)"id"); + } else if (!xmlStrcmp(cur->name, (xmlChar*)"library_images")) { + s->library_images=1; + //library_images is wrote at texture image name. only use one image file + } else if (s->library_images && !xmlStrcmp(cur->name, (xmlChar*)"init_from")) { + s->tex_picname = (char*)xmlGetProp(cur, (xmlChar*)"init_from"); + get_texture_image(s->tex_picname, sg, cur , root->tmanager); + printf("------------------%s",s->tex_picname); + s->library_images=0; + s->images_flag=1; + } else if (!s->polylist && !xmlStrcmp(cur->name, (xmlChar*)"input")) { + char *semantic = (char*)xmlGetProp(cur, (xmlChar*)"semantic"); + if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"POSITION")) { + s->vertices_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); + } + } else if (s->polylist && !xmlStrcmp(cur->name, (xmlChar*)"input")) { + char *semantic = (char*)xmlGetProp(cur, (xmlChar*)"semantic"); + if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"VERTEX")) { + s->vertex_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); + s->vertex_float = most_match(s->vertices_src+1, list); + } else if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"NORMAL")) { + s->normal_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); + s->normal_offset = atoi((char*)xmlGetProp(cur, (xmlChar*)"offset")); + s->normal_float = most_match(s->normal_src+1, list); + } else if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"TEXCOORD")) { + s->texcoord_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); + s->texcoord_offset = atoi((char*)xmlGetProp(cur, (xmlChar*)"offset")); + s->texcoord_float = most_match(s->texcoord_src+1, list); + } + } else if (!xmlStrcmp(cur->name, (xmlChar*)"vcount")) { + char *vcont = (char*)xmlNodeGetContent(cur); + s->vcount = new float[s->polylist_count]; + for (int i=0; vcont!=NULL; i++) { + /* store vcount list */ + vcont = pickup_float(vcont, s->vcount+i); + } + } else if (!xmlStrcmp(cur->name, (xmlChar*)"p")) { + get_points(cur,s,root->tmanager); + in_polylist = 0; + } else if (!xmlStrcmp(cur->name, (xmlChar*)"float_array")) { + decode_float_array(cur,list); + } else if (!xmlStrcmp(cur->name, (xmlChar*)"node" )) { + s->name = (char*)xmlGetProp(cur, (xmlChar*)"id"); + } + for (cur=cur->children; cur; cur=cur->next){ + xml_walk(cur,s,list,sg,root); + } +} +void +init_list(LIST_P list) { + list->first = NULL; + list->end = NULL; +} + + +void +SceneGraphRoot::createFromCOLLADAfile(TaskManager *manager, const char *xmlColladafile) +{ + /*make parse dom*/ + xmlDocPtr doc; + xmlNodePtr cur; + //,cur_images,cur_effects,cur_geometries,cur_visual_scenes; + //SceneGraphPtr tmp; + + doc = xmlParseFile(xmlColladafile); + cur = xmlDocGetRootElement(doc); + + if (xmlStrcmp(cur->name, (xmlChar*)"COLLADA")){ + return ; + } + + /* node analyze */ + struct collada_state s; + SceneGraphPtr sg = new SceneGraph(manager); + for (cur=cur->children; cur; cur=cur->next){ + LIST list; + init_list(&list); + xml_walk(cur,&s,&list,sg,this); + } + registSceneGraph(decode_points(&s,manager,sg)); + xmlFreeDoc(doc); +}
--- a/Renderer/Engine/SceneGraph.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/SceneGraph.cc Thu Jan 26 22:30:32 2012 +0900 @@ -124,21 +124,9 @@ { init(); - - matrix = (float*)manager->allocate(sizeof(float)*16); - texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); - + allocate_init(manager); 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"; @@ -155,8 +143,7 @@ memcpy(this, orig, sizeof(SceneGraph)); - matrix = (float*)manager->allocate(sizeof(float)*16); - texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); + allocate_init(manager); for (int i = 0; i < 16; i++) { matrix[i] = orig->matrix[i]; @@ -187,9 +174,7 @@ { init(); - - matrix = (float*)manager->allocate(sizeof(float)*16*2); - texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); + allocate_init(manager); texture_info->texture_id = -1; //size : 頂点の数かな @@ -197,13 +182,6 @@ 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); } @@ -237,21 +215,20 @@ 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)); + allocate_init(manager); 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; } + + //size : 頂点の数かな + size = 6; + parent_name = NULL; + name = string_name; if (size % 3 != 0) { printf("vertex size is error. size %% 3 = %lld\n", size % 3); @@ -460,8 +437,28 @@ gid = -1; frame = 0; + } +// spe に渡すために 16アラインメント に allocate をする +void +SceneGraph::allocate_init(TaskManager *manager) +{ + matrix = (float*)manager->allocate(sizeof(float)*16); + out_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] = 0; + out_matrix[i] = 0; + } + for (int i = 0; i < 4; i++) { + matrix[i*4+i] = 1; + out_matrix[i*4+i] = 1; + } +} + + SceneGraph::~SceneGraph() { (this->*finalize)(); @@ -1228,9 +1225,9 @@ void SceneGraph::translate(float x, float y, float z) { - this->matrix[3] += x; - this->matrix[4+3] += y; - this->matrix[8+3] += z; + this->matrix[12] += x; + this->matrix[13] += y; + this->matrix[14] += z; } /** @@ -1241,7 +1238,7 @@ void SceneGraph::translateX(float x) { - this->matrix[3] += x; + this->matrix[12] += x; } /** @@ -1252,7 +1249,7 @@ void SceneGraph::translateY(float y) { - this->matrix[4+3] += y; + this->matrix[13] += y; } /** @@ -1263,23 +1260,36 @@ void SceneGraph::translateZ(float z) { - this->matrix[8+3] += z; + this->matrix[14] += z; } void -SceneGraph::angleIt(float *angle) +SceneGraph::angleIt(float xangle, float yangle, float zangle) { float m[16]; float t[4] = {0,0,0,0}; + float angle[4] = {xangle, yangle, zangle, 1}; for(int i=0;i<16;i++) m[i] = matrix[i]; get_matrix(matrix, angle, t, m); } + +// 今の SceneGraph の構造だと、親のスケーリングが子に繁栄される。 void -SceneGraph::scaleIt(float *scale) +SceneGraph::scaleIt(float sx, float sy, float sz) { - for(int i=0;i<4;i++) { - for(int j=0;i<3;j++) { + + float scale[3] = {sx, sy, sz}; + + /* + * | sx*r sx*r sx*r 0 | + * | sy*r sy*r sy*r 0 | + * | sz*r sz*r sz*r 0 | + * | t t t 1 | + */ + + for(int i=0;i<3;i++) { + for(int j=0;j<3;j++) { matrix[i*4+j] = matrix[i*4+j]*scale[i]; } }
--- a/Renderer/Engine/SceneGraph.h Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/SceneGraph.h Thu Jan 26 22:30:32 2012 +0900 @@ -87,7 +87,8 @@ // desutroctor で呼ばれる void (SceneGraph::*finalize)(void); - void init(void); + void init(); + void allocate_init(TaskManager *manager); void finalize_original(void); void finalize_copy(void); void move_execute(int screen_w, int screen_h); @@ -117,8 +118,8 @@ void translateX(float x); void translateY(float y); void translateZ(float z); - void scaleIt(float *scale); - void angleIt(float *angle); + void scaleIt(float sx, float sy, float sz); + void angleIt(float xangle, float yangle, float zangle); void tree_check(void);
--- a/Renderer/Engine/SceneGraphRoot.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/SceneGraphRoot.cc Thu Jan 26 22:30:32 2012 +0900 @@ -232,9 +232,6 @@ doc = xmlParseFile(xmlfile); cur = xmlDocGetRootElement(doc); - /* ?? */ - xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); - /* XMLのノードを一つずつ解析 */ for (cur=cur->children; cur; cur=cur->next) { /*初期化:curをドキュメントルートの一個下に設定 @@ -261,452 +258,6 @@ xmlFreeDoc(doc); } -/*static const char* -get_property(const char *name, xmlNodePtr cur){ - xmlAttr *p=cur->properties; - if (p==0) return ""; - for ( ;p; p=p->next) { - if ( xmlStrcmp(p->name, (xmlChar*)name) !=0 ) { - xmlNode* n=p->children; - if ( n==NULL ) return ""; - const char * v=(const char*)n->content; - if ( v==NULL ) return ""; - return v; - } - } - return ""; -}*/ - -typedef struct source { - char *id; - union { - float *array; - char *alias; - }u; - int count; - struct source *next; -} SOURCE; -typedef SOURCE *SOURCE_P; - -typedef struct list { - SOURCE_P first; - SOURCE_P end; -} LIST; -typedef LIST *LIST_P; - -/* add source list */ -static void -addSource(LIST_P list, SOURCE_P src) { - if (list->first == NULL && list->end == NULL) { - list->first = list->end = src; - return; - } - list->end->next = src; - list->end = src; -} - -/* compare a with b. Using to compare id */ -/* -static int -strcmp_a(const char *a, const char *b) -{ - while (*a && *a++ == *b++); - if (*a) return 0; - return a[-1] > b[-1] ? 1:-1; -} -static float -get_point(char *id, int position, LIST_P list) -{ - SOURCE_P cur = list->first; - for (;cur ; cur=cur->next) { - if (!strcmp_a(id, cur->id)) { - if (cur->count == 0) //alias - return get_point(cur->u.alias, position, list); - float *a = cur->u.array; - if (position <= cur->count) { - return a[position]; - } - } - } -} -*/ -/** - * co - */ -static SOURCE_P -most_match(const char *id , LIST_P list) -{ - SOURCE_P src = NULL; - SOURCE_P cur = NULL;; - int tmplength = 0; - int strlength; - for (cur=list->first ;cur!=list->end ;cur=cur->next) { - for (strlength=0;id[strlength]==cur->id[strlength];strlength++); - if (tmplength < strlength) { - tmplength = strlength; - src = cur; - } - } - - if (src == NULL){ - fprintf(stderr,"not match"); - } - return src; -} - -struct collada_state { - collada_state(){ - polylist = 0; - - vertex_offset = -1; - vertex_count = 0; - - normal_offset = -1; - normal_count = 0; - - texcoord_offset = -1; - texcoord_count = 0; - - polylist_count = 0; - vcsum = 0; - - } - int polylist; - int library_images; - xmlChar *pid; - - char *vertex_src; - int vertex_offset; - int vertex_count; - - char *normal_src; - int normal_offset; - int normal_count; - - char *texcoord_src; - int texcoord_offset; - int texcoord_count; - - float *vcount; - float *pcount; - - SOURCE_P normal_float; - SOURCE_P vertex_float; - SOURCE_P texcoord_float; - - char *vertices_src; - int polylist_count; - - char *name; - char *tex_picname; - int vcsum; -}; - -static texture_list list[TABLE_SIZE]; -static texture_list *texture_info; - -void get_texpic(char *filename, SceneGraphPtr sg, xmlNodePtr cur, TaskManager *manager) -{ - char image_name[20] = "/tmp/image_XXXXXX"; - if (filename == NULL || filename[0] == 0) { - return; - } - - /** - * image_name を既に Load していれば何もしない - */ - int tex_id; - /* ball test */ - if (sgid_hash.sg_hash_regist(/*filename*/"Ball", tex_id) == -1) { - - SDL_Surface *texture_image = sg->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 = sg->makeTapestries(manager, texture_image, tex_id); - tex_id = texture_info->texture_id; - - if (unlink(image_name)) { - printf("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 decode_float_array(xmlNodePtr cur,LIST_P list ){ - SOURCE_P src = (SOURCE_P)malloc(sizeof(SOURCE)); - char *id = (char*)xmlGetProp(cur, (xmlChar*)"id"); - src->id = (char*)xmlGetProp(cur, (xmlChar*)"id"); - - int count = atoi((char*)xmlGetProp(cur, (xmlChar*)"count")); - src->count = atoi((char*)xmlGetProp(cur, (xmlChar*)"count")); - //src->u.array = (float*)malloc(sizeof(float)*src->count); - src->u.array = new float[src->count]; - char *cont =(char*)xmlNodeGetContent(cur); - //const char *id = get_property("id", cur); - //int count = atoi(get_property("count", cur)); - - /* store float inpoint list */ - for (int i = 0; cont != NULL; i++) { - cont = pickup_float(cont, src->u.array+i); - } - - src->next = NULL; - addSource(list, src); - printf("id:%s count:%d cont:%s\n", id, count, cont); -} - - -void -get_points(xmlNodePtr cur, collada_state *s, TaskManager *manager){ - printf("start decode points\n"); - char *pcont = (char*)xmlNodeGetContent(cur); - for (int i = 0;i < s->polylist_count;i++){ - s->vcsum += s->vcount[i]; - } - - //s->pcount = (float*)malloc(sizeof(float)*vcsum); - s->pcount = new float[s->vcsum]; - for (int i=0; pcont != NULL; i++) { - pcont = pickup_float(pcont, s->pcount+i); - } -} -void -decode_points(xmlNodePtr cur, collada_state *s, TaskManager *manager){ - int vertexp[s->vcsum]; - for (int i=0;i<s->vcsum;i++){ - vertexp[i]=0; - } - //float *vertex_table; - //float *normal_table; - //float *texcoord_table; - - float vertex_table[s->vertex_float->count]; - //vertex_table = new float[s->vertex_float->count]; - //float *vertex_table = (float*)malloc(sizeof(float)*s->vertex_float->count) ; - - float normal_table[s->normal_float->count]; - //normal_table = new float[s->normal_float->count]; - //float *normal_table = (float*)malloc(sizeof(float)*s->normal_float->count); - - float texcoord_table[s->texcoord_float->count]; - //texcoord_table = new float[s->texcoord_float->count]; - //float *texcoord_table = (float*)malloc(sizeof(float)*s->texcoord_float->count) ; - - int limit = s->vcsum * 2; - if (s->texcoord_offset == 2){ - limit = s->vcsum * 3; - } - - /* p separate vertex position and nomal position. */ - for (int i=0,j=0; i < limit; i+=2,j++) { - vertexp[j] = s->pcount[i]; - normal_table[j] = s->normal_float->u.array[(int)s->pcount[i+1]]; - if (s->texcoord_offset == 2) { - texcoord_table[j] = s->texcoord_float->u.array[(int)s->pcount[i+2]]; - i++; - } - } - - for (int i=0;i<s->vcsum;i++) { - if (s->vcount[i] == 4) { - for (int j=0; j < s->vcount[i]; j++) { - vertex_table[i] = s->vertex_float->u.array[vertexp[i]]; - vertex_table[i+3] = s->vertex_float->u.array[vertexp[i+1]]; - i += 2; - } - }else if (s->vcount[i]==3) { - vertex_table[i] = s->vertex_float->u.array[vertexp[i]]; - } - } - /** - * (SceneGraph.cc) - * pickup_normal,pickup_coordinate,pickup_textureの処理 - * vcsumは頂点の数,countは面の数 - */ - int count = s->vcsum / 3; - //polygonの作成 - SceneGraphPtr sg = new SceneGraph(manager); - sg->pp_num = (count + MAX_SIZE_TRIANGLE - 1) / MAX_SIZE_TRIANGLE; - sg->pp = (PolygonPack*)malloc(sizeof(PolygonPack)*sg->pp_num); - //sg->pp = new PolygonPack[sg->pp_num]; - - for (int i = 0;i < sg->pp_num; i++ ){ - PolygonPackPtr pp = sg->pp; - TrianglePackPtr tri = pp[i].tri; - // TrianglePack の size のチェック - int tri_size = (count < MAX_SIZE_TRIANGLE) ? count : MAX_SIZE_TRIANGLE ; - pp[i].info.size = tri_size; - int k = 0; - int m = 0; - int n = 0; - for (int j = 0; j < tri_size; j++) { - tri[j].normal1.x = normal_table[k++]; - tri[j].normal1.y = normal_table[k++]; - tri[j].normal1.z = normal_table[k++]; - - tri[j].normal2.x = normal_table[k++]; - tri[j].normal2.y = normal_table[k++]; - tri[j].normal2.z = normal_table[k++]; - - tri[j].normal3.x = normal_table[k++]; - tri[j].normal3.y = normal_table[k++]; - tri[j].normal3.z = normal_table[k++]; - - tri[j].ver1.tex_x = texcoord_table[m++]; - tri[j].ver1.tex_y = texcoord_table[m++]; - - tri[j].ver2.tex_x = texcoord_table[m++]; - tri[j].ver2.tex_y = texcoord_table[m++]; - - tri[j].ver3.tex_x = texcoord_table[m++]; - tri[j].ver3.tex_y = texcoord_table[m++]; - - tri[j].ver1.x = vertex_table[n++]; - tri[j].ver1.y = vertex_table[n++]; - tri[j].ver1.z = vertex_table[n++]; - - tri[j].ver2.x = vertex_table[n++]; - tri[j].ver2.y = vertex_table[n++]; - tri[j].ver2.z = vertex_table[n++]; - - tri[j].ver3.x = vertex_table[n++]; - tri[j].ver3.y = vertex_table[n++]; - tri[j].ver3.z = vertex_table[n++]; - - } - - } - sg->c_xyz[0] = sg->c_xyz[1] = sg->c_xyz[2] = 0; - - /*TEST*/ - for (int i=0; i<s->vcsum; i++) { - printf("vertexp = %d\n", vertexp[i]); - //printf("vertex_table= %f\n", s->vertex_table[i]); - } - int tex_id = 0; - sgid_hash.sg_hash_regist("Ball", tex_id); - //get_texpic(s->tex_picname, sg, cur , manager); - //free(vertexp); - //free(vertex_table); - //free(normal_table); - //free(texcoord_table); - - //delete []vertex_table; - //delete []normal_table; - //delete []texcoord_table; - - /* got out of polylist */ - s->polylist = 0; -} - -static void -xml_walk(xmlNodePtr cur, struct collada_state *s, LIST_P list,SceneGraphRoot *root) -{ - int in_polylist=0; - printf("name = %s, child:%s\n", (char *)cur->name, (char *)cur->children); - printf("s->polylist = %d\n",s->polylist); - if (!xmlStrcmp(cur->name, (xmlChar*)"polylist")) { - s->polylist_count = atoi((char*)xmlGetProp(cur, (xmlChar*)"count")); - s->polylist=1; - in_polylist=1; - } else if (!xmlStrcmp(cur->name, (xmlChar*)"vertices")) { - s->pid = xmlGetProp(cur, (xmlChar*)"id"); - } else if (!xmlStrcmp(cur->name, (xmlChar*)"library_images")) { - s->library_images=1;// library_images is wrote at texture image name. only use one image file - } else if (s->library_images && !xmlStrcmp(cur->name, (xmlChar*)"init_from")) { - s->tex_picname = (char*)xmlGetProp(cur, (xmlChar*)"init_from"); - printf("------------------%s",s->tex_picname); - s->library_images=0; - } else if (!s->polylist && !xmlStrcmp(cur->name, (xmlChar*)"input")) { - char *semantic = (char*)xmlGetProp(cur, (xmlChar*)"semantic"); - if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"POSITION")) { - s->vertices_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); - } - } else if (s->polylist && !xmlStrcmp(cur->name, (xmlChar*)"input")) { - char *semantic = (char*)xmlGetProp(cur, (xmlChar*)"semantic"); - if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"VERTEX")) { - s->vertex_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); - s->vertex_offset = atoi((char*)xmlGetProp(cur, (xmlChar*)"offset")); - s->vertex_float = most_match(s->vertices_src+1, list); - } else if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"NORMAL")) { - s->normal_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); - s->normal_offset = atoi((char*)xmlGetProp(cur, (xmlChar*)"offset")); - s->normal_float = most_match(s->normal_src+1, list); - } else if (!xmlStrcmp((xmlChar*)semantic, (xmlChar*)"TEXCOORD")) { - s->texcoord_src = (char*)xmlGetProp(cur, (xmlChar*)"source"); - s->texcoord_offset = atoi((char*)xmlGetProp(cur, (xmlChar*)"offset")); - s->texcoord_float = most_match(s->texcoord_src+1, list); - } - } else if (!xmlStrcmp(cur->name, (xmlChar*)"vcount")) { - char *vcont = (char*)xmlNodeGetContent(cur); - //s->vcount = (float*)malloc(sizeof(float)*s->polylist_count); - s->vcount = new float[s->polylist_count]; - for (int i=0; vcont!=NULL; i++) { - /* store vcount list */ - vcont = pickup_float(vcont, s->vcount+i); - } - } else if (!xmlStrcmp(cur->name, (xmlChar*)"p")) { - get_points(cur,s,root->tmanager); - in_polylist = 0; - } else if (!xmlStrcmp(cur->name, (xmlChar*)"float_array")) { - decode_float_array(cur,list); - } else if (!xmlStrcmp(cur->name, (xmlChar*)"node" )) { - s->name = (char*)xmlGetProp(cur, (xmlChar*)"id"); - decode_points(cur,s,root->tmanager); - } - for (cur=cur->children; cur; cur=cur->next){ - xml_walk(cur,s,list,root); - } -} - -void -init_list(LIST_P list) { - list->first = NULL; - list->end = NULL; -} - -void -SceneGraphRoot::createFromCOLLADAfile(TaskManager *manager, const char *xmlColladafile) -{ - /*make parse dom*/ - xmlDocPtr doc; - xmlNodePtr cur; - //,cur_images,cur_effects,cur_geometries,cur_visual_scenes; - //SceneGraphPtr tmp; - - doc = xmlParseFile(xmlColladafile); - cur = xmlDocGetRootElement(doc); - - if (xmlStrcmp(cur->name, (xmlChar*)"COLLADA")){ - return ; - } - - /* node analyze */ - struct collada_state s; - for (cur=cur->children; cur; cur=cur->next){ - LIST list; - init_list(&list); - xml_walk(cur,&s,&list,this); - } - //xmlFreeDoc(doc); -} - void SceneGraphRoot::createFromXMLmemory(TaskManager *manager, SceneGraph *node, char *data, int len) { @@ -718,9 +269,6 @@ doc = xmlParseMemory(data, len); cur = xmlDocGetRootElement(doc); - /* ?? */ - xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); - /* XMLのノードを一つずつ解析 */ for (cur=cur->children; cur; cur=cur->next) { /* 扱うのはsurfaceオンリー */ @@ -858,9 +406,6 @@ light_vector[i*4+3] = light_vector_tmp[i*4+3]; } - - - } } @@ -941,7 +486,7 @@ * (polygon_vertex) * camera->(s) */ - matrix4x4(camera->matrix, camera->m_view, camera->m_pers); + matrix4x4(camera->out_matrix, camera->m_view, camera->m_pers); lightCalc(camera); copyTree(sg_draw_tree, camera); @@ -956,13 +501,92 @@ sg_exec_tree = camera->children; } +struct st_matrix { + float *m; + st_matrix *next; + st_matrix *prev; +}; + +typedef struct matrix_list { + int length; + st_matrix *first; + st_matrix *end; +}matrix_list, *matrix_listp; + +static void +initList(matrix_list *list) { + list->first = NULL; + list->end = NULL; + list->length = 0; +} + + +static void +addMatrix(matrix_list *list, float *matrix) { + + ++list->length; + + st_matrix *sm = new st_matrix; + sm->m = matrix; + sm->next = NULL; + sm->prev = NULL; + + if (list->first == NULL && list->end == NULL) { + list->first = list->end = sm; + return; + } + list->end->next = sm; + sm->prev = list->end; + list->end = sm; +} + +static void +popMatrix(matrix_list *list) { + + st_matrix *end = list->end; + --list->length; + + if (end != list->first) { + st_matrix *new_end = end->prev; + new_end->next = NULL; + list->end = new_end; + } else { + list->first = NULL; + list->end = NULL; + } + + delete end; +} + +static void +removeMatrix(matrix_list *list) { + st_matrix *p = list->first; + while (p) { + st_matrix *p1 = p->next; + delete p; + p = p1; + } +} + + void SceneGraphRoot::copyTree(SceneGraphPtr t, SceneGraphPtr cur_parent) { // SceneGraphPtr t = sg_draw_tree; + // + //int matrix_size = 16; // 4x4の行列の大きさ + matrix_list *mlist = new matrix_list; + initList(mlist); + + /* + * Task の引数として設定するため、 + * ひとつの SceneGraphNode に必要な matrix を、 + * Tree を辿ると同時にリストに登録していく + */ + addMatrix(mlist, cur_parent->matrix); + /*removeのflagをもとにtreeを形成*/ - while (t) { SceneGraphPtr c = NULL; if (!t->isRemoved()) { @@ -971,11 +595,40 @@ cur_parent->addChild(c); c->frame = t->frame; /*親の回転、座標から、子の回転、座標を算出*/ - get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix); + //get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix); + + /***** + // うーん、SceneGraphRoot内で task create しちゃっていいのか? + + HTaskPtr cmat = create_task_array(CALC_MATRIX, 1, 1, mlist->length+1, 1); // +1は自分の分 + + int index = 0; + for (st_matrixp m = list->fisrt; m != NULL; m = m->next) { + cmat->set_inData(index, m->matrix, sizeof(float)*matrix_size); + index++; + } + cmat->set_inData(index, t->matrix, sizeof(float)*matrix_size); + + cmat->set_outData(0, c->out_matrix, sizeof(float)*matrix_size); + cmat->set_cpu(SPE_ANY); + task_next->wait_for(cmat); + cmat->spawn_task_array(cmat->next()); + cmat->spawn(); + + // きちんと matrix を list にできるかテストしなきゃ + ******/ + + float m[16]; + unitMatrix(m); + // matrix を直接いじるAPI と, xyz,angle を使った座標変換を共存させる + get_matrix(m, c->angle, c->xyz, c->matrix); + matrix4x4(c->out_matrix, m, cur_parent->out_matrix); + } if (t->children != NULL && c != NULL) { + addMatrix(mlist, t->matrix); cur_parent = c; t = t->children; } else if (t->brother != NULL) { @@ -990,6 +643,7 @@ t = NULL; break; } else { + popMatrix(mlist); cur_parent = cur_parent->parent; t = t->parent; } @@ -998,14 +652,20 @@ } } + removeMatrix(mlist); + delete mlist; } void SceneGraphRoot::treeApply(int screen_w, int screen_h) { + + matrix4x4(camera->out_matrix, camera->m_view, camera->m_pers); + // don't calcurate sg_draw_tree's brother - transTree(sg_draw_tree->children, camera); + transTree(sg_draw_tree, camera); + } @@ -1015,16 +675,14 @@ void SceneGraphRoot::transTree(SceneGraphPtr t, SceneGraphPtr cur_parent) { - // SceneGraphPtr t = sg_draw_tree; /*removeのflagをもとにtreeを形成*/ while (t) { - SceneGraphPtr c = NULL; if (!t->isRemoved()) { /*親の回転、座標から、子の回転、座標を算出*/ - matrix4x4(t->matrix,t->matrix,cur_parent->matrix); + matrix4x4(t->out_matrix,t->matrix,cur_parent->out_matrix); } - if (t->children != NULL && c != NULL) { + if (t->children != NULL) { cur_parent = t; t = t->children; } else if (t->brother != NULL) { @@ -1104,6 +762,7 @@ } } +// 呼ばれてない void SceneGraphRoot::checkRemove() {
--- a/Renderer/Engine/base64_de.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/base64_de.cc Thu Jan 26 22:30:32 2012 +0900 @@ -10,6 +10,7 @@ int nlen; }; +const char* szB64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; unsigned char CtoNum(int c) { @@ -89,3 +90,5 @@ return 0; } + +
--- a/Renderer/Engine/matrix_calc.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/matrix_calc.cc Thu Jan 26 22:30:32 2012 +0900 @@ -92,6 +92,15 @@ } +void +copyMatrix(float *m0, float *m1) +{ + for (int i = 0; i < 16; i++) { + m0[i] = m1[i]; + } +} + + /** * ベクトルの正規化 * @@ -166,6 +175,7 @@ */ void matrix4x4(float *xyz, float *xyz1, float *xyz2) //xyz[16] { + for(int t=0; t<16; t+=4) { for(int i=0; i<4; i++)
--- a/Renderer/Engine/matrix_calc.h Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/matrix_calc.h Thu Jan 26 22:30:32 2012 +0900 @@ -25,6 +25,7 @@ float determinant(float *m); void transMatrix(float *m0, float *m1, float *v); void ApplyMatrix(float *v1, float *v2); +void copyMatrix(float *m0, float *m1); void ScaleMatrix(float *m, float v); void ScaleMatrixXYZ(float *m, float sx,float sy, float sz); static inline unsigned long align(unsigned long x,unsigned long alig) { return ((x+(alig-1))&~(alig-1)); }
--- a/Renderer/Engine/polygon.h Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/polygon.h Thu Jan 26 22:30:32 2012 +0900 @@ -15,12 +15,16 @@ const char *name; const char *parent_name; + // SceneGraph から直接操作するmatrix. 操作した matrix は保存しておかないといけない float *matrix; + // matrix に view, perspective, screen 変換をかけたものが入る. SceneGraphから直接操作される matrix は別に必要 + float *out_matrix; texture_list *texture_info; PolygonPackPtr pp; int pp_num; + // ここの xyz, angle はいらなくなる float xyz[4]; // position float angle[4]; // angle float c_xyz[4]; // center of rotation
--- a/Renderer/Engine/task/CreatePolygonFromSceneGraph.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/task/CreatePolygonFromSceneGraph.cc Thu Jan 26 22:30:32 2012 +0900 @@ -117,7 +117,7 @@ normal_matrix[4*3] = normal_matrix[4*3+1] = normal_matrix[4*3+2] = 0; normal_matrix[4*3+3] = 1; - float matrix[16]; // wvpm matrix + float matrix[16]; // wvps matrix matrix4x4(matrix, wvp_matrix, m_screen); texture_list *tritexinfo = (texture_list*)smanager->get_input(rbuf, 3);
--- a/Renderer/Engine/viewer.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Engine/viewer.cc Thu Jan 26 22:30:32 2012 +0900 @@ -457,8 +457,6 @@ */ - - HTaskPtr game_task_array = 0; /* GameTask の処理の終了を待ってからポリゴンを作る */ @@ -471,7 +469,6 @@ CameraPtr camera = sgroot->getCamera(); - //多分このsg_remove_listであってる?。チェック対象かも for (SceneGraphPtr t = sgroot->sg_remove_list; t != NULL; t = t->next) { if (t->size > 0) { pp_sum_num += t->pp_num; @@ -480,7 +477,7 @@ HTaskPtr create_pp = manager->create_task(CreatePolygonFromSceneGraph); create_pp->add_inData(&t->pp[i], sizeof(PolygonPack)); - create_pp->add_inData(t->matrix, sizeof(float)*16); + create_pp->add_inData(t->out_matrix, sizeof(float)*16); create_pp->add_inData(camera->m_screen, sizeof(float)*16); create_pp->add_inData(t->texture_info, sizeof(texture_list));
--- a/Renderer/Test/ball_bound.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Test/ball_bound.cc Thu Jan 26 22:30:32 2012 +0900 @@ -31,9 +31,9 @@ if (pad->circle.isHold()) { if (pad->left.isHold()) { - node->xyz[0] -= speed; + node->xyz[0] -= speed; if(node->xyz[0] < ball_radius) - node->xyz[0] = ball_radius; + node->xyz[0] = ball_radius; } else if (pad->right.isHold()) { node->xyz[0] += speed; if(node->xyz[0] > screen_w - ball_radius)
--- a/Renderer/Test/universe.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/Renderer/Test/universe.cc Thu Jan 26 22:30:32 2012 +0900 @@ -17,25 +17,29 @@ static void moon_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) { - node->angle[0] += 3.0f; + //node->stack_angle[0] += 3.0f; + node->angleIt(3, 0, 0); } static void earth_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) { - node->angle[1] += 1.0f; - if (node->angle[1] > 360.0f) { - node->angle[1] = 0.0f; - } + //node->angle[1] += 1.0f; + node->angleIt(0, 1, 0); + //if (node->angle[1] > 360.0f) { + //node->angle[1] = 0.0f; + //} - node->xyz[0] += node->stack_xyz[0]; - if ((int)node->xyz[0] > screen_w || (int)node->xyz[0] < 0) { + //node->xyz[0] += node->stack_xyz[0]; + node->translateX(node->stack_xyz[0]); + if ((int)node->matrix[12] > screen_w || (int)node->matrix[12] < 0) { node->stack_xyz[0] = -node->stack_xyz[0]; } - node->xyz[1] += node->stack_xyz[1]; - if ((int)node->xyz[1] > screen_h || (int)node->xyz[1] < 0) { + //node->xyz[1] += node->stack_xyz[1]; + node->translateY(node->stack_xyz[1]); + if ((int)node->matrix[13] > screen_h || (int)node->matrix[13] < 0) { node->stack_xyz[1] = -node->stack_xyz[1]; } } @@ -51,23 +55,29 @@ sgroot->OnLightSysSwitch(); SceneGraphPtr light = sgroot->getLight(0); sgroot->OnLightSwitch(0); - light->xyz[0] = screen_w; - light->xyz[1] = screen_h; - light->xyz[2] = 100; + //light->xyz[0] = screen_w; + //light->xyz[1] = screen_h; + //light->xyz[2] = 100; + light->translateX(screen_w); + light->translateY(screen_h); + light->translateZ(100); // SceneGraph ID から SceneGraph を生成する earth = sgroot->createSceneGraph("Earth"); // SceneGraph の move と collision を設定 earth->set_move_collision(earth_move, earth_collision); - earth->xyz[0] = screen_w / 2; - earth->xyz[1] = screen_h / 2; + //earth->xyz[0] = screen_w / 2; + earth->translateX(screen_w / 2); + //earth->xyz[1] = screen_h / 2; + earth->translateY(screen_h / 2); + earth->scaleIt(3,1,3); earth->stack_xyz[0] = 3.0f; earth->stack_xyz[1] = 3.0f; moon = sgroot->createSceneGraph("Moon"); moon->set_move_collision(moon_move, moon_collision); - + // SceneGraph 同士の親子関係を設定 (今回は 親 earth、子 moon) earth->addChild(moon);
--- a/TaskManager/Cell/CellTaskManagerImpl.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Cell/CellTaskManagerImpl.cc Thu Jan 26 22:30:32 2012 +0900 @@ -26,9 +26,6 @@ spe_running = 0; spuIdle = spuIdle_; - //speThreads = new SpeThreads(machineNum); - //speThreads->init(); - // 実行される Task 用の パイプライン用のダブルバッファ speTaskList = new QueueInfo<TaskList>*[machineNum]; // spe上の走っている Task の配列 taskListInfo = new QueueInfo<TaskList>*[machineNum]; // 次に走る Task の配列 @@ -46,6 +43,8 @@ set_scheduler(mscheduler); ppeManager->init(mscheduler, this, useRefDma); // ここで HTaskInfo が共有される。 + speThreads->init(); + // 実行可能な HTask のリスト。 FifoTaskManager と共有される activeTaskQueue = ppeManager->activeTaskQueue; // HTask の factory。 HTaskInfo ならなんでもいい。 @@ -358,7 +357,6 @@ create_impl(int num, int useRefDma) { Threads *cpus = new SpeThreads(num); - cpus->init(); return new CellTaskManagerImpl(num,cpus); } #endif // __CERIUM_CELL
--- a/TaskManager/Fifo/FifoDmaManager.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Fifo/FifoDmaManager.cc Thu Jan 26 22:30:32 2012 +0900 @@ -11,15 +11,15 @@ { if (size == 0) return buf; - //unsigned long long wait = 0; - //(this->*start_dmawait_profile)(); + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); if (s) buf = s->manager->allocate(size); memcpy(buf, (void*)addr, size); - //(this->*end_dmawait_profile)(&wait); - //global_load_time += wait; - //dma_load_time += wait; + (this->*end_dmawait_profile)(&wait); + global_load_time += wait; + dma_load_time += wait; return buf; } @@ -36,14 +36,14 @@ { if (size == 0) return buf; - //unsigned long long wait = 0; - //(this->*start_dmawait_profile)(); + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); memcpy((void*)addr, buf, size); - //(this->*end_dmawait_profile)(&wait); - //global_store_time += wait; - //dma_store_time += wait; + (this->*end_dmawait_profile)(&wait); + global_store_time += wait; + dma_store_time += wait; return buf; } @@ -60,8 +60,8 @@ void * FifoDmaManager::dma_loadList(Scheduler *s, ListDataPtr list, void *buff, uint32 mask) { - //unsigned long long wait = 0; - //(this->*start_dmawait_profile)(); + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); int list_size = list->length; long bound; @@ -75,9 +75,9 @@ bound += elm->size; } - //(this->*end_dmawait_profile)(&wait); - //global_load_time += wait; - //dma_loadList_time += wait; + (this->*end_dmawait_profile)(&wait); + global_load_time += wait; + dma_loadList_time += wait; return buff; } @@ -93,8 +93,8 @@ void FifoDmaManager::dma_storeList(ListDataPtr list, void *buff, uint32 mask) { - //unsigned long long wait = 0; - //(this->*start_dmawait_profile)(); + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); int list_size = list->length; memaddr bound; @@ -107,9 +107,115 @@ bound += elm->size; } - //(this->*end_dmawait_profile)(&wait); - //global_store_time += wait; - //dma_storeList_time += wait; + (this->*end_dmawait_profile)(&wait); + global_store_time += wait; + dma_storeList_time += wait; +} + +void +FifoDmaManager::mail_write(memaddr data) +{ + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + mail_queue1->send(data); + + (this->*end_dmawait_profile)(&wait); + global_mail_time += wait; + mail_write_time += wait; +} + +void +FifoDmaManager::mail_write_queue(memaddr data) +{ + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + mail_queue1->send(data); + + (this->*end_dmawait_profile)(&wait); + global_mail_time += wait; + mail_write_time += wait; +} + +void +FifoDmaManager::mail_write_finish_list(memaddr data) +{ + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + mail_queue1->send(data); + + (this->*end_dmawait_profile)(&wait); + global_mail_time += wait; + mail_write_time += wait; +} + +memaddr +FifoDmaManager::mail_read() +{ + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + memaddr data; + data = mail_queue2->recv(); + + (this->*end_dmawait_profile)(&wait); + global_mail_time += wait; + mail_read_time += wait; + + return data; +} + +memaddr +FifoDmaManager::task_list_mail_read() +{ + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + memaddr data; + data = mail_queue2->recv(); + + (this->*end_dmawait_profile)(&wait); + global_mail_time += wait; + mail_read_time += wait; + + return data; +} + +void +FifoDmaManager::mail_write_from_host(memaddr data) +{ + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + mail_queue2->send(data); + + (this->*end_dmawait_profile)(&wait); + global_mail_time += wait; + mail_write_from_host_time += wait; +} + +memaddr +FifoDmaManager::mail_read_from_host() +{ + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + memaddr data; + data = mail_queue1->recv(); + + (this->*end_dmawait_profile)(&wait); + global_mail_time += wait; + mail_read_from_host_time += wait; + + return data; +} + +int +FifoDmaManager::has_mail_from_host() +{ + return mail_queue1->count(); } void @@ -118,10 +224,15 @@ global_busy_time = 0; global_load_time = 0; global_store_time = 0; + global_mail_time = 0; dma_load_time = 0; dma_store_time = 0; dma_loadList_time = 0; dma_storeList_time = 0; + mail_read_time = 0; + mail_write_time = 0; + mail_read_from_host_time = 0; + mail_write_from_host_time = 0; start_dmawait_profile = &FifoDmaManager::do_start_dmawait_profile; end_dmawait_profile = &FifoDmaManager::do_end_dmawait_profile; @@ -133,7 +244,7 @@ FifoDmaManager::stop_profile() { start_time = rdtsc(); - global_busy_time = stop_time - start_time; + global_busy_time += start_time - stop_time; start_dmawait_profile = &FifoDmaManager::null_start_dmawait_profile; end_dmawait_profile = &FifoDmaManager::null_end_dmawait_profile; @@ -143,7 +254,7 @@ FifoDmaManager::do_start_dmawait_profile() { start_time = rdtsc(); - global_busy_time += stop_time - start_time; + global_busy_time += start_time - stop_time; } void @@ -159,25 +270,48 @@ void FifoDmaManager::show_dma_wait(Scheduler *s, int cpu) { - unsigned long long all_time = global_busy_time + global_load_time + global_store_time; + unsigned long long all_time = global_busy_time + global_load_time + + global_store_time + global_mail_time; double busy = ((double)global_busy_time)/((double)all_time)*100.0; double load = ((double)global_load_time)/((double)all_time)*100.0; double store = ((double)global_store_time)/((double)all_time)*100.0; + double mail = ((double)global_mail_time)/((double)all_time)*100.0; + double read = ((double)mail_read_time)/((double)all_time)*100.0; + double write = ((double)mail_write_time)/((double)all_time)*100.0; + double read_from_host = ((double)mail_read_from_host_time)/((double)all_time)*100.0; + double write_from_host = ((double)mail_write_from_host_time)/((double)all_time)*100.0; - s->printf("cpu%d:\n busy_time = %.3g%%" - " load_time = %.3g%%, " - " store_time = %.3g%% " - ,cpu, busy, load, store); + s->printf("cpu%d:\n busy_time = %lld(%.3g%%)\n" + " load_time = %lld(%.3g%%), " + " store_time = %lld(%.3g%%), " + " mail_time = %lld(%.3g%%) \n" + " mail_read_time = %lld(%.3g%%), " + " mail_write_time = %lld(%.3g%%)\n" + " mail_read_from_host_time = %lld(%.3g%%), " + " mail_write_from_host_time = %lld(%.3g%%)\n" + ,cpu, global_busy_time, busy, + global_load_time, load, + global_store_time, store, + global_mail_time, mail, + mail_read_time, read, + mail_write_time, write, + mail_read_from_host_time, read_from_host, + mail_write_from_host_time, write_from_host); global_busy_time = 0; global_load_time = 0; global_store_time = 0; + global_mail_time = 0; dma_load_time = 0; dma_store_time = 0; dma_loadList_time = 0; dma_storeList_time = 0; + mail_read_time = 0; + mail_write_time = 0; + mail_read_from_host_time = 0; + mail_write_from_host_time = 0; } uint32
--- a/TaskManager/Fifo/FifoDmaManager.h Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Fifo/FifoDmaManager.h Thu Jan 26 22:30:32 2012 +0900 @@ -28,6 +28,8 @@ mail_queue1 = new MailManager(); mail_queue2 = new MailManager(); #endif + start_dmawait_profile = &FifoDmaManager::null_start_dmawait_profile; + end_dmawait_profile = &FifoDmaManager::null_end_dmawait_profile; } ~FifoDmaManager() { @@ -38,8 +40,10 @@ /* variables */ protected: unsigned long long start_time, stop_time; - unsigned long long global_busy_time, global_load_time, global_store_time; + unsigned long long global_busy_time, global_load_time, global_store_time, global_mail_time; unsigned long long dma_load_time, dma_store_time, dma_loadList_time, dma_storeList_time; + unsigned long long mail_read_time, mail_write_time; + unsigned long long mail_read_from_host_time, mail_write_from_host_time; /* functions */ public: @@ -54,15 +58,15 @@ void show_dma_wait(Scheduler *s, int cpu); - void mail_write(memaddr data) { mail_queue1->send(data); } - void mail_write_queue(memaddr data) { mail_queue1->send(data); } - void mail_write_finish_list(memaddr data) { mail_queue1->send(data); } - memaddr mail_read() { return mail_queue2->recv(); } - memaddr task_list_mail_read() { return mail_queue2->recv(); } + void mail_write(memaddr data); + void mail_write_queue(memaddr data); + void mail_write_finish_list(memaddr data); + memaddr mail_read(); + memaddr task_list_mail_read(); - void mail_write_from_host(memaddr data) { mail_queue2->send(data); } - memaddr mail_read_from_host() { return mail_queue1->recv(); } - int has_mail_from_host() { return mail_queue1->count(); } + void mail_write_from_host(memaddr data); + memaddr mail_read_from_host(); + int has_mail_from_host(); virtual void *dma_loadList(Scheduler *s, ListDataPtr list, void *buff, uint32 mask); void dma_storeList(ListDataPtr, void *buff, uint32 mask);
--- a/TaskManager/Fifo/FifoTaskManagerImpl.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Fifo/FifoTaskManagerImpl.cc Thu Jan 26 22:30:32 2012 +0900 @@ -342,7 +342,6 @@ return new FifoTaskManagerImpl(num); } else { Threads *cpus = new CpuThreads(num,useRefDma); - cpus->init(); return new CellTaskManagerImpl(num,cpus); } }
--- a/TaskManager/Fifo/PreRefDmaManager.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Fifo/PreRefDmaManager.cc Thu Jan 26 22:30:32 2012 +0900 @@ -5,9 +5,17 @@ void * PreRefDmaManager::dma_load(Scheduler *s, void *buf, memaddr addr, uint32 size, uint32 mask) { + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + #ifdef __CERIUM_FIFO__ asm("prefetcht0 %0"::"m"(addr):"memory"); #endif // __CERIUM_FIFO__ + + (this->*end_dmawait_profile)(&wait); + global_load_time += wait; + dma_load_time += wait; + return (void*)addr; }
--- a/TaskManager/Fifo/ReferencedDmaManager.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Fifo/ReferencedDmaManager.cc Thu Jan 26 22:30:32 2012 +0900 @@ -5,12 +5,27 @@ void * ReferencedDmaManager::dma_load(Scheduler *s, void *buf, memaddr addr, uint32 size, uint32 mask) { + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + + (this->*end_dmawait_profile)(&wait); + global_load_time += wait; + dma_load_time += wait; + return (void*)addr; } void * ReferencedDmaManager::dma_loadList(Scheduler *s, ListDataPtr list, void *buff, uint32 mask) { + unsigned long long wait = 0; + (this->*start_dmawait_profile)(); + ListElementPtr elm = &list->element[0]; + + (this->*end_dmawait_profile)(&wait); + global_load_time += wait; + dma_loadList_time += wait; + return (void*)elm->addr; }
--- a/TaskManager/Makefile.def Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Makefile.def Thu Jan 26 22:30:32 2012 +0900 @@ -29,7 +29,7 @@ ABIBIT = 64 -OPT = -g -O0 -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE +OPT = -g -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE #OPT = -O9 -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE
--- a/TaskManager/Makefile.fifo Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Makefile.fifo Thu Jan 26 22:30:32 2012 +0900 @@ -14,8 +14,7 @@ ALL_OBJS = $(KERN_MAIN_OBJS) $(KERN_PPE_OBJS) $(KERN_SCHED_OBJS) \ $(KERN_SYSTASK_OBJS) $(IMPL_FIFO_OBJS) $(KERN_MEM_OBJS) \ - Cell/spe/SpeTaskManagerImpl.o Cell/CellTaskManagerImpl.o \ - Cell/spe/ShowTime.o Cell/spe/StartProfile.o + Cell/spe/SpeTaskManagerImpl.o Cell/CellTaskManagerImpl.o Makefile.dep:
--- a/TaskManager/Makefile.parallel Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/Makefile.parallel Thu Jan 26 22:30:32 2012 +0900 @@ -15,8 +15,7 @@ ALL_OBJS = $(KERN_MAIN_OBJS) $(KERN_PPE_OBJS) $(KERN_SCHED_OBJS) \ $(KERN_SYSTASK_OBJS) $(IMPL_FIFO_OBJS) $(KERN_MEM_OBJS) \ - Cell/spe/SpeTaskManagerImpl.o Cell/CellTaskManagerImpl.o \ - Cell/spe/ShowTime.o Cell/spe/StartProfile.o + Cell/spe/SpeTaskManagerImpl.o Cell/CellTaskManagerImpl.o Makefile.dep: make -f Makefile.parallel depend
--- a/TaskManager/kernel/ppe/CpuThreads.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/kernel/ppe/CpuThreads.cc Thu Jan 26 22:30:32 2012 +0900 @@ -11,19 +11,12 @@ SchedExternTask(StartProfile); -CpuThreads::CpuThreads(int num, int useRefDma, int start_id) : cpu_num(num), id_offset(start_id) { +CpuThreads::CpuThreads(int num, int useRefDma, int start_id) : cpu_num(num), use_refdma(useRefDma), id_offset(start_id) { threads = new pthread_t[cpu_num]; args = new cpu_thread_arg_t[cpu_num]; wait = new Sem(0); - for (int i = 0; i < cpu_num; i++) { - args[i].cpuid = i + id_offset; - args[i].scheduler = new MainScheduler(); - args[i].wait = wait; - args[i].useRefDma = useRefDma; - } - } CpuThreads::~CpuThreads() @@ -73,6 +66,13 @@ //CpuThreads::init() CpuThreads::init() { + for (int i = 0; i < cpu_num; i++) { + args[i].cpuid = i + id_offset; + args[i].scheduler = new MainScheduler(); + args[i].wait = wait; + args[i].useRefDma = use_refdma; + } + for (int i = 0; i < cpu_num; i++) { pthread_create(&threads[i], NULL, &cpu_thread_run, (void*)&args[i]);
--- a/TaskManager/kernel/ppe/CpuThreads.h Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/kernel/ppe/CpuThreads.h Thu Jan 26 22:30:32 2012 +0900 @@ -36,6 +36,7 @@ cpu_thread_arg_t *args; SemPtr wait; //スレッド生成時の待ち用 int cpu_num; + int use_refdma; int id_offset; };
--- a/TaskManager/kernel/schedule/Scheduler.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/TaskManager/kernel/schedule/Scheduler.cc Thu Jan 26 22:30:32 2012 +0900 @@ -48,6 +48,12 @@ task_count = 0; #endif + /* + * ;TODO + * Multi-Core Verの場合、各スレッドにMain Schedulerが作られるが、 + * その際、globalなlistの初期化を繰り返して無駄な処理を行なっている + */ + for (int i = 0; i< MAX_TASK_OBJECT; i++) { task_list[i].run = null_run; task_list[i].load = null_loader;
--- a/example/word_count/main.cc Thu Jan 26 22:19:46 2012 +0900 +++ b/example/word_count/main.cc Thu Jan 26 22:30:32 2012 +0900 @@ -338,7 +338,7 @@ if (w->task_num < w->task_blocks) { // last case - if (w->size >= w->division_size) + while (w->size >= w->division_size) run_tasks(manager,w,w->task_num, w->t_print, w->division_size); // remaining data while (w->size>0)