// obj2dsm.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include #include #include #include #define PI (3.1415926535) #define RAD (PI/180.0f) #define ARGSMAX (32) #define LINEMAX (4096) #define TOKENMAX (2048) #define VERTEXMAX (63) class Vector4 { public: float v[4]; }; class Face3 { public: int i[3][3]; int c[3]; int ce[3]; int cc,cn,ca; int sl; Vector4 fn; Face3(){int j,k;for(j=0;j<3;j++){for(k=0;k<3;k++){i[j][k]=0;}c[j]=-1;} cc=0;cn=sl=ca=-1; fn.v[0]=fn.v[1]=fn.v[2]=fn.v[3]=0.0f;} }; class FileObject { int gvn; Vector4* gv; int tvn; Vector4* tv; int nvn; Vector4* nv; int fn; Face3* f; void CalcNorm(); int WriteStrip(FILE *fp,int ct,int fi,int an,int si,Vector4* v,int ind); void Striper(); int SStrip(int ct,int fn,int an,int si); int SetStrip(int ct,int fn,int an,int si); public: bool Load(char* strFileName); void Export(FILE *fp); FileObject(){gvn=tvn=nvn=fn=0;gv=tv=nv=NULL;f=NULL;} ~FileObject(){gvn=tvn=nvn=fn=0;delete gv;delete tv;delete nv;delete f;} }; char helpfile[]="\ WaveFront OBJファイルをPS2 dsm形式に変換します。\n\ obj2dsm [-S][-P][-W][-N オブジェクト名][-C 頂点色][-A スムージング角度] 入力ファイル [-O 出力ファイル]\n\ 入力ファイル .OBJファイル(OBJファイル)を指定します。\n\ 出力ファイル 作成するファイル名を指定します(省略した場合はa.dsm)。\n"; char header[]="\ /* Making by obj2dsm\n\ */\n\ .data\n\ .DmaPackVif 0\n\ \n\ .include \"vumacros.h\"\n\ .global %s_start\n\ \n\ ;-----------------------------------------------\n\ %s_start:\n\ DMAcnt *\n"; char vifcodet[]="\ unpack[r] 4,4, V4_32, 0, *\n\ iwzyx 0x0, 0x412, 0x300dc000, 0x8%03x\n\ .EndUnpack\n\ \n\ unpack[r] 4,4, V4_32, 1, *\n"; char vifcodes[]="\ unpack[r] 4,4, V4_32, 0, *\n\ iwzyx 0x0, 0x412, 0x300e4000, 0x8%03x\n\ .EndUnpack\n\ \n\ unpack[r] 4,4, V4_32, 1, *\n"; char vifcodesw[]="\ unpack[r] 4,4, V4_32, 0, *\n\ iwzyx 0x0, 0x412, 0x300d4000, 0x8%03x\n\ .EndUnpack\n\ \n\ unpack[r] 4,4, V4_32, 1, *\n"; char vifend[]="\ .EndUnpack\n\ MSCNT\n\n"; char dmaend[]="\ .EndDmaData\n\ \n\ DMAend\n"; float gSman=(float)(45.0f*RAD); Vector4 vcolor={127.0f,127.0f,127.0f,127.0f}; int gStripFlag=0; int gPrintFlag=0; int gColorFlag=0; int gWireFlag=0; int gMaxStripLen=0; char myobject[LINEMAX]="My_torus"; static int sScenesn=0; static FileObject *sSceneList[ARGSMAX]; static char sOutName[FILENAME_MAX]; static Vector4 normalize(Vector4& v) { Vector4 nv; float mg=(float)sqrt(v.v[0]*v.v[0]+v.v[1]*v.v[1]+v.v[2]*v.v[2]); nv.v[0]=v.v[0]/mg;nv.v[1]=v.v[1]/mg;nv.v[2]=v.v[2]/mg; return nv; } #define FUZZY (0.00001) static int cmpVector4(Vector4& v1,Vector4& v2) { if((v1.v[0]>=(v2.v[0]-FUZZY) && v1.v[0]<=(v2.v[0]+FUZZY)) && (v1.v[1]>=(v2.v[1]-FUZZY) && v1.v[1]<=(v2.v[1]+FUZZY)) && (v1.v[2]>=(v2.v[2]-FUZZY) && v1.v[2]<=(v2.v[2]+FUZZY)) && (v1.v[3]>=(v2.v[3]-FUZZY) && v1.v[3]<=(v2.v[3]+FUZZY))) return 0; return -1; } static int cmpind(int *a,int *b) { int i; for(i=0;i<3;i++) { if(a[i]!=b[i]) return -1; } return 0; } int parse(char* s,char** v) { int c=0; while(1) { while(*s==' '||*s=='\t') s++; if(*s && *s!='\n' && *s!='\r') v[c++]=s; if(*s=='"'){ v[c-1]+=1; s++; while(*s && *s!='"' && *s!='\n' && *s!='\r') s++; if(*s=='"') *s++='\0'; }else while(*s && *s!=' ' && *s!='\t' && *s!='\n' && *s!='\r') s++; if(*s=='\0' || *s=='\n' || *s=='\r') { *s='\0'; break; }else *s++='\0'; } v[c]=NULL; return c; } static int parsef(char* s,char** v) { int c=0,f=0; while(*s) { if(*s!='/' && f==0) { v[c++]=s; f=1; }else if(*s=='/' && f==1){ *s='\0'; f=0; } s++; } return c; } static void setv(int n,char *t[],Vector4 *v) { for(int i=0;i<4;i++) { if(n>i+1) v->v[i]=(float)atof(t[i+1]); else v->v[i]=0.0f; } } static void setf(int n,char *t[],Face3 *f) { char *ti[TOKENMAX]; for(int i=0;i<3;i++) { if(n>i+1){ int in=parsef(t[i+1],ti); for(int j=0;j<3;j++) { if(in>j) { if(ti[j][0]!='\0') f->i[i][j]=atoi(ti[j]); else f->i[i][j]=0; }else{ f->i[i][j]=0; } } }else f->i[i][0]=f->i[i][1]=f->i[i][2]=0; } } static int sat3(int n) {return (n+3)%3;} static Vector4 calcnormal(Vector4 &v0,Vector4 &v1,Vector4 &v2) { Vector4 nm; nm.v[0]=(v1.v[1]-v0.v[1])*(v2.v[2]-v1.v[2])-(v1.v[2]-v0.v[2])*(v2.v[1]-v1.v[1]); nm.v[1]=(v1.v[2]-v0.v[2])*(v2.v[0]-v1.v[0])-(v1.v[0]-v0.v[0])*(v2.v[2]-v1.v[2]); nm.v[2]=(v1.v[0]-v0.v[0])*(v2.v[1]-v1.v[1])-(v1.v[1]-v0.v[1])*(v2.v[0]-v1.v[0]); nm=normalize(nm); return nm; } static float calcangle(Vector4 &v0,Vector4 &v1) { double dd; dd=v1.v[0]*v0.v[0]+v1.v[1]*v0.v[1]+v1.v[2]*v0.v[2]; return((float)acos(dd)); } bool FileObject::Load(char* strFileName) { FILE *fp; int tn,i,j; char line[LINEMAX],*token[TOKENMAX]; if((fp=fopen(strFileName,"rt"))!=NULL) { while(fgets(line,LINEMAX,fp)!=NULL) { if(line[0]!='#') { tn=parse(line,token); if(tn>0) { if(strcmp(token[0],"v")==0) gvn++; else if(strcmp(token[0],"vt")==0) tvn++; else if(strcmp(token[0],"vn")==0) nvn++; else if(strcmp(token[0],"f")==0) fn++; } } } fseek(fp,0,SEEK_SET); int *gvm,*tvm,*nvm; int gvi=0,tvi=0,nvi=0,fi=0; gvm=new int[gvn]; tvm=new int[tvn]; nvm=new int[nvn]; gv=new Vector4[gvn]; tv=new Vector4[tvn]; nv=new Vector4[nvn]; f=new Face3[fn]; while(fgets(line,LINEMAX,fp)!=NULL) { if(line[0]!='#') { tn=parse(line,token); if(tn>0) { if(strcmp(token[0],"v")==0 && gvi0) for(i=0;i=0) continue; for(k=0;kgSman) break; total.v[0]+=f[np].fn.v[0]; total.v[1]+=f[np].fn.v[1]; total.v[2]+=f[np].fn.v[2]; pp=np; np=f[pp].c[sat3(eg-1)]; eg=f[pp].ce[sat3(eg-1)]; } int ppp=i; int npp=f[i].c[sat3(j+1)]; eg=f[i].ce[sat3(j+1)]; while(1) { if(npp<0 || npp==pp) break; if(calcangle(f[ppp].fn,f[npp].fn)>gSman) break; total.v[0]+=f[npp].fn.v[0]; total.v[1]+=f[npp].fn.v[1]; total.v[2]+=f[npp].fn.v[2]; ppp=npp; npp=f[ppp].c[sat3(eg+1)]; eg=f[ppp].ce[sat3(eg+1)]; } nv[i*3+j]=normalize(total); } } } int FileObject::SStrip(int ct,int fn,int an,int si) { int n; if(fn<0 || f[fn].cn>=0 || ct>(VERTEXMAX-3)) return 0; f[fn].cn=0; n=SStrip(ct+1,f[fn].c[sat3(an)],sat3(f[fn].ce[sat3(an)]+si),si*-1); f[fn].cn=-1; return n+1; } int FileObject::SetStrip(int ct,int fn,int an,int si) { int n; if(fn<0 || f[fn].cn>=0 || ct>(VERTEXMAX-3)) return 0; f[fn].cn=ct; f[fn].ca=an; if((n=SetStrip(ct+1,f[fn].c[sat3(an)],sat3(f[fn].ce[sat3(an)]+si),si*-1))==0) f[fn].ca=-1; return n+1; } void FileObject::Striper() { int i,j,k,l,n; for(i=0;i=0) break; for(k=0;k=0) f[i].cc++; } } for(i=0;i=0)) { for(k=0;k<3;k++) { int tn; if((tn=SStrip(0,j,k,-1))>maxl) { maxl=tn;maxf=j;maxa=k; } } } } if(maxf<0) break; if((f[maxf].sl=SetStrip(0,maxf,maxa,-1))>gMaxStripLen) gMaxStripLen=f[maxf].sl; }} } static void wvector(FILE *fp,float a,float b,float c,float d) { fprintf(fp,"fxyzw %.6f, %.6f, %.6f, %.6f\n",a,b,c,d); } int FileObject::WriteStrip(FILE *fp,int ct,int fi,int an,int si,Vector4* v,int ind) { if(f[fi].cn!=ct) return 0; if(si<0) wvector(fp,v[f[fi].i[sat3(an)][ind]].v[0],v[f[fi].i[sat3(an)][ind]].v[1],v[f[fi].i[sat3(an)][ind]].v[2],1.0f); else wvector(fp,v[f[fi].i[sat3(an-1)][ind]].v[0],v[f[fi].i[sat3(an-1)][ind]].v[1],v[f[fi].i[sat3(an-1)][ind]].v[2],1.0f); if(f[fi].ca<0) return 0; return WriteStrip(fp,ct+1,f[fi].c[an],sat3(f[fi].ce[an]+si),si*-1,v,ind)+1; } #define RCOLORN 14 Vector4 rcolor[RCOLORN]={ {127.0f,000.0f,000.0f,127.0f} ,{000.0f,127.0f,000.0f,127.0f} ,{127.0f,127.0f,000.0f,127.0f} ,{000.0f,000.0f,127.0f,127.0f} ,{127.0f,000.0f,127.0f,127.0f} ,{000.0f,127.0f,127.0f,127.0f} ,{127.0f,127.0f,127.0f,127.0f} ,{255.0f,000.0f,000.0f,127.0f} ,{000.0f,255.0f,000.0f,127.0f} ,{255.0f,255.0f,000.0f,127.0f} ,{000.0f,000.0f,255.0f,127.0f} ,{255.0f,000.0f,255.0f,127.0f} ,{000.0f,255.0f,255.0f,127.0f} ,{255.0f,255.0f,255.0f,127.0f}}; void FileObject::Export(FILE *fp) { int i,j,sn,vertn,ln; if(gPrintFlag) { for(vertn=i=1;i0;ln--) { for(i=0;i0) continue; pn+=ln;vn+=ln+2;sn++; if(maxln) min=ln; if(gWireFlag) fprintf(fp,vifcodesw,ln+2); else fprintf(fp,vifcodes,ln+2); fprintf(fp,";-- position --\n"); wvector(fp,gv[f[i].i[sat3(f[i].ca-2)][0]].v[0],gv[f[i].i[sat3(f[i].ca-2)][0]].v[1],gv[f[i].i[sat3(f[i].ca-2)][0]].v[2],1.0f); wvector(fp,gv[f[i].i[sat3(f[i].ca-1)][0]].v[0],gv[f[i].i[sat3(f[i].ca-1)][0]].v[1],gv[f[i].i[sat3(f[i].ca-1)][0]].v[2],1.0f); WriteStrip(fp,0,i,f[i].ca,-1,gv,0); fprintf(fp,";-- normal --\n"); wvector(fp,nv[f[i].i[sat3(f[i].ca-2)][2]].v[0],nv[f[i].i[sat3(f[i].ca-2)][2]].v[1],nv[f[i].i[sat3(f[i].ca-2)][2]].v[2],1.0f); wvector(fp,nv[f[i].i[sat3(f[i].ca-1)][2]].v[0],nv[f[i].i[sat3(f[i].ca-1)][2]].v[1],nv[f[i].i[sat3(f[i].ca-1)][2]].v[2],1.0f); WriteStrip(fp,0,i,f[i].ca,-1,nv,2); fprintf(fp,";-- color ---\n"); for(j=0;jfn*3)?fn*3-bt:VERTEXMAX; fprintf(fp,vifcodet,pc); fprintf(fp,";-- position --\n"); for(i=0;i=argc) break; strcpy(sOutName,argv[i]); break; case 'N': i++; if(i>=argc) break; strcpy(myobject,argv[i]); break; case 'A': i++; if(i>=argc) break; gSman=(float)(atof(argv[i])*RAD); break; case 'C': for(int j=0;j<4;j++) { i++; if(i>=argc) break; vcolor.v[j]=(float)atof(argv[i]); } break; } }else{ sSceneList[sScenesn]=new FileObject(); if(sSceneList[sScenesn]->Load(argv[i])) { sScenesn++; }else{ delete(sSceneList[sScenesn]); } } } if(sScenesn>0 && (dsmfile=fopen(sOutName,"wb"))!=NULL) { printf("makefile=%s\n",sOutName); for(i=0;iExport(dsmfile); fclose(dsmfile); } return 0; }