00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define PM_ASE_C
00037
00038
00039
00040
00041
00042
00043 #include "picointernal.h"
00044
00045 #ifdef DEBUG_PM_ASE
00046 #include "time.h"
00047 #endif
00048
00049
00050 static picoColor_t white = { 255, 255, 255, 255 };
00051
00052
00053
00054
00055
00056
00057 typedef struct aseSubMaterial_s
00058 {
00059 struct aseSubMaterial_s* next;
00060 int subMtlId;
00061 picoShader_t* shader;
00062
00063 } aseSubMaterial_t;
00064
00065 typedef struct aseMaterial_s
00066 {
00067 struct aseMaterial_s* next;
00068 struct aseSubMaterial_s* subMtls;
00069 int mtlId;
00070 } aseMaterial_t;
00071
00072
00073 static aseMaterial_t* _ase_get_material (aseMaterial_t* list, int mtlIdParent)
00074 {
00075 aseMaterial_t* mtl = list;
00076
00077 while (mtl) {
00078 if (mtlIdParent == mtl->mtlId) {
00079 break;
00080 }
00081 mtl = mtl->next;
00082 }
00083 return mtl;
00084 }
00085
00086 static aseSubMaterial_t* _ase_get_submaterial (aseMaterial_t* list, int mtlIdParent, int subMtlId)
00087 {
00088 aseMaterial_t* parent = _ase_get_material(list, mtlIdParent);
00089 aseSubMaterial_t* subMtl = NULL;
00090
00091 if (!parent) {
00092 _pico_printf(PICO_ERROR, "No ASE material exists with id %i\n", mtlIdParent);
00093 return NULL;
00094 }
00095
00096 subMtl = parent->subMtls;
00097 while (subMtl) {
00098 if (subMtlId == subMtl->subMtlId) {
00099 break;
00100 }
00101 subMtl = subMtl->next;
00102 }
00103 return subMtl;
00104 }
00105
00106 static aseSubMaterial_t* _ase_get_submaterial_or_default (aseMaterial_t* materials, int mtlIdParent, int subMtlId)
00107 {
00108 aseSubMaterial_t* subMtl = _ase_get_submaterial(materials, mtlIdParent, subMtlId);
00109 if (subMtl != NULL) {
00110 return subMtl;
00111 }
00112
00113
00114 subMtl = _ase_get_submaterial(materials, mtlIdParent, 0);
00115 if (subMtl != NULL) {
00116 return subMtl;
00117 }
00118
00119 _pico_printf(PICO_ERROR, "Could not find material/submaterial for id %d/%d\n", mtlIdParent, subMtlId);
00120 return NULL;
00121 }
00122
00123 static aseMaterial_t* _ase_add_material (aseMaterial_t **list, int mtlIdParent)
00124 {
00125 aseMaterial_t *mtl = _pico_calloc(1, sizeof(aseMaterial_t));
00126 mtl->mtlId = mtlIdParent;
00127 mtl->subMtls = NULL;
00128 mtl->next = *list;
00129 *list = mtl;
00130
00131 return mtl;
00132 }
00133
00134 static aseSubMaterial_t* _ase_add_submaterial (aseMaterial_t **list, int mtlIdParent, int subMtlId,
00135 picoShader_t* shader)
00136 {
00137 aseMaterial_t *parent = _ase_get_material(*list, mtlIdParent);
00138 aseSubMaterial_t *subMtl = _pico_calloc(1, sizeof(aseSubMaterial_t));
00139
00140 if (!parent) {
00141 parent = _ase_add_material(list, mtlIdParent);
00142 }
00143
00144 subMtl->shader = shader;
00145 subMtl->subMtlId = subMtlId;
00146 subMtl->next = parent->subMtls;
00147 parent->subMtls = subMtl;
00148
00149 return subMtl;
00150 }
00151
00152 static void _ase_free_materials (aseMaterial_t **list)
00153 {
00154 aseMaterial_t* mtl = *list;
00155 aseSubMaterial_t* subMtl = NULL;
00156
00157 aseMaterial_t* mtlTemp = NULL;
00158 aseSubMaterial_t* subMtlTemp = NULL;
00159
00160 while (mtl) {
00161 subMtl = mtl->subMtls;
00162 while (subMtl) {
00163 subMtlTemp = subMtl->next;
00164 _pico_free(subMtl);
00165 subMtl = subMtlTemp;
00166 }
00167 mtlTemp = mtl->next;
00168 _pico_free(mtl);
00169 mtl = mtlTemp;
00170 }
00171 (*list) = NULL;
00172 }
00173
00174 #ifdef DEBUG_PM_ASE
00175 static void _ase_print_materials (aseMaterial_t *list)
00176 {
00177 aseMaterial_t* mtl = list;
00178 aseSubMaterial_t* subMtl = NULL;
00179
00180 while (mtl) {
00181 _pico_printf(PICO_NORMAL, "ASE Material %i", mtl->mtlId);
00182 subMtl = mtl->subMtls;
00183 while (subMtl) {
00184 _pico_printf(PICO_NORMAL, " -- ASE SubMaterial %i - %s\n", subMtl->subMtlId, subMtl->shader->name);
00185 subMtl = subMtl->next;
00186 }
00187 mtl = mtl->next;
00188 }
00189 }
00190 #endif
00191
00192
00193
00194
00195
00199 static int _ase_canload (PM_PARAMS_CANLOAD)
00200 {
00201 picoParser_t *p;
00202
00203
00204 if (bufSize < 80)
00205 return PICO_PMV_ERROR_SIZE;
00206
00207
00208 p = _pico_new_parser((picoByte_t*) buffer, bufSize);
00209 if (p == NULL)
00210 return PICO_PMV_ERROR_MEMORY;
00211
00212
00213 if (_pico_parse_first(p) == NULL) {
00214 return PICO_PMV_ERROR_IDENT;
00215 }
00216
00217
00218 if (_pico_stricmp(p->token, "*3dsmax_asciiexport")) {
00219 _pico_free_parser(p);
00220 return PICO_PMV_ERROR_IDENT;
00221 }
00222
00223
00224 _pico_free_parser(p);
00225
00226
00227 return PICO_PMV_OK;
00228 }
00229
00230 typedef struct aseVertex_s
00231 {
00232 picoVec3_t xyz;
00233 picoVec3_t normal;
00234 picoIndex_t id;
00235 } aseVertex_t;
00236
00237 typedef struct aseTexCoord_s
00238 {
00239 picoVec2_t texcoord;
00240 } aseTexCoord_t;
00241
00242 typedef struct aseColor_s
00243 {
00244 picoColor_t color;
00245 } aseColor_t;
00246
00247 typedef struct aseFace_s
00248 {
00249 picoIndex_t indices[9];
00250 picoIndex_t smoothingGroup;
00251 picoIndex_t materialId;
00252 picoIndex_t subMaterialId;
00253 } aseFace_t;
00254
00255 typedef aseFace_t* aseFacesIter_t;
00256
00265 static void _ase_submit_triangles (picoModel_t* model, aseMaterial_t* materials, aseVertex_t* vertices,
00266 aseTexCoord_t* texcoords, aseColor_t* colors, aseFace_t* faces, int numFaces)
00267 {
00268 aseFacesIter_t i = faces, end = faces + numFaces;
00269 for (; i != end; ++i) {
00270
00271 aseSubMaterial_t* subMtl = _ase_get_submaterial_or_default(materials, (*i).materialId, (*i).subMaterialId);
00272 if (subMtl == NULL)
00273 return;
00274
00275 {
00276 picoVec3_t* xyz[3];
00277 picoVec3_t* normal[3];
00278 picoVec2_t* st[3];
00279 picoColor_t* color[3];
00280 picoIndex_t smooth[3];
00281 int j;
00282
00283 for (j = 0; j < 3; j++) {
00284 xyz[j] = &vertices[(*i).indices[j]].xyz;
00285 normal[j] = &vertices[(*i).indices[j]].normal;
00286 st[j] = &texcoords[(*i).indices[j + 3]].texcoord;
00287
00288 if (colors != NULL && (*i).indices[j + 6] >= 0) {
00289 color[j] = &colors[(*i).indices[j + 6]].color;
00290 } else {
00291 color[j] = &white;
00292 }
00293
00294 smooth[j] = (vertices[(*i).indices[j]].id * (1 << 16)) + (*i).smoothingGroup;
00295
00296 }
00297
00298
00299 PicoAddTriangleToModel(model, xyz, normal, 1, st, 1, color, subMtl->shader, smooth);
00300 }
00301 }
00302 }
00303
00304 static void shadername_convert (char* shaderName)
00305 {
00306
00307 char* s = shaderName;
00308 for (; *s != '\0'; ++s) {
00309 if (*s == '\\') {
00310 *s = '/';
00311 }
00312 }
00313 }
00314
00318 static picoModel_t *_ase_load (PM_PARAMS_LOAD)
00319 {
00320 picoModel_t *model;
00321 picoParser_t *p;
00322 char lastNodeName[1024];
00323
00324 aseVertex_t* vertices = NULL;
00325 aseTexCoord_t* texcoords = NULL;
00326 aseColor_t* colors = NULL;
00327 aseFace_t* faces = NULL;
00328 int numVertices = 0;
00329 int numFaces = 0;
00330 int numTextureVertices = 0;
00331 int numTextureVertexFaces = 0;
00332 int numColorVertices = 0;
00333 int numColorVertexFaces = 0;
00334 int vertexId = 0;
00335
00336 aseMaterial_t* materials = NULL;
00337
00338 #ifdef DEBUG_PM_ASE
00339 clock_t start, finish;
00340 double elapsed;
00341 start = clock();
00342 #endif
00343
00344
00345 #define _ase_error_return(m) \
00346 { \
00347 _pico_printf(PICO_ERROR, "%s in ASE, line %d.",m,p->curLine); \
00348 _pico_free_parser(p); \
00349 PicoFreeModel(model); \
00350 return NULL; \
00351 }
00352
00353 p = _pico_new_parser((picoByte_t *) buffer, bufSize);
00354 if (p == NULL)
00355 return NULL;
00356
00357
00358 model = PicoNewModel();
00359 if (model == NULL) {
00360 _pico_free_parser(p);
00361 return NULL;
00362 }
00363
00364 PicoSetModelFrameNum(model, frameNum);
00365 PicoSetModelName(model, fileName);
00366 PicoSetModelFileName(model, fileName);
00367
00368
00369 memset(lastNodeName, 0, sizeof(lastNodeName));
00370
00371
00372 while (1) {
00373
00374 if (_pico_parse_first(p) == NULL)
00375 break;
00376
00377
00378 if (p->token == NULL || !strlen(p->token))
00379 continue;
00380
00381
00382 if (p->token[0] != '*' && p->token[0] != '{' && p->token[0] != '}') {
00383 _pico_parse_skip_rest(p);
00384 continue;
00385 }
00386
00387 if (!_pico_stricmp(p->token, "*node_name")) {
00388
00389 char *ptr = _pico_parse(p, 0);
00390 if (ptr == NULL)
00391 _ase_error_return("Node name parse error");
00392
00393
00394 strncpy(lastNodeName, ptr, sizeof(lastNodeName));
00395 }
00396
00397 else if (!_pico_stricmp(p->token, "*mesh")) {
00398
00399 _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces);
00400 _pico_free(faces);
00401 _pico_free(vertices);
00402 _pico_free(texcoords);
00403 _pico_free(colors);
00404 colors = NULL;
00405 faces = NULL;
00406 vertices = NULL;
00407 texcoords = NULL;
00408 } else if (!_pico_stricmp(p->token, "*mesh_numvertex")) {
00409 if (!_pico_parse_int(p, &numVertices))
00410 _ase_error_return("Missing MESH_NUMVERTEX value");
00411
00412 vertices = _pico_calloc(numVertices, sizeof(aseVertex_t));
00413 } else if (!_pico_stricmp(p->token, "*mesh_numfaces")) {
00414 if (!_pico_parse_int(p, &numFaces))
00415 _ase_error_return("Missing MESH_NUMFACES value");
00416
00417 faces = _pico_calloc(numFaces, sizeof(aseFace_t));
00418 } else if (!_pico_stricmp(p->token, "*mesh_numtvertex")) {
00419 if (!_pico_parse_int(p, &numTextureVertices))
00420 _ase_error_return("Missing MESH_NUMTVERTEX value");
00421
00422 texcoords = _pico_calloc(numTextureVertices, sizeof(aseTexCoord_t));
00423 } else if (!_pico_stricmp(p->token, "*mesh_numtvfaces")) {
00424 if (!_pico_parse_int(p, &numTextureVertexFaces))
00425 _ase_error_return("Missing MESH_NUMTVFACES value");
00426 } else if (!_pico_stricmp(p->token, "*mesh_numcvertex")) {
00427 if (!_pico_parse_int(p, &numColorVertices))
00428 _ase_error_return("Missing MESH_NUMCVERTEX value");
00429
00430 colors = _pico_calloc(numColorVertices, sizeof(aseColor_t));
00431 memset(colors, 255, numColorVertices * sizeof(aseColor_t));
00432 } else if (!_pico_stricmp(p->token, "*mesh_numcvfaces")) {
00433 if (!_pico_parse_int(p, &numColorVertexFaces))
00434 _ase_error_return("Missing MESH_NUMCVFACES value");
00435 }
00436
00437
00438
00439
00440 else if (!_pico_stricmp(p->token, "*material_ref")) {
00441 int mtlId;
00442
00443
00444 if (!_pico_parse_int(p, &mtlId))
00445 _ase_error_return("Missing material reference ID");
00446
00447 {
00448 int i = 0;
00449
00450
00451 for (; i < numFaces; ++i) {
00452 faces[i].materialId = mtlId;
00453 }
00454 }
00455 }
00456
00457 else if (!_pico_stricmp(p->token, "*mesh_vertex")) {
00458 int index;
00459
00460 if (numVertices == 0)
00461 _ase_error_return("Vertex parse error");
00462
00463
00464 if (!_pico_parse_int(p, &index))
00465 _ase_error_return("Vertex parse error");
00466 if (!_pico_parse_vec(p, vertices[index].xyz))
00467 _ase_error_return("Vertex parse error");
00468
00469 vertices[index].id = vertexId++;
00470 }
00471
00472 else if (!_pico_stricmp(p->token, "*mesh_vertexnormal")) {
00473 int index;
00474
00475 if (numVertices == 0)
00476 _ase_error_return("Vertex parse error");
00477
00478
00479 if (!_pico_parse_int(p, &index))
00480 _ase_error_return("Vertex parse error");
00481 if (!_pico_parse_vec(p, vertices[index].normal))
00482 _ase_error_return("Vertex parse error");
00483 }
00484
00485 else if (!_pico_stricmp(p->token, "*mesh_face")) {
00486 picoIndex_t indexes[3];
00487 int index;
00488
00489 if (numFaces == 0)
00490 _ase_error_return("Face parse error");
00491
00492
00493 if (!_pico_parse_int(p, &index))
00494 _ase_error_return("Face parse error");
00495
00496
00497 _pico_parse(p, 0);
00498 if (!_pico_parse_int(p, &indexes[0]))
00499 _ase_error_return("Face parse error");
00500
00501
00502 _pico_parse(p, 0);
00503 if (!_pico_parse_int(p, &indexes[1]))
00504 _ase_error_return("Face parse error");
00505
00506
00507 _pico_parse(p, 0);
00508 if (!_pico_parse_int(p, &indexes[2]))
00509 _ase_error_return("Face parse error");
00510
00511
00512 while (1) {
00513 if (!_pico_parse(p, 0)) {
00514 break;
00515 }
00516 if (!_pico_stricmp(p->token, "*MESH_SMOOTHING")) {
00517 _pico_parse_int(p, &faces[index].smoothingGroup);
00518 }
00519 if (!_pico_stricmp(p->token, "*MESH_MTLID")) {
00520 _pico_parse_int(p, &faces[index].subMaterialId);
00521 }
00522 }
00523
00524 faces[index].materialId = 0;
00525 faces[index].indices[0] = indexes[2];
00526 faces[index].indices[1] = indexes[1];
00527 faces[index].indices[2] = indexes[0];
00528 }
00529
00530 else if (!_pico_stricmp(p->token, "*mesh_tvert")) {
00531 int index;
00532
00533 if (numVertices == 0)
00534 _ase_error_return("Texture Vertex parse error");
00535
00536
00537 if (!_pico_parse_int(p, &index) || index >= numTextureVertices)
00538 _ase_error_return("Texture vertex parse error");
00539
00540
00541 if (!_pico_parse_float(p, &texcoords[index].texcoord[0]))
00542 _ase_error_return("Texture vertex parse error");
00543
00544
00545 if (!_pico_parse_float(p, &texcoords[index].texcoord[1]))
00546 _ase_error_return("Texture vertex parse error");
00547
00548
00549 texcoords[index].texcoord[1] = 1.0f - texcoords[index].texcoord[1];
00550 }
00551
00552 else if (!_pico_stricmp(p->token, "*mesh_tface")) {
00553 picoIndex_t indexes[3];
00554 int index;
00555
00556 if (numFaces == 0)
00557 _ase_error_return("Texture face parse error");
00558
00559
00560 if (!_pico_parse_int(p, &index))
00561 _ase_error_return("Texture face parse error");
00562
00563
00564 if (!_pico_parse_int(p, &indexes[0]))
00565 _ase_error_return("Texture face parse error");
00566
00567
00568 if (!_pico_parse_int(p, &indexes[1]))
00569 _ase_error_return("Texture face parse error");
00570
00571
00572 if (!_pico_parse_int(p, &indexes[2]))
00573 _ase_error_return("Texture face parse error");
00574
00575 faces[index].indices[3] = indexes[2];
00576 faces[index].indices[4] = indexes[1];
00577 faces[index].indices[5] = indexes[0];
00578 }
00579
00580 else if (!_pico_stricmp(p->token, "*mesh_vertcol")) {
00581 int index;
00582 float colorInput;
00583
00584 if (numVertices == 0)
00585 _ase_error_return("Color Vertex parse error");
00586
00587
00588 if (!_pico_parse_int(p, &index))
00589 _ase_error_return("Color vertex parse error");
00590
00591
00592 if (!_pico_parse_float(p, &colorInput))
00593 _ase_error_return("Color vertex parse error");
00594 colors[index].color[0] = (picoByte_t) (colorInput * 255);
00595
00596
00597 if (!_pico_parse_float(p, &colorInput))
00598 _ase_error_return("Color vertex parse error");
00599 colors[index].color[1] = (picoByte_t) (colorInput * 255);
00600
00601
00602 if (!_pico_parse_float(p, &colorInput))
00603 _ase_error_return("Color vertex parse error");
00604 colors[index].color[2] = (picoByte_t) (colorInput * 255);
00605
00606
00607 colors[index].color[3] = 255;
00608 }
00609
00610 else if (!_pico_stricmp(p->token, "*mesh_cface")) {
00611 picoIndex_t indexes[3];
00612 int index;
00613
00614 if (numFaces == 0)
00615 _ase_error_return("Face parse error");
00616
00617
00618 if (!_pico_parse_int(p, &index))
00619 _ase_error_return("Face parse error");
00620
00621
00622 if (!_pico_parse_int(p, &indexes[0]))
00623 _ase_error_return("Face parse error");
00624
00625
00626 if (!_pico_parse_int(p, &indexes[1]))
00627 _ase_error_return("Face parse error");
00628
00629
00630 if (!_pico_parse_int(p, &indexes[2]))
00631 _ase_error_return("Face parse error");
00632
00633 faces[index].indices[6] = indexes[2];
00634 faces[index].indices[7] = indexes[1];
00635 faces[index].indices[8] = indexes[0];
00636 }
00637
00638 else if (!_pico_stricmp(p->token, "*material")) {
00639 aseSubMaterial_t*subMaterial = NULL;
00640 picoShader_t *shader = NULL;
00641 int level = 1, index;
00642 char materialName[1024];
00643 float transValue = 0.0f, shineValue = 1.0f;
00644 picoColor_t ambientColor, diffuseColor, specularColor;
00645 char *mapname = NULL;
00646 int subMtlId, subMaterialLevel = -1;
00647
00648
00649 _pico_parse_int(p, &index);
00650
00651
00652 if (!_pico_parse_check(p, 1, "{"))
00653 _ase_error_return("Material missing opening brace");
00654
00655
00656 while (1) {
00657
00658 if (_pico_parse(p, 1) == NULL)
00659 break;
00660 if (!strlen(p->token))
00661 continue;
00662
00663
00664 if (p->token[0] == '{')
00665 level++;
00666 else if (p->token[0] == '}')
00667 level--;
00668 if (!level)
00669 break;
00670
00671 if (level == subMaterialLevel) {
00672
00673 _pico_first_token(materialName);
00674 shadername_convert(materialName);
00675 PicoSetShaderName(shader, materialName);
00676
00677
00678 PicoSetShaderTransparency(shader, transValue);
00679
00680
00681 PicoSetShaderAmbientColor(shader, ambientColor);
00682
00683
00684 diffuseColor[3] = (picoByte_t) (transValue * 255.0);
00685
00686
00687 PicoSetShaderDiffuseColor(shader, diffuseColor);
00688
00689
00690 PicoSetShaderSpecularColor(shader, specularColor);
00691
00692
00693 PicoSetShaderShininess(shader, shineValue);
00694
00695
00696 PicoSetShaderMapName(shader, mapname);
00697
00698 subMaterial = _ase_add_submaterial(&materials, index, subMtlId, shader);
00699 subMaterialLevel = -1;
00700 }
00701
00702
00703 if (!_pico_stricmp(p->token, "*submaterial")) {
00704
00705 _pico_parse_int(p, &subMtlId);
00706
00707 shader = PicoNewShader(model);
00708 if (shader == NULL) {
00709 PicoFreeModel(model);
00710 return NULL;
00711 }
00712 subMaterialLevel = level;
00713 }
00714
00715 else if (!_pico_stricmp(p->token, "*material_name")) {
00716 char* name = _pico_parse(p, 0);
00717 if (name == NULL)
00718 _ase_error_return("Missing material name");
00719
00720 strcpy(materialName, name);
00721
00722 _pico_parse_skip_rest(p);
00723 continue;
00724 }
00725
00726 else if (!_pico_stricmp(p->token, "*material_transparency")) {
00727
00728 if (!_pico_parse_float(p, &transValue))
00729 _ase_error_return("Material transparency parse error");
00730
00731
00732 _pico_parse_skip_rest(p);
00733 continue;
00734 }
00735
00736 else if (!_pico_stricmp(p->token, "*material_shine")) {
00737
00738
00739
00740
00741
00742 if (!_pico_parse_float(p, &shineValue))
00743 _ase_error_return("Material shine parse error");
00744
00745
00746 shineValue *= 128.0;
00747
00748
00749 _pico_parse_skip_rest(p);
00750 continue;
00751 }
00752
00753 else if (!_pico_stricmp(p->token, "*material_ambient")) {
00754 picoVec3_t vec;
00755
00756 if (!_pico_parse_vec(p, vec))
00757 _ase_error_return("Material color parse error");
00758
00759
00760 ambientColor[0] = (int) (vec[0] * 255.0);
00761 ambientColor[1] = (int) (vec[1] * 255.0);
00762 ambientColor[2] = (int) (vec[2] * 255.0);
00763 ambientColor[3] = (int) (255);
00764
00765
00766 _pico_parse_skip_rest(p);
00767 continue;
00768 }
00769
00770 else if (!_pico_stricmp(p->token, "*material_diffuse")) {
00771 picoVec3_t vec;
00772
00773
00774 if (!_pico_parse_vec(p, vec))
00775 _ase_error_return("Material color parse error");
00776
00777
00778 diffuseColor[0] = (int) (vec[0] * 255.0);
00779 diffuseColor[1] = (int) (vec[1] * 255.0);
00780 diffuseColor[2] = (int) (vec[2] * 255.0);
00781 diffuseColor[3] = (int) (255);
00782
00783
00784 _pico_parse_skip_rest(p);
00785 continue;
00786 }
00787
00788 else if (!_pico_stricmp(p->token, "*material_specular")) {
00789 picoVec3_t vec;
00790
00791
00792 if (!_pico_parse_vec(p, vec))
00793 _ase_error_return("Material color parse error");
00794
00795
00796 specularColor[0] = (int) (vec[0] * 255);
00797 specularColor[1] = (int) (vec[1] * 255);
00798 specularColor[2] = (int) (vec[2] * 255);
00799 specularColor[3] = (int) (255);
00800
00801
00802 _pico_parse_skip_rest(p);
00803 continue;
00804 }
00805
00806 else if (!_pico_stricmp(p->token, "*map_diffuse")) {
00807 int sublevel = 0;
00808
00809
00810 while (1) {
00811
00812 if (_pico_parse(p, 1) == NULL)
00813 break;
00814 if (!strlen(p->token))
00815 continue;
00816
00817
00818 if (p->token[0] == '{')
00819 sublevel++;
00820 else if (p->token[0] == '}')
00821 sublevel--;
00822 if (!sublevel)
00823 break;
00824
00825
00826 if (!_pico_stricmp(p->token, "*bitmap")) {
00827 char* name = _pico_parse(p, 0);
00828 if (name == NULL)
00829 _ase_error_return("Missing material map bitmap name");
00830 mapname = _pico_alloc(strlen(name) + 1);
00831 strcpy(mapname, name);
00832
00833 _pico_parse_skip_rest(p);
00834 continue;
00835 }
00836 }
00837 }
00838
00839 }
00840
00841
00842 if (subMaterial == NULL) {
00843
00844 shader = PicoNewShader(model);
00845 if (shader == NULL) {
00846 PicoFreeModel(model);
00847 return NULL;
00848 }
00849
00850
00851 shadername_convert(materialName);
00852 PicoSetShaderName(shader, materialName);
00853
00854
00855 PicoSetShaderTransparency(shader, transValue);
00856
00857
00858 PicoSetShaderAmbientColor(shader, ambientColor);
00859
00860
00861 diffuseColor[3] = (picoByte_t) (transValue * 255.0);
00862
00863
00864 PicoSetShaderDiffuseColor(shader, diffuseColor);
00865
00866
00867 PicoSetShaderSpecularColor(shader, specularColor);
00868
00869
00870 PicoSetShaderShininess(shader, shineValue);
00871
00872
00873 PicoSetShaderMapName(shader, mapname);
00874
00875
00876 if (mapname != NULL) {
00877 char* p = mapname;
00878
00879
00880 shadername_convert(mapname);
00881 {
00882
00883 char* last_period = strrchr(p, '.');
00884 if (last_period != NULL) {
00885 *last_period = '\0';
00886 }
00887 }
00888
00889
00890 for (; *p != '\0'; ++p) {
00891 if (_pico_strnicmp(p, "models/", 7) == 0 || _pico_strnicmp(p, "textures/", 9) == 0) {
00892 break;
00893 }
00894 }
00895
00896 if (*p != '\0') {
00897
00898 PicoSetShaderName(shader, p);
00899 }
00900 }
00901
00902
00903 subMaterial = _ase_add_submaterial(&materials, index, 0, shader);
00904 }
00905
00906
00907 if (mapname != NULL)
00908 _pico_free(mapname);
00909 }
00910
00911
00912 _pico_parse_skip_rest(p);
00913 }
00914
00915
00916 _ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces);
00917 _pico_free(faces);
00918 _pico_free(vertices);
00919 _pico_free(texcoords);
00920 _pico_free(colors);
00921
00922 #ifdef DEBUG_PM_ASE
00923 _ase_print_materials(materials);
00924 finish = clock();
00925 elapsed = (double)(finish - start) / CLOCKS_PER_SEC;
00926 _pico_printf(PICO_NORMAL, "Loaded model in in %-.2f second(s)\n", elapsed);
00927 #endif
00928
00929 _ase_free_materials(&materials);
00930
00931 _pico_free_parser(p);
00932
00933
00934 return model;
00935 }
00936
00937
00938 const picoModule_t picoModuleASE = { "1.0",
00939 "Autodesk 3DSMAX ASCII",
00940 "Jared Hefty, seaw0lf",
00941 "2003 Jared Hefty, 2002 seaw0lf",
00942 { "ase", NULL, NULL, NULL
00943 }, _ase_canload,
00944 _ase_load,
00945 NULL,
00946 NULL
00947 };