Mercurial > hg > Game > Cerium
changeset 1331:1dd2b2f5e2e9 draft
add collada file test program.
author | Taiki TAIRA <e095767@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 21 Dec 2011 04:22:17 +0900 |
parents | 615555d5bfa0 |
children | fab593a9feb1 6b7151aec7b6 |
files | Renderer/Engine/SceneGraphRoot.cc Renderer/Test/collada_test/collada_test.cc |
diffstat | 2 files changed, 403 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Renderer/Engine/SceneGraphRoot.cc Wed Dec 21 04:17:24 2011 +0900 +++ b/Renderer/Engine/SceneGraphRoot.cc Wed Dec 21 04:22:17 2011 +0900 @@ -478,7 +478,7 @@ float *vertex_table = (float*)malloc(sizeof(float)*s->vertex_float->count) ; float *normal_table = (float*)malloc(sizeof(float)*s->normal_float->count) ; - float *texcoord_table = (float*)malloc(sizeof(float)*s->texcoord_float->count) ; + float *texcoord_table = (float*)malloc(sizeof(float)*s->texcoord_float->count) ; /* p separate vertex position and nomal position. */ for (int i = 0,j=0; i < s->polylist_count; i+=2,j++) { @@ -578,7 +578,12 @@ LIST list; init_list(&list); +<<<<<<< local + + xml_walk(this, cur,&s, &list); +======= xml_walk(cur,&s, &list); +>>>>>>> other } xmlFreeDoc(doc); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Test/collada_test/collada_test.cc Wed Dec 21 04:22:17 2011 +0900 @@ -0,0 +1,397 @@ +#include <stdio.h> +#include <libxml/parser.h> + +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) { + printf("not match list\n"); + } + + 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; + } + + int polylist; + + 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 *skip_to_number(char *cont) +{ + if (cont == NULL) return(NULL); + for (;(*cont < '+' || *cont > '9') && (*cont != '\0');cont++) {} + if (*cont == '\0') + { + fprintf(stderr,"Content data is short\n"); + return(NULL); + } + return(cont); +} + + +char *pickup_float(char *cont, float *index) +{ + int sign=1,exp=1; + float shift=10,val_dec=0,val_int=0; + + cont = skip_to_number(cont); + if (cont == NULL) return(NULL); + + for (;*cont != ' ' && *cont != '\n' && *cont != '\t' && *cont != ',' ;cont++) + { + if (*cont == '-') + { + sign = -1; + } + else if (*cont == '.') + { + shift = 0.1; + } + else if (*cont >= '0' && *cont <= '9') + { + if (shift == 10) + { + val_int *= shift; + val_int += *cont - 48; + } + else + { + val_dec += (*cont - 48) * shift; + shift *= 0.1; + } + } + else if (*cont == 'e' || *cont == 'E') + { + //cont = pickup_exponent(&exp,cont+1); + if (cont == NULL) return(NULL); + } + else if (*cont == '+' || *cont == '/' || *cont == ' ') + { + // ignore + } + + else if (*cont == '\0') + { + // NULL end + + /* ここの条件は collada の仕様に合わせたもの。 + * 自前の blender script から吐き出される xml形式では、 + * 文字の終わりをNULLでは判断せず、エラー処理としていた + * ので必要ではなかった。よって、自前 blender script の + * xml形式の時、途中で NULL が来た場合、エラー処理され + * なくなる。NULL を返すので、呼び出し側で判断する + */ + + *index = sign * (val_int + val_dec) * exp; + return(NULL); + } + else + { + fprintf(stderr,"Pick up float failed : %c(%d)\n",*cont,*cont); + return(NULL); + } + } + + *index = sign * (val_int + val_dec) * exp; + cont++; + return(cont); +} + + + +static void +xml_walk(xmlNodePtr cur, struct collada_state *s, LIST_P list) +{ + + 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 (!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); + + for (int i=0; vcont!=NULL; i++) { + /* store vcount list */ + vcont = pickup_float(vcont, s->vcount+i); + } + + } else if (!xmlStrcmp(cur->name, (xmlChar*)"p")) { + + char *pcont = (char*)xmlNodeGetContent(cur); + + int vcsum = 0; + for (int i=0; i < s->polylist_count; i++) { + vcsum += s->vcount[i]; + } + + s->pcount = (float*)malloc(sizeof(float)*vcsum); + + for (int i=0; pcont != NULL; i++) { + pcont = pickup_float(pcont, s->pcount+i); + } + + int vertexp[vcsum]; + + for (int i=0; i<vcsum ;i++) { + vertexp[i]=0; + } + + float *vertex_table = (float*)malloc(sizeof(float)*s->vertex_float->count) ; + float *normal_table = (float*)malloc(sizeof(float)*s->normal_float->count) ; + float *texcoord_table = (float*)malloc(sizeof(float)*s->texcoord_float->count) ; + + /* p separate vertex position and nomal position. */ + for (int i=0, j=0; i < s->polylist_count; i+=2,j++) { + vertexp[j] = (int)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; vertexp[i];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]]; + } + } + /*TEST*/ + for (int i=0; i<vcsum; i++) { + //printf("normal_table= %f\n", normal_table[i]); + printf("vertexp= %d\n", vertexp[i]); + } + + free(vertex_table); + free(normal_table); + free(texcoord_table); + + /* got out of polylist */ + s->polylist = 0; + in_polylist = 0; + + } else if (!xmlStrcmp(cur->name, (xmlChar*)"float_array")) { + + 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); + + char *cont =(char*)xmlNodeGetContent(cur); + //const char *id = get_property("id", cur); + //int count = atoi(get_property("count", cur)); + + printf("id:%s count:%d cont:%s\n", id, count, cont); + /* 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); + + } + + for (cur=cur->children; cur; cur=cur->next){ + xml_walk(cur, s, list); + } +} + +void +init_list(LIST_P list) { + list->first = NULL; + list->end = NULL; +} + + +int main(int argc, char *argv[]) { + + const char *xmlColladafile = argv[1]; + + /*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 0; + } + + /* node analyze */ + struct collada_state s; + + LIST list; + + for(cur=cur->children; cur; cur=cur->next){ + init_list(&list); + xml_walk(cur,&s, &list); + } + + //printlist(list); + xmlFreeDoc(doc); + + return 0; + +}