/** ******************************************************************************* @file /gui/model/reader_ase.cpp @brief Nizkourovnova knihovna pro nacitani modelu z formatu ASE popis formatu: http://www.solosnake.com/main/ase.htm http://www.unrealwiki.com/wiki/ASE_File_Format @author Vajicek @version 0.1 ******************************************************************************/ #include "gui/model/reader_ase.h" #include "common/Log.h" #include "common/types.h" #include "common/compatibility.h" #include "common/mm.h" #include #include #include #include using namespace std; // //main #define MAX_ASCIIEXPORT "*3DSMAX_ASCIIEXPORT" #define COMMENT "*COMMENT" #define SCENE "*SCENE" #define MATERIAL_LIST "*MATERIAL_LIST" #define GEOMOBJECT "*GEOMOBJECT" #define LIGHTOBJECT "*LIGHTOBJECT" #define CAMERAOBJECT "*CAMERAOBJECT" //scena #define SCENE_FILENAME "*SCENE_FILENAME" #define SCENE_FIRSTFRAME "*SCENE_FIRSTFRAME" #define SCENE_LASTFRAME "*SCENE_LASTFRAME" #define SCENE_FRAMESPEED "*SCENE_FRAMESPEED" #define SCENE_TICKSPERFRAME "*SCENE_TICKSPERFRAME" #define SCENE_BACKGROUND_STATIC "*SCENE_BACKGROUND_STATIC" #define SCENE_AMBIENT_STATIC "*SCENE_AMBIENT_STATIC" //material #define MATERIAL_COUNT "*MATERIAL_COUNT" #define MATERIAL "*MATERIAL" #define MATERIAL_NAME "*MATERIAL_NAME" #define MATERIAL_CLASS "*MATERIAL_CLASS" #define MATERIAL_AMBIENT "*MATERIAL_AMBIENT" #define SCENE_AMBIENT_STATIC "*SCENE_AMBIENT_STATIC" #define MATERIAL_DIFFUSE "*MATERIAL_DIFFUSE" #define MATERIAL_SPECULAR "*MATERIAL_SPECULAR" #define MATERIAL_SHINE "*MATERIAL_SHINE" #define MATERIAL_SHINESTRENGTH "*MATERIAL_SHINESTRENGTH" #define MATERIAL_TRANSPARENCY "*MATERIAL_TRANSPARENCY" #define MATERIAL_WIRESIZE "*MATERIAL_WIRESIZE" #define NUMSUBMTLS "*NUMSUBMTLS" #define SUBMATERIAL "*SUBMATERIAL" #define MATERIAL_SHADING "*MATERIAL_SHADING" #define MATERIAL_XP_FALLOFF "*MATERIAL_XP_FALLOFF" #define MATERIAL_SELFILLUM "*MATERIAL_SELFILLUM" #define MATERIAL_FALLOFF "*MATERIAL_FALLOFF" #define MATERIAL_XP_TYPE "*MATERIAL_XP_TYPE" #define MAP_DIFFUSE "*MAP_DIFFUSE" //mapping #define MAP_NAME "*MAP_NAME" #define MAP_CLASS "*MAP_CLASS" #define MAP_SUBNO "*MAP_SUBNO" #define MAP_AMOUNT "*MAP_AMOUNT" #define BITMAP "*BITMAP" #define MAP_TYPE "*MAP_TYPE" #define UVW_U_OFFSET "*UVW_U_OFFSET" #define UVW_V_OFFSET "*UVW_V_OFFSET" #define UVW_U_TILING "*UVW_U_TILING" #define UVW_V_TILING "*UVW_V_TILING" #define UVW_ANGLE "*UVW_ANGLE" #define UVW_BLUR "*UVW_BLUR" #define UVW_BLUR_OFFSET "*UVW_BLUR_OFFSET" #define UVW_NOUSE_AMT "*UVW_NOUSE_AMT" #define UVW_NOISE_SIZE "*UVW_NOISE_SIZE" #define UVW_NOISE_LEVEL "*UVW_NOISE_LEVEL" #define UVW_NOISE_PHASE "*UVW_NOISE_PHASE" #define BITMAP_FILTER "*BITMAP_FILTER" //geometry #define NODE_NAME "*NODE_NAME" #define NODE_PARENT "*NODE_PARENT" #define NODE_TM "*NODE_TM" #define PROP_MOTIONBLUR "*PROP_MOTIONBLUR" #define PROP_CASTSHADOW "*PROP_CASTSHADOW" #define PROP_RECVSHADOW "*PROP_RECVSHADOW" #define TM_ANIMATION "*TM_ANIMATION" #define MATERIAL_REF "*MATERIAL_REF" //animation #define CONTROL_ROT_TRACK "*CONTROL_ROT_TRACK" #define CONTROL_ROT_SAMPLE "*CONTROL_ROT_SAMPLE" #define CONTROL_POS_TRACK "*CONTROL_POS_TRACK" #define CONTROL_POS_SAMPLE "*CONTROL_POS_SAMPLE" //node tranformation #define NODE_NAME "*NODE_NAME" #define INHERIT_POS "*INHERIT_POS" #define INHERIT_ROT "*INHERIT_ROT" #define INHERIT_SCL "*INHERIT_SCL" #define TM_ROW0 "*TM_ROW0" #define TM_ROW1 "*TM_ROW1" #define TM_ROW2 "*TM_ROW2" #define TM_ROW3 "*TM_ROW3" #define TM_POS "*TM_POS" #define TM_ROTAXIS "*TM_ROTAXIS" #define TM_ROTANGLE "*TM_ROTANGLE" #define TM_SCALE "*TM_SCALE" #define TM_SCALEAXIS "*TM_SCALEAXIS" #define TM_SCALEAXISANG "*TM_SCALEAXISANG" #define TIMEVALUE "*TIMEVALUE" //mesh #define MESH_NUMVERTEX "*MESH_NUMVERTEX" #define MESH_VERTEX_LIST "*MESH_VERTEX_LIST" #define MESH_NUMFACES "*MESH_NUMFACES" #define MESH_FACE_LIST "*MESH_FACE_LIST" #define MESH_NUMTVERTEX "*MESH_NUMTVERTEX" #define MESH_TVERTLIST "*MESH_TVERTLIST" #define MESH_NUMTVFACES "*MESH_NUMTVFACES" #define MESH_TFACELIST "*MESH_TFACELIST" #define MESH_MAPPINGCHANNEL "*MESH_MAPPINGCHANNEL" #define MESH_NUMCVERTEX "*MESH_NUMCVERTEX" #define MESH_CVERTLIST "*MESH_CVERTLIST" #define MESH_NUMCVFACES "*MESH_NUMCVFACES" #define MESH_CFACELIST "*MESH_CFACELIST" #define MESH_CFACE "*MESH_CFACE" #define MESH_VERTCOL "*MESH_VERTCOL" #define MESH_NORMALS "*MESH_NORMALS" #define MESH_VERTEXNORMAL "*MESH_VERTEXNORMAL" #define MESH_FACENORMAL "*MESH_FACENORMAL" #define MESH "*MESH" #define MESH_VERTEX "*MESH_VERTEX" #define MESH_FACE "*MESH_FACE" #define MESH_FACEMAPLIST "*MESH_FACEMAPLIST" #define MESH_TVERT "*MESH_TVERT" #define MESH_TFACE "*MESH_TFACE" #define LPARENTEHESIS "{" #define RPARENTEHESIS "}" // #define TOKEN_BUFF_SIZE 20 #define BUFF_SIZE 255 #define SMALL_BUFF_SIZE 64 // #define ASE_FRGB(r,g,b) (((int)(r*255)<<16) | ((int)(g*255)<<8) | (int)(b*255)) #define LOGGER //Log.LogMsg //#define THROW(a,b) printf(b); /////////////////////////////////////////////////////////////////////////////// namespace gui{ /** Stavova struktura pro nacitani a parsovani ASE souboru. */ struct ASEFile { FILE* f; int line; int pos; int total_len; char buff[BUFF_SIZE]; char* tok[TOKEN_BUFF_SIZE]; int tokc; // char read_geometry; char read_animation; char read_lod; char read_hierarchy; char read_meshonly; //konverze char conv_textureupdown; char conv_degree; // float lod_dist; // P3F nt_pos; P3F nt_rot; float nt_rotang; P3F nt_scl; MX4 object_transform; //W1->O1 MX4 world_transform; //O1->W1 T3DObject* module_geometry;//pouhy odkaz na prave nacitany fajl TKeyframer* module_keyframer; // int scene_firstframe; int scene_lastframe; int scene_framespeed; int scene_ticksperframe; }; /** Struktura pro nabufferovani face pred prevodem do vnitrni reprezentace. */ struct ase_face{ int vertex[3]; P3F vnormal[3]; int color[3]; int tvert[3]; int submat; }; /** Reprezentace barvy. */ struct ase_vertcolor{ float grb[3]; }; /** Mapovani textur. */ struct ase_tvert{ float u,v; }; void tokenize(char* str,char* del,int* num,char **tokens,int quote='"'){ int p=0; *num=0; int isquoted=0; while(1){ //preskoc for(;str[p];p++) if(!strchr(del,str[p]))break; isquoted=(str[p]==quote); if(!str[p])return; if(isquoted)p++; tokens[*num]=str+p; (*num)++; if(*num >= TOKEN_BUFF_SIZE ) THROW(E_8K_ASE_READER, "tokenize(): token buffer overflow!"); //preskoc for(;str[p];p++) if(isquoted){ if(str[p]==quote)break; } else if(strchr(del,str[p]))break; str[p]=0; p++; isquoted=0; } } char* ReadASELine(ASEFile* ase) { ase->line++; char* res = fgets(ase->buff,BUFF_SIZE,ase->f); ase->pos=ftell(ase->f); tokenize(ase->buff, " \n\t", &(ase->tokc), ase->tok); return res; } int CloseASEFile(ASEFile* ase){ if(ase->f) fclose(ase->f); return 0; } char* _GetToken(ASEFile* ase, int ord){ if( ord>=ase->tokc || ord<0 ) THROW(E_8K_ASE_READER, "getToken(): token not exists"); return ase->tok[ord]; } char* _GetTokenError(){ THROW(E_8K_ASE_READER, "getToken(): token not exists"); return NULL; } ///kontrola rozsahu //#define GetToken _GetToken #define GetToken(_ase,_ord) ( ( (_ord>=(_ase)->tokc)||(_ord<0) )?_GetTokenError():(_ase)->tok[_ord] ) int OpenASEFile(ASEFile* ase,char*file) { ase->f=fopen(file,"r"); if(!ase->f){ THROW(E_8K_ASE_READER, "OpenASEFile(): File not found"); } ase->pos=0; ase->line=0; fseek(ase->f,0,SEEK_END); ase->total_len = ftell(ase->f); fseek(ase->f,0,SEEK_SET); ase->tokc = 0; // SetIdentityMX4(ase->world_transform); SetIdentityMX4(ase->object_transform); ase->module_geometry = NULL; ase->module_keyframer = NULL; // return 0; } /////////////////////////////////////////////////////////////////////////////// ///READ UNSUPPORTED VALUE void read_unsupported_value(char** tok,int c){ LOGGER("unsupported value: "); for(int i=0;itokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase,0)); else read_unsupported_value(ase->tok,ase->tokc); } //nedostal se k zavorce, FAIL THROW(E_8K_ASE_READER, "read_unsupported_list(): RPARENTEHESIS not found!"); } ///SKIP LIST void skip_list(ASEFile* ase,char* ln){ // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase,0),RPARENTEHESIS)) return; //OK else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) skip_list(ase,GetToken(ase, 0)); else skip_value(ase->tok,ase->tokc); } //FAIL THROW(E_8K_ASE_READER, "skip_list(): RPARENTEHESIS not found!"); } /**READ VERTEX LIST ASE_err = -4 //spatny pocet vrcholu */ void read_vertex_list(ASEFile* ase, TVertex* vertexbuff, int vertexbuffer_c){ float v[4]; int i=0; // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return; // //nacteni vrcholu else if(!stricmp(GetToken(ase, 0),MESH_VERTEX)) { if(i>=vertexbuffer_c) THROW(E_8K_ASE_READER, "read_vertex_list(): Wrong Vertex Count"); v[0] = (float)atof(GetToken(ase, 2)); v[1] = (float)atof(GetToken(ase, 3)); v[2] = (float)atof(GetToken(ase, 4)); v[3] = 1; //transformace do lokalnich souradnic if(ase->read_hierarchy){ float w[4]; //transformace z world space do obj space ApplyVectorMX4(v,ase->object_transform,w); vertexbuff[i].position.x=(float)(w[0]/w[3]); vertexbuff[i].position.y=(float)(w[1]/w[3]); vertexbuff[i].position.z=(float)(w[2]/w[3]); } else { vertexbuff[i].position.x=(float)v[0]; vertexbuff[i].position.y=(float)v[1]; vertexbuff[i].position.z=(float)v[2]; } i++; } } //FAIL THROW(E_8K_ASE_READER, "read_vertex_list(): RPARENTEHESIS not found!"); } void read_vertex_colors(ASEFile* ase, ase_vertcolor* colorbuffer, int colorbuffer_c){ int indx; float r,g,b; // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return; // //nacteni normaly //*MESH_VERTCOL 0 1.0000 1.0000 1.0000 else if(!stricmp(GetToken(ase, 0),MESH_VERTCOL)) { indx = atoi(GetToken(ase, 1)); r = (float)atof(GetToken(ase, 2)); g = (float)atof(GetToken(ase, 3)); b = (float)atof(GetToken(ase, 4)); if( indx < colorbuffer_c ){ colorbuffer[indx].grb[0] = r; colorbuffer[indx].grb[1] = g; colorbuffer[indx].grb[2] = b; } } } //FAIL THROW(E_8K_ASE_READER, "read_vertex_colors(): RPARENTEHESIS not found!"); } void read_face_colors(ASEFile* ase, ase_vertcolor* colorbuffer, ase_face* facebuffer){ /**/ int indx; int v1,v2,v3; // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return; // //nacteni normaly //*MESH_CFACE 0 110 111 112 else if(!stricmp(GetToken(ase, 0),MESH_CFACE)) { indx = atoi(GetToken(ase,1)); v1 = atoi(GetToken(ase, 2)); v2 = atoi(GetToken(ase, 3)); v3 = atoi(GetToken(ase, 4)); facebuffer[indx].color[0] = v1; facebuffer[indx].color[1] = v2; facebuffer[indx].color[2] = v3; } } //FAIL THROW(E_8K_ASE_READER, "read_face_colors(): RPARENTEHESIS not found!"); } void read_tvert_list(ASEFile* ase, ase_tvert* tvertbuff){ int i; float u, v, w; while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return; // //nacteni facu //*MESH_TVERT 35 1.0000 1.0000 0.0000 else if(!stricmp(GetToken(ase, 0),MESH_TVERT)){ i = atoi(GetToken(ase, 1)); u = (float)atof(GetToken(ase, 2)); v = (float)atof(GetToken(ase, 3)); w = (float)atof(GetToken(ase, 4)); tvertbuff[i].u = u; tvertbuff[i].v = v; if(ase->conv_textureupdown){ tvertbuff[i].v = 1 - tvertbuff[i].v; } } } //FAIL THROW(E_8K_ASE_READER, "read_tvert_list(): RPARENTEHESIS not found!"); } void read_tfaces_list(ASEFile* ase, ase_face* facebuffer){ int i, a, b, c; while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return; // //nacteni facu //*MESH_TFACE 0 8 9 10 else if(!stricmp(GetToken(ase, 0),MESH_TFACE)){ i = atoi(GetToken(ase, 1)); a = atoi(GetToken(ase, 2)); b = atoi(GetToken(ase, 3)); c = atoi(GetToken(ase, 4)); // facebuffer[i].tvert[0] = a; facebuffer[i].tvert[1] = b; facebuffer[i].tvert[2] = c; } } //FAIL THROW(E_8K_ASE_READER, "read_tfaces_list(): RPARENTEHESIS not found!"); } void read_normals_list(ASEFile* ase, ase_face* facebuff, int facebuffer_c){ int indx, findx, vindx; float norm[4]; // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return; // //nacteni normaly //*MESH_VERTEXNORMAL 95 0.0000 -0.0000 1.0000 else if(!stricmp(GetToken(ase, 0),MESH_VERTEXNORMAL)) { indx = atoi(GetToken(ase, 1)); norm[0] = (float)atof(GetToken(ase, 2)); norm[1] = (float)atof(GetToken(ase, 3)); norm[2] = (float)atof(GetToken(ase, 4)); norm[3] = 1; vindx = 0; while( (vindx < 3) && (facebuff[findx].vertex[vindx] != indx) ) vindx++; //transformace do globalnich souradnic, pouziva se? if(!ase->read_hierarchy){ float w[4]; ApplyVectorMX4(norm,ase->object_transform,w); facebuff[findx].vnormal[vindx].x = (float)(w[0]/w[3]); facebuff[findx].vnormal[vindx].y = (float)(w[1]/w[3]); facebuff[findx].vnormal[vindx].z = (float)(w[2]/w[3]); } else /**/ { if( vindx < 3 ){ facebuff[findx].vnormal[vindx].x = (float)norm[0]; facebuff[findx].vnormal[vindx].y = (float)norm[1]; facebuff[findx].vnormal[vindx].z = (float)norm[2]; } } } //*MESH_FACENORMAL 166 0.0000 -0.0000 -1.0000 else if(!stricmp(GetToken(ase, 0),MESH_FACENORMAL)){ findx = atoi(GetToken(ase, 1)); } } //FAIL THROW(E_8K_ASE_READER, "read_normals_list(): RPARENTEHESIS not found!"); } /**READ FACE LIST ASE_err = -4 //spatny pocet vrcholu @param ase Soubor. @param facebuff Pole facu. @param facebuffer_c Pocet facu. */ void read_face_list(ASEFile* ase, ase_face* facebuff, int facebuffer_c){ int a,b,c,sm,ind; // // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return; // //nacteni facu // poradi 1.vr 2.vr 3.vr 1.or 2.or 3.or //*MESH_FACE 0: A: 0 B: 2 C: 3 AB: 1 BC: 1 CA: 0 *MESH_SMOOTHING 2 *MESH_MTLID 1 else if(!stricmp(GetToken(ase, 0),MESH_FACE)){ ind=atoi(GetToken(ase, 1)); a=atoi(GetToken(ase, 3)); b=atoi(GetToken(ase, 5)); c=atoi(GetToken(ase, 7)); sm=atoi(GetToken(ase, 16)); facebuff[ind].vertex[0] = a; facebuff[ind].vertex[1] = b; facebuff[ind].vertex[2] = c; facebuff[ind].submat = sm; } } //FAIL THROW(E_8K_ASE_READER, "read_face_list(): RPARENTEHESIS not found!"); } //READ NODE_TM void read_node_tm_list(ASEFile* ase){ // MX4 mk; SetIdentityMX4(mk); // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),INHERIT_POS)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),INHERIT_ROT)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),INHERIT_SCL)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),TM_ROW0)){ mk[0]=(float)atof(GetToken(ase, 1)); mk[1]=(float)atof(GetToken(ase, 2)); mk[2]=(float)atof(GetToken(ase, 3)); } else if(!stricmp(GetToken(ase, 0),TM_ROW1)){ mk[4]=(float)atof(GetToken(ase, 1)); mk[5]=(float)atof(GetToken(ase, 2)); mk[6]=(float)atof(GetToken(ase, 3)); } else if(!stricmp(GetToken(ase, 0),TM_ROW2)){ mk[8]=(float)atof(GetToken(ase, 1)); mk[9]=(float)atof(GetToken(ase, 2)); mk[10]=(float)atof(GetToken(ase, 3)); } else if(!stricmp(GetToken(ase, 0),TM_ROW3)){ mk[12]=(float)atof(GetToken(ase, 1)); mk[13]=(float)atof(GetToken(ase, 2)); mk[14]=(float)atof(GetToken(ase, 3)); } else if(!stricmp(GetToken(ase, 0),TM_POS)){ ase->nt_pos.x=(float)atof(GetToken(ase, 1)); ase->nt_pos.y=(float)atof(GetToken(ase, 2)); ase->nt_pos.z=(float)atof(GetToken(ase, 3)); } else if(!stricmp(GetToken(ase, 0),TM_ROTAXIS)){ ase->nt_rot.x=(float)atof(GetToken(ase, 1)); ase->nt_rot.y=(float)atof(GetToken(ase, 2)); ase->nt_rot.z=(float)atof(GetToken(ase, 3)); } else if(!stricmp(GetToken(ase, 0),TM_ROTANGLE)){ ase->nt_rotang=(float)atof(GetToken(ase, 1)); } else if(!stricmp(GetToken(ase, 0),TM_SCALE)){ ase->nt_scl.x=(float)atof(GetToken(ase, 1)); ase->nt_scl.y=(float)atof(GetToken(ase, 2)); ase->nt_scl.z=(float)atof(GetToken(ase, 3)); } else if(!stricmp(GetToken(ase, 0),TM_SCALEAXIS)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),TM_SCALEAXISANG)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)){ //implicitni InverseMX4(ase->object_transform, mk); CopyMX4(ase->world_transform, mk); return; } else read_unsupported_value(ase->tok,ase->tokc); } //FAIL THROW(E_8K_ASE_READER, "read_node_tm_list(): RPARENTEHESIS not found!"); } ///READ MESH void read_mesh(ASEFile* ase, TMesh* mesh){ // TVertex* vertexbuff = NULL; int vertexbuffer_c = 0; ase_face* facebuffer = NULL; int facebuffer_c; ase_vertcolor* colorbuffer = NULL; int colorbuffer_c; ase_tvert* tvertbuff = NULL; int tvertbuff_c; // while(ReadASELine(ase)){ //SIZE OF VERTEX BUFFER if(!stricmp(GetToken(ase, 0),MESH_NUMVERTEX)){ vertexbuffer_c = atoi(GetToken(ase, 1)); if(vertexbuffer_c) vertexbuff = (TVertex*)KMemAlloc(sizeof(TVertex)*vertexbuffer_c ); } //READ VERTEXLIST TO VERTEX BUFFER else if(!stricmp(GetToken(ase, 0),MESH_VERTEX_LIST)){ read_vertex_list(ase, vertexbuff, vertexbuffer_c); } else if(!stricmp(GetToken(ase, 0),MESH_NUMFACES)){ facebuffer_c = atoi(GetToken(ase, 1)); if(facebuffer_c) facebuffer = (ase_face*)KMemAlloc(sizeof(ase_face)*facebuffer_c ); } //FACELIST else if(!stricmp(GetToken(ase, 0),MESH_FACE_LIST)){ read_face_list(ase, facebuffer, facebuffer_c); } //TEXTURES else if(!stricmp(GetToken(ase, 0),MESH_NUMTVERTEX)){ tvertbuff_c = atoi(GetToken(ase, 1)); if(tvertbuff_c) tvertbuff = (ase_tvert*)KMemAlloc(sizeof(ase_tvert)*tvertbuff_c ); } else if(!stricmp(GetToken(ase, 0),MESH_TVERTLIST)){ read_tvert_list(ase, tvertbuff); } else if(!stricmp(GetToken(ase, 0),MESH_NUMTVFACES)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),MESH_TFACELIST)){ read_tfaces_list(ase, facebuffer); } else if(!stricmp(GetToken(ase, 0),MESH_MAPPINGCHANNEL)){ read_unsupported_value(ase->tok,ase->tokc); } //COLORS else if(!stricmp(GetToken(ase, 0),MESH_NUMCVERTEX)){ colorbuffer_c = atoi(GetToken(ase, 1)); if(colorbuffer_c) colorbuffer = (ase_vertcolor*)KMemAlloc(sizeof(ase_vertcolor)*colorbuffer_c ); } else if(!stricmp(GetToken(ase, 0),MESH_CVERTLIST)){ read_vertex_colors(ase, colorbuffer, colorbuffer_c); } else if(!stricmp(GetToken(ase, 0),MESH_NUMCVFACES)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),MESH_CFACELIST)){ read_face_colors(ase, colorbuffer, facebuffer); } else if(!stricmp(GetToken(ase, 0),MESH_NORMALS)){ read_normals_list(ase, facebuffer, facebuffer_c); } else if(!stricmp(GetToken(ase, 0),MESH_FACEMAPLIST)){ read_unsupported_list(ase,GetToken(ase, 0)); } else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase, 0)); else if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)){ TPolygon* fe; TVertex *v1,*v; ase_face* af; ase_vertcolor* vc; ase_tvert *tv; //generate net for(int i = 0; i < facebuffer_c; i++){ af = facebuffer + i; //pridej polygon fe = AddPolygonToObject(ase->module_geometry, mesh); fe->submat = af->submat; //pridej vrcholy for(int j = 0; j < 3 ;j++){ v = vertexbuff + af->vertex[j]; v1 = AddVertexToObject(ase->module_geometry, 0,0,0); memcpy(v1, v, sizeof(TVertex)); v1->normal.x = af->vnormal[j].x; v1->normal.y = af->vnormal[j].y; v1->normal.z = af->vnormal[j].z; if(colorbuffer){ vc = colorbuffer + af->color[j]; v1->color = ASE_FRGB(vc->grb[0],vc->grb[1],vc->grb[2]); } if(tvertbuff){ tv = tvertbuff + af->tvert[j]; v1 -> texture.x = tv -> u; v1 -> texture.y = tv -> v; } } } if((facebuffer_c == 0) && (vertexbuffer_c != 0)) { //body netvori zadny utvar mesh->iFlag = MESHFLAG_POINTS_ONLY; fe = AddPolygonToObject(ase->module_geometry, mesh); for(int j = 0; j < vertexbuffer_c ;j++){ v = vertexbuff + j; v1 = AddVertexToObject(ase->module_geometry, 0,0,0); memcpy(v1, v, sizeof(TVertex)); } } if(colorbuffer) KMemFree(colorbuffer); if(facebuffer) KMemFree(facebuffer); if(vertexbuff) KMemFree(vertexbuff); if(tvertbuff) KMemFree(tvertbuff); return; } } //FAIL THROW(E_8K_ASE_READER, "read_mesh(): RPARENTEHESIS not found!"); } ///READ MATERIAL MAP TMaterialMap* read_map(ASEFile* ase, PMaterial mat){ assert(mat); TMaterialMap* mmap = AddMaterialMapToMaterial(mat); while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return mmap;//OK else if(!stricmp(GetToken(ase, 0),BITMAP)) mmap->bitmap_file = KInitString(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),UVW_U_OFFSET)) mmap->uvw_u_offset = (float)atof(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),UVW_V_OFFSET)) mmap->uvw_v_offset = (float)atof(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),UVW_U_TILING)) mmap->uvw_u_tiling = (float)atof(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),UVW_V_TILING)) mmap->uvw_v_tiling = (float)atof(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),UVW_ANGLE)) mmap->uvw_angle = (float)atof(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase, 0)); else read_unsupported_value(ase->tok,ase->tokc); } //FAIL THROW(E_8K_ASE_READER, "read_map(): RPARENTEHESIS not found!"); } ///READ MATERIAL void read_material(ASEFile* ase, TModel* m, PMaterial parent){ float r,g,b,s; PMaterial mat; assert(m); if(parent) mat = AddSubMaterialToMaterial(parent); else mat = m->addMaterialToModel(); // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return;//OK else if(!stricmp(GetToken(ase, 0),MATERIAL_NAME)) strcpy(mat->name, GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),MATERIAL_CLASS)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),MATERIAL_AMBIENT)){ r = (float)atof(GetToken(ase, 1)); g = (float)atof(GetToken(ase, 2)); b = (float)atof(GetToken(ase, 3)); mat->ambient.x = r; mat->ambient.y = g; mat->ambient.z = b; mat->ambient.u = 1; } else if(!stricmp(GetToken(ase, 0),MATERIAL_DIFFUSE)){ r = (float)atof(GetToken(ase, 1)); g = (float)atof(GetToken(ase, 2)); b = (float)atof(GetToken(ase, 3)); mat->diffuse.x = r; mat->diffuse.y = g; mat->diffuse.z = b; mat->diffuse.u = 1; } else if(!stricmp(GetToken(ase, 0),MATERIAL_SPECULAR)){ r = (float)atof(GetToken(ase, 1)); g = (float)atof(GetToken(ase, 2)); b = (float)atof(GetToken(ase, 3)); mat->specular.x = r; mat->specular.y = g; mat->specular.z = b; mat->specular.u = 1; } else if(!stricmp(GetToken(ase, 0),MATERIAL_SHINE)){ s = (float)atof(GetToken(ase, 1)); mat->shininess = s; } else if(!stricmp(GetToken(ase, 0),MATERIAL_SHINESTRENGTH)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),MATERIAL_TRANSPARENCY)) mat->transparency = (float)atof(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),MATERIAL_WIRESIZE)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),MATERIAL_SHADING)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),MATERIAL_XP_FALLOFF)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),MATERIAL_SELFILLUM)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),MATERIAL_XP_TYPE)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),SUBMATERIAL)) read_material(ase, m, mat); else if(!stricmp(GetToken(ase, 0),MAP_DIFFUSE)) read_map(ase, mat); else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase, 0)); else read_unsupported_value(ase->tok,ase->tokc); } //FAIL THROW(E_8K_ASE_READER, "read_material(): RPARENTEHESIS not found!"); } ///READ MATERIAL LIST void read_material_list(ASEFile* ase,TModel* m){ // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return;//OK else if(!stricmp(GetToken(ase, 0),MATERIAL_COUNT)) read_unsupported_value(ase->tok,ase->tokc); else if(!stricmp(GetToken(ase, 0),MATERIAL)) read_material(ase, m, NULL); else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase, 0)); else read_unsupported_value(ase->tok,ase->tokc); } //FAIL THROW(E_8K_ASE_READER, "read_material_list(): RPARENTEHESIS not found!"); } ///READ ANIMATION TRACK void read_animation(ASEFile* ase,TModel* m) { TKeyframer* kf = NULL; TMeshNode* mn = NULL; TAnim_object* aon=NULL; float v[4]; float tick_to_ms = 1000.0f / float(ase->scene_framespeed * ase->scene_ticksperframe) ; //najdi keyframer, zatim jakykoliv if(!ase->module_keyframer){ kf = m->addFramer(); kf->frame_per_sec = ase->scene_framespeed; kf->frames = ase->scene_lastframe; ase->module_keyframer = kf; } else kf = ase->module_keyframer; // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),NODE_NAME)){ char name[50]; strcpy(name,GetToken(ase, 1)); //najdi mesh if(!(mn = m->findMeshNode(name))) THROW(E_8K_ASE_READER, "read_animation(): mesh_nod not exists!"); aon=NULL; //najdi anim nod, nebo vytvor for( int i = 0; i < kf->anim_object_nodes_c; i++) { if(kf->anim_object_nodes[i].mesh == mn){ aon = kf->anim_object_nodes + i; break; } } // if(!aon) aon = AddFramerObjectNode(kf, mn); } //TODO scale,.. else if(!stricmp(GetToken(ase, 0),CONTROL_ROT_TRACK)){ TRot_track_sample* rot; int first = 1; P3F ax; float ang; QUATER q0; MX4 mr,mp,mm; // SetIdentityMX4(mr); while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),CONTROL_ROT_SAMPLE)){ FIRST: aon->rot_track = (TRot_track_sample*)KExtArrayRealloc( aon->rot_track, sizeof(TRot_track_sample), aon->rot_track_c + 1, aon->rot_track_c); rot = aon->rot_track + aon->rot_track_c; aon->rot_track_c ++; // rot->keyframe = ROUND( atoi(GetToken(ase, 1)) * tick_to_ms ); if( first && rot->keyframe ){ rot->keyframe = 0; ax.x = 0; ax.y = 0; ax.z = 0; ang = 0; } else{ ax.x = (float)atof(GetToken(ase, 2)); ax.y = (float)atof(GetToken(ase, 3)); ax.z = (float)atof(GetToken(ase, 4)); ang = -(float)atof(GetToken(ase, 5)); first=0; } // AATOMX(mp, ang, ax.x, ax.y, ax.z); MulMatrixMX4(mm,mr,mp); CopyMX4(mr,mm); MXTOQ(mm, &q0); QTOAA(&q0, &ax , &ang ); // rot->axis.x = (float)ax.x; rot->axis.y = (float)ax.y; rot->axis.z = (float)ax.z; rot->angle = (float)ang; // if(ase->conv_degree) rot->angle = (float)Rad2Deg(rot->angle); // if(first){ first=0; goto FIRST; } } else if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) break; }//while if(stricmp(GetToken(ase, 0),RPARENTEHESIS))//skoncilo jinak nez zavorkou, FAIL THROW(E_8K_ASE_READER, "read_animation() - CONTROL_ROT_TRACK: RPARENTEHESIS not found!"); } else if(!stricmp(GetToken(ase, 0),CONTROL_POS_TRACK)){ TPos_track_sample* pos; while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),CONTROL_POS_SAMPLE)){ aon->pos_track = (TPos_track_sample*)KExtArrayRealloc( aon->pos_track, sizeof(TPos_track_sample), aon->pos_track_c + 1, aon->pos_track_c); pos = aon->pos_track + aon->pos_track_c; aon->pos_track_c ++; pos->keyframe = ROUND( atoi(GetToken(ase, 1)) * tick_to_ms ); //souradnice lokalni vzhledem k predkovi v[0] = (float)atof(GetToken(ase, 2)); v[1] = (float)atof(GetToken(ase, 3)); v[2] = (float)atof(GetToken(ase, 4)); v[3] = 1; //transformace do lokalnich souradnic vzhledem k objektu w = l * a pos->position.x=(float)v[0]; pos->position.y=(float)v[1]; pos->position.z=(float)v[2]; } else if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) break; } if(stricmp(GetToken(ase, 0),RPARENTEHESIS))//skoncilo jinak nez zavorkou, FAIL THROW(E_8K_ASE_READER, "read_animation() - CONTROL_POS_TRACK: RPARENTEHESIS not found!"); } else if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return;//OK else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase, 0)); } //FAIL THROW(E_8K_ASE_READER, "read_animation(): RPARENTEHESIS not found!"); } /** cisty data: T3DObject* - reprezentuje jeden soubor? TMesh* - reprezentuje jeden geometry? -v ramci gemoetry se odkazuje relativne v tomto geometry... nevadilo by mesh si pamatuje zacatky v objektu -vsechny data budou v objektu, jinde budou odkazy -jeden geometryobjekt obsahuje jeden mesh -mesh = geometryobjekt -3dobjekt = jeden soubor ase -objekt je celek nacteny ze souboru.. vice objektu.. je vice kusu jednoho modeu nactenych z vice souboru nadstavba: TMeshNode* - spojuje jednotlivy geometry, resi matice prechodu k lokalnim souradnicim */ ///READ GEOM OBJECT void read_geom_object(ASEFile* ase,TModel* m){ //novy nod do hierarchie, novy mesh do objektu TMeshNode* mesh_nod = NULL; //hierarchie TMesh* mesh = NULL; //data //create geometry object if(ase->read_geometry && !ase->module_geometry){ ase->module_geometry = m->addGeometry(); if(ase->read_lod){ TLODLevel* lev = m->addLODLevel(ase->lod_dist); if(ase->read_meshonly) lev->object = ase->module_geometry; } } // if(ase->read_geometry){ mesh = AddMeshToObject(ase->module_geometry, MESHFLAG_TRINAGLES_ONLY); } //PREDPOKLAD: nejprve je JMENO, pak TRANSFORMACE a RODIC while(ReadASELine(ase)){ if(!stricmp(GetToken(ase, 0),NODE_NAME)){ //vytvor mesh nod if(ase->read_geometry){ mesh_nod = m->addMeshNodToModel(NULL); mesh_nod->mesh = ase->module_geometry->mesh_c-1; mesh_nod->obj = mesh->obj; strcpy(mesh_nod->name,GetToken(ase, 1)); } //najde uz ulozeny mesh else{ mesh_nod = m->findMeshNode(GetToken(ase, 1)); if(!mesh_nod)THROW(E_8K_ASE_READER, "read_geom_object() - mesh_node not exists!"); mesh = mesh_nod->obj->mesh + mesh_nod->mesh; } } //PARENT BINDING else if(!stricmp(GetToken(ase, 0),NODE_PARENT)){ if(ase->read_hierarchy && ase->read_geometry){//teprve rodic vytvari zaznam v hierarchii(protoze ho obsahuje) PMeshNode parent = m->findMeshNode(GetToken(ase, 1)); //vytvorit zaznam v hierarchii PMeshNode new_mesh_nod = m->addMeshNodToModel(parent); //zkopiruj obsah stareho do noveho, predpoklad: kopirovani je korektni new_mesh_nod->mesh = mesh_nod->mesh; new_mesh_nod->obj = mesh_nod->obj; strcpy(new_mesh_nod->name,mesh_nod->name); //odstaran stary m->removeMeshNodFromModel(mesh_nod); //aktualizuj mesh_nod = new_mesh_nod; } } //NODE TRANSFORMATIONS else if(!stricmp(GetToken(ase, 0),NODE_TM)){ //precte transformaci read_node_tm_list(ase); if(ase->read_hierarchy && ase->read_geometry){ //transformace mesh_nod->rotate.ang = (float)Rad2Deg(-ase->nt_rotang); CopyV3(mesh_nod->rotate.ax.p, ase->nt_rot.p); CopyV3(mesh_nod->translate.p, ase->nt_pos.p); CopyV3(mesh_nod->scale.p, ase->nt_scl.p); //globalni transformace CopyMX4(mesh_nod->global, ase->world_transform); CopyV3(mesh_nod->glob_scale.p, ase->nt_scl.p); //lokalni transformace if(ase->read_hierarchy && mesh_nod->parent){ MX4 mpi,lt1,lt2,sm,smi; //lokalni skalovani mesh_nod->scale.x = mesh_nod->scale.x/mesh_nod->parent->glob_scale.x; mesh_nod->scale.y = mesh_nod->scale.y/mesh_nod->parent->glob_scale.y; mesh_nod->scale.z = mesh_nod->scale.z/mesh_nod->parent->glob_scale.z; // InverseMX4( mpi, mesh_nod->parent->global); MulMatrixMX4(lt1, mesh_nod->global, mpi ); //lokalni translace mesh_nod->translate.x = lt1[12]; mesh_nod->translate.y = lt1[13]; mesh_nod->translate.z = lt1[14]; //odstraneni skalovani MaskROT(lt1); SetScaleMX4(sm, mesh_nod->scale.x, mesh_nod->scale.y, mesh_nod->scale.z); InverseMX4( smi, sm); MulMatrixMX4(lt2, smi, lt1); //lokalni rotace MaskROT(lt2); MXTOAA(lt2,&(mesh_nod->rotate.ax), &(mesh_nod->rotate.ang)); mesh_nod->rotate.ang = (float)Rad2Deg(-mesh_nod->rotate.ang); } //inicialni nastaveni mesh_nod->initial_rotate.ang = mesh_nod->rotate.ang; CopyV3(mesh_nod->initial_rotate.ax.p, mesh_nod->rotate.ax.p); CopyV3(mesh_nod->initial_translate.p, mesh_nod->translate.p); CopyV3(mesh_nod->initial_scale.p, mesh_nod->scale.p); } } //MESH GEOMETRY else if(!stricmp(GetToken(ase, 0),MESH)){ if(mesh && ase->read_geometry) read_mesh(ase, mesh); else skip_list(ase,GetToken(ase, 0)); } else if(!stricmp(GetToken(ase, 0),PROP_MOTIONBLUR)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),PROP_CASTSHADOW)){ read_unsupported_value(ase->tok,ase->tokc); } else if(!stricmp(GetToken(ase, 0),PROP_RECVSHADOW)){ read_unsupported_value(ase->tok,ase->tokc); } //ANIMATION else if(!stricmp(GetToken(ase, 0),TM_ANIMATION)){ if(ase->read_animation && ase->read_hierarchy) read_animation(ase,m); else skip_list(ase,GetToken(ase, 0)); } else if(!stricmp(GetToken(ase, 0),MATERIAL_REF)){ if(mesh) mesh->mat = atoi(GetToken(ase, 1)); else skip_list(ase,GetToken(ase, 0)); } else if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return;//OK else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase, 0)); } //FAIL THROW(E_8K_ASE_READER, "read_geom_object(): RPARENTEHESIS not found!"); } ///READ SCENE void read_scene(ASEFile* ase){ // while(ReadASELine(ase)){ // if(!stricmp(GetToken(ase, 0),RPARENTEHESIS)) return;//OK else if(!stricmp(GetToken(ase, 0),SCENE_FIRSTFRAME)) ase->scene_firstframe = atoi(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),SCENE_LASTFRAME)) ase->scene_lastframe = atoi(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),SCENE_FRAMESPEED)) ase->scene_framespeed = atoi(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, 0),SCENE_TICKSPERFRAME)) ase->scene_ticksperframe = atoi(GetToken(ase, 1)); else if(!stricmp(GetToken(ase, ase->tokc - 1),LPARENTEHESIS)) read_unsupported_list(ase,GetToken(ase, 0)); else read_unsupported_value(ase->tok,ase->tokc); } //FAIL THROW(E_8K_ASE_READER, "read_scene(): RPARENTEHESIS not found!"); } /* [ASE_NEW/ASE_APPEND] | [ASE_GEOMETRY/ASE_ANIMATION/..] | [ASE_MESHONLY|ASE_HIERARCHY] | ASE_LOD test for input: load_ASE("file.ase", m, ASE_NEW|ASE_GEOMETRY|ASE_MESHONLY , 0) load_ASE("file.ase", m, ASE_NEW|ASE_GEOMETRY|ASE_HIERARCHY , 0) load_ASE("file.ase", m, ASE_NEW|ASE_GEOMETRY|ASE_ANIMATION|ASE_HIERARCHY , 0) ->nahraje animaci i s objektem v hierarchii load_ASE("file.ase", m, ASE_APPEND|ASE_GEOMETRY , 0) -> prida dalsi objekt load_ASE("file.ase", m, ASE_APPEND|ASE_ANIMATION , 0) -> prida dalsi animaci load_ASE("file.ase", m, ASE_APPEND|ASE_ANIMATION|ASE_HIERARCHY , 0) -> prida dalsi animaci, ekviv spredchozim load_ASE("file.ase", m, ASE_APPEND|ASE_GEOMETRY|ASE_HIERARCHY , 0) -> prida dalsi hierarchii load_ASE("file.ase", m, ASE_APPEND|ASE_GEOMETRY|ASE_HIERARCHY|ASE_LOD , 0) -> prida dalsi hierarchii, do nove lod urovne load_ASE("file.ase", m, ASE_APPEND|ASE_GEOMETRY|ASE_MESHONLY|ASE_LOD , 0) -> prida dalsi objekt, do nove lod urovne load_ASE("file.ase", m, ASE_APPEND|ASE_ANIMATION|ASE_HIERARCHY|ASE_LOD , 0) -> prida dalsi animaci, do posledni lod urovne load_ASE("file.ase", m, ASE_APPEND|ASE_ANIMATION|ASE_LOD , 0) -> stejne jako predchozi load_ASE("file.ase", m, ASE_APPEND|ASE_GEOMETRY|ASE_HIERARCHY|ASE_LOD , 0) -> prida dalsi hierarchii, do nove lod urovne --- load_ASE("file.ase", m, ASE_NEW|ASE_GEOMETRY|ASE_ANIMATION|ASE_MESHONLY , 0) -> CHYBA,musi byt hierarchie load_ASE("file.ase", m, ASE_ANIMATION|ASE_HIERARCHY , 0) -> CHYBA, musi byt new nebo append load_ASE("file.ase", m, ASE_NEW|ASE_HIERARCHY , 0) -> CHYBA, musi byt geometry nebo anim load_ASE("file.ase", m, ASE_NEW|ASE_ANIMATION|ASE_HIERARCHY , 0) -> animace se da nahrat jen do existujici hierarchie load_ASE("file.ase", m, ASE_NEW|ASE_ANIMATION , 0)-> CHYBA,animace se da nahrat jen do existujici hierarchie +stejne s LOD */ void load_ASE(char* file, TModel* m, int flag) { load_ASE(file, m, flag, 0); } void load_ASE(char* file, TModel* m, int flag, float dist) { ASEFile ase; // //parse/check parameters if((flag & ASE_HIERARCHY) && (flag & ASE_MESHONLY)) THROW(E_8K_ASE_READER, "load_ASE: Wrong Parameters"); if(!(flag & ASE_HIERARCHY) && !(flag & ASE_MESHONLY)) THROW(E_8K_ASE_READER, "load_ASE: Wrong Parameters"); // if((flag & ASE_MESHONLY) && (flag & ASE_ANIMATION)) THROW(E_8K_ASE_READER, "load_ASE: Wrong Parameters"); // if((flag & ASE_NEW) && (flag & ASE_ANIMATION) && !(flag & ASE_GEOMETRY)) THROW(E_8K_ASE_READER, "load_ASE: Wrong Parameters"); // if(!(flag & ASE_ANIMATION) && !(flag & ASE_GEOMETRY)) THROW(E_8K_ASE_READER, "load_ASE: Wrong Parameters"); // if(!(flag & ASE_APPEND) && !(flag & ASE_NEW)) THROW(E_8K_ASE_READER, "load_ASE: Wrong Parameters"); if((flag & ASE_APPEND) && (flag & ASE_NEW)) THROW(E_8K_ASE_READER, "load_ASE: Wrong Parameters"); // OpenASEFile(&ase,file); // // ase.read_hierarchy = (flag & ASE_HIERARCHY)?1:0; ase.read_meshonly = (flag & ASE_MESHONLY)?1:0; ase.read_lod = (flag & ASE_LOD)?1:0; ase.read_geometry = (flag & ASE_GEOMETRY)?1:0; ase.read_animation = (flag & ASE_ANIMATION)?1:0; ase.conv_textureupdown = (flag & ASE_TEXTUREUPDOWN)?1:0; ase.conv_degree = (flag & ASE_DEGREES)?1:0; ase.lod_dist = dist; //initialization if(flag & ASE_NEW) { m->initModel(ase.read_lod,ase.read_hierarchy); } else if(flag & ASE_APPEND){ } try{ //READ MAIN BLOCKS while(ReadASELine(&ase)){ // if(!stricmp(GetToken(&ase, 0), MAX_ASCIIEXPORT)){ read_unsupported_value(ase.tok,ase.tokc); } else if(!stricmp(GetToken(&ase,0), COMMENT)){ read_unsupported_value(ase.tok,ase.tokc); } //SCENE, only how to interpret other data(animation,..) else if(!stricmp(GetToken(&ase, 0), SCENE)){ read_scene(&ase); } else if(!stricmp(GetToken(&ase, 0), MATERIAL_LIST)){ read_material_list(&ase, m); } //GEOMETRY else if(!stricmp(GetToken(&ase, 0), GEOMOBJECT)){ read_geom_object(&ase,m); } else if(!stricmp(GetToken(&ase, 0), LIGHTOBJECT)){ read_unsupported_list(&ase, GetToken(&ase, 0)); } else if(!stricmp(GetToken(&ase, 0), CAMERAOBJECT)){ read_unsupported_list(&ase, GetToken(&ase, 0)); } else if(!stricmp(GetToken(&ase, 0), RPARENTEHESIS)){ THROW(E_8K_ASE_READER, "load_ASE(): RPARENTEHESIS not expected!"); } } //FAIL }//try catch(E_8K_ASE_READER e){ CloseASEFile(&ase); throw e; }//catch CloseASEFile(&ase); } }//namespace /*****************************************************************************/