1 /* -----------------------------------------------------------------------------
5 Copyright (c) 2002, Randy Reddig & seaw0lf
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
11 Redistributions of source code must retain the above copyright notice, this list
12 of conditions and the following disclaimer.
14 Redistributions in binary form must reproduce the above copyright notice, this
15 list of conditions and the following disclaimer in the documentation and/or
16 other aseMaterialList provided with the distribution.
18 Neither the names of the copyright holders nor the names of its contributors may
19 be used to endorse or promote products derived from this software without
20 specific prior written permission.
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ----------------------------------------------------------------------------- */
39 /* uncomment when debugging this module */
40 //#define DEBUG_PM_ASE
41 //#define DEBUG_PM_ASE_EX
45 #include "picointernal.h"
52 static picoColor_t white = { 255, 255, 255, 255 };
54 /* jhefty - multi-subobject material support */
56 /* Material/SubMaterial management */
57 /* A material should have 1..n submaterials assigned to it */
59 typedef struct aseSubMaterial_s
61 struct aseSubMaterial_s* next;
67 typedef struct aseMaterial_s
69 struct aseMaterial_s* next;
70 struct aseSubMaterial_s* subMtls;
74 /* Material/SubMaterial management functions */
75 static aseMaterial_t* _ase_get_material( aseMaterial_t* list, int mtlIdParent ){
76 aseMaterial_t* mtl = list;
80 if ( mtlIdParent == mtl->mtlId ) {
88 static aseSubMaterial_t* _ase_get_submaterial( aseMaterial_t* list, int mtlIdParent, int subMtlId ){
89 aseMaterial_t* parent = _ase_get_material( list, mtlIdParent );
90 aseSubMaterial_t* subMtl = NULL;
93 _pico_printf( PICO_ERROR, "No ASE material exists with id %i\n", mtlIdParent );
97 subMtl = parent->subMtls;
100 if ( subMtlId == subMtl->subMtlId ) {
103 subMtl = subMtl->next;
108 static aseMaterial_t* _ase_add_material( aseMaterial_t **list, int mtlIdParent ){
109 aseMaterial_t *mtl = _pico_calloc( 1, sizeof( aseMaterial_t ) );
110 mtl->mtlId = mtlIdParent;
118 static aseSubMaterial_t* _ase_add_submaterial( aseMaterial_t **list, int mtlIdParent, int subMtlId, picoShader_t* shader ){
119 aseMaterial_t *parent = _ase_get_material( *list, mtlIdParent );
120 aseSubMaterial_t *subMtl = _pico_calloc( 1, sizeof( aseSubMaterial_t ) );
123 parent = _ase_add_material( list, mtlIdParent );
126 subMtl->shader = shader;
127 subMtl->subMtlId = subMtlId;
128 subMtl->next = parent->subMtls;
129 parent->subMtls = subMtl;
134 static void _ase_free_materials( aseMaterial_t **list ){
135 aseMaterial_t* mtl = *list;
136 aseSubMaterial_t* subMtl = NULL;
138 aseMaterial_t* mtlTemp = NULL;
139 aseSubMaterial_t* subMtlTemp = NULL;
143 subMtl = mtl->subMtls;
146 subMtlTemp = subMtl->next;
147 _pico_free( subMtl );
158 static void _ase_print_materials( aseMaterial_t *list ){
159 aseMaterial_t* mtl = list;
160 aseSubMaterial_t* subMtl = NULL;
164 _pico_printf( PICO_NORMAL, "ASE Material %i", mtl->mtlId );
165 subMtl = mtl->subMtls;
168 _pico_printf( PICO_NORMAL, " -- ASE SubMaterial %i - %s\n", subMtl->subMtlId, subMtl->shader->name );
169 subMtl = subMtl->next;
174 #endif //DEBUG_PM_ASE
176 /* ASE Face management */
177 /* These are used to keep an association between a submaterial and a face definition */
178 /* They are kept in parallel with the current picoSurface, */
179 /* and are used by _ase_submit_triangles to lookup the proper material/submaterial IDs */
180 typedef struct aseFace_s
182 struct aseFace_s* next;
188 /* ASE Face management functions */
189 void _ase_add_face( aseFace_t **list, aseFace_t **tail, aseFace_t *newFace ){
190 /* insert as head of list */
196 ( *tail )->next = newFace;
200 newFace->next = NULL;
202 //tag the color indices so we can detect them and apply the default color to them
203 newFace->index[6] = -1;
204 newFace->index[7] = -1;
205 newFace->index[8] = -1;
208 aseFace_t* _ase_get_face_for_index( aseFace_t *list, int index ){
210 aseFace_t* face = list;
212 while ( counter < index )
219 static void _ase_free_faces( aseFace_t** list, aseFace_t** tail ){
220 aseFace_t* face = *list;
221 aseFace_t* tempFace = NULL;
225 tempFace = face->next;
235 * - apply material specific uv offsets to uv coordinates
239 * validates a 3dsmax ase model file.
241 static int _ase_canload( PM_PARAMS_CANLOAD ){
245 /* quick data length validation */
246 if ( bufSize < 80 ) {
247 return PICO_PMV_ERROR_SIZE;
250 /* keep the friggin compiler happy */
251 *fileName = *fileName;
253 /* create pico parser */
254 p = _pico_new_parser( (picoByte_t*) buffer, bufSize );
256 return PICO_PMV_ERROR_MEMORY;
259 /* get first token */
260 if ( _pico_parse_first( p ) == NULL ) {
261 return PICO_PMV_ERROR_IDENT;
264 /* check first token */
265 if ( _pico_stricmp( p->token, "*3dsmax_asciiexport" ) ) {
266 _pico_free_parser( p );
267 return PICO_PMV_ERROR_IDENT;
270 /* free the pico parser object */
271 _pico_free_parser( p );
273 /* file seems to be a valid ase file */
279 /* _ase_submit_triangles - jhefty
280 use the surface and the current face list to look up material/submaterial IDs
281 and submit them to the model for proper processing
283 The following still holds from ydnar's _ase_make_surface:
284 indexes 0 1 2 = vert indexes
285 indexes 3 4 5 = st indexes
286 indexes 6 7 8 = color indexes (new)
289 static void _ase_submit_triangles( picoSurface_t* surface, picoModel_t* model, aseMaterial_t* materials, aseFace_t* faces ){
291 aseSubMaterial_t* subMtl;
293 picoVec3_t* normal[3];
295 picoColor_t* color[3];
299 while ( face != NULL )
301 /* look up the shader for the material/submaterial pair */
302 subMtl = _ase_get_submaterial( materials, face->mtlId, face->subMtlId );
303 if ( subMtl == NULL ) {
304 /* ydnar: trying default submaterial */
305 subMtl = _ase_get_submaterial( materials, face->mtlId, 0 );
306 if ( subMtl == NULL ) {
307 _pico_printf( PICO_ERROR, "Could not find material/submaterial for id %d/%d\n", face->mtlId, face->subMtlId );
312 /* we pull the data from the surface using the facelist data */
313 for ( i = 0 ; i < 3 ; i++ )
315 xyz[i] = (picoVec3_t*) PicoGetSurfaceXYZ( surface, face->index[ i ] );
316 normal[i] = (picoVec3_t*) PicoGetSurfaceNormal( surface, face->index[ i ] );
317 st[i] = (picoVec2_t*) PicoGetSurfaceST( surface, 0, face->index[ i + 3 ] );
319 if ( face->index [ i + 6] >= 0 ) {
320 color[i] = (picoColor_t*)PicoGetSurfaceColor( surface, 0, face->index[ i + 6 ] );
329 /* submit the triangle to the model */
330 PicoAddTriangleToModel( model, xyz, normal, 1, st, 1, color, subMtl->shader );
332 /* advance to the next face */
338 * loads a 3dsmax ase model file.
340 static picoModel_t *_ase_load( PM_PARAMS_LOAD ){
342 picoSurface_t *surface = NULL;
344 char lastNodeName[ 1024 ];
346 aseFace_t* faces = NULL;
347 aseFace_t* facesTail = NULL;
348 aseMaterial_t* materials = NULL;
351 clock_t start, finish;
357 #define _ase_error_return( m ) \
359 _pico_printf( PICO_ERROR,"%s in ASE, line %d.",m,p->curLine ); \
360 _pico_free_parser( p ); \
361 PicoFreeModel( model ); \
364 /* create a new pico parser */
365 p = _pico_new_parser( (picoByte_t *)buffer,bufSize );
370 /* create a new pico model */
371 model = PicoNewModel();
372 if ( model == NULL ) {
373 _pico_free_parser( p );
377 PicoSetModelFrameNum( model, frameNum );
378 PicoSetModelName( model, fileName );
379 PicoSetModelFileName( model, fileName );
381 /* initialize some stuff */
382 memset( lastNodeName,0,sizeof( lastNodeName ) );
384 /* parse ase model file */
387 /* get first token on line */
388 if ( _pico_parse_first( p ) == NULL ) {
392 /* we just skip empty lines */
393 if ( p->token == NULL || !strlen( p->token ) ) {
397 /* we skip invalid ase statements */
398 if ( p->token[0] != '*' && p->token[0] != '{' && p->token[0] != '}' ) {
399 _pico_parse_skip_rest( p );
402 /* remember node name */
403 if ( !_pico_stricmp( p->token,"*node_name" ) ) {
405 char *ptr = _pico_parse( p,0 );
407 _ase_error_return( "Node name parse error" );
410 /* remember node name */
411 strncpy( lastNodeName,ptr,sizeof( lastNodeName ) );
413 /* model mesh (originally contained within geomobject) */
414 else if ( !_pico_stricmp( p->token,"*mesh" ) ) {
415 /* finish existing surface */
416 //_ase_make_surface( model, &surface );
417 _ase_submit_triangles( surface, model,materials,faces );
418 _ase_free_faces( &faces,&facesTail );
420 /* allocate new pico surface */
421 surface = PicoNewSurface( NULL );
422 if ( surface == NULL ) {
423 PicoFreeModel( model );
427 /* mesh material reference. this usually comes at the end of */
428 /* geomobjects after the mesh blocks. we must assume that the */
429 /* new mesh was already created so all we can do here is assign */
430 /* the material reference id (shader index) now. */
431 else if ( !_pico_stricmp( p->token,"*material_ref" ) ) {
435 /* we must have a valid surface */
436 if ( surface == NULL ) {
437 _ase_error_return( "Missing mesh for material reference" );
440 /* get the material ref (0..n) */
441 if ( !_pico_parse_int( p,&mtlId ) ) {
442 _ase_error_return( "Missing material reference ID" );
445 /* fix up all of the aseFaceList in the surface to point to the parent material */
446 /* we've already saved off their subMtl */
448 while ( face != NULL )
454 /* model mesh vertex */
455 else if ( !_pico_stricmp( p->token,"*mesh_vertex" ) ) {
459 /* we must have a valid surface */
460 if ( surface == NULL ) {
464 /* get vertex data (orig: index +y -x +z) */
465 if ( !_pico_parse_int( p,&index ) ) {
466 _ase_error_return( "Vertex parse error" );
468 if ( !_pico_parse_vec( p,v ) ) {
469 _ase_error_return( "Vertex parse error" );
473 PicoSetSurfaceXYZ( surface,index,v );
475 /* model mesh vertex normal */
476 else if ( !_pico_stricmp( p->token,"*mesh_vertexnormal" ) ) {
480 /* we must have a valid surface */
481 if ( surface == NULL ) {
485 /* get vertex data (orig: index +y -x +z) */
486 if ( !_pico_parse_int( p,&index ) ) {
487 _ase_error_return( "Vertex parse error" );
489 if ( !_pico_parse_vec( p,v ) ) {
490 _ase_error_return( "Vertex parse error" );
494 PicoSetSurfaceNormal( surface,index,v );
496 /* model mesh face */
497 else if ( !_pico_stricmp( p->token,"*mesh_face" ) ) {
498 picoIndex_t indexes[3];
501 /* we must have a valid surface */
502 if ( surface == NULL ) {
507 if ( !_pico_parse_int( p,&index ) ) {
508 _ase_error_return( "Face parse error" );
511 /* get 1st vertex index */
513 if ( !_pico_parse_int( p,&indexes[0] ) ) {
514 _ase_error_return( "Face parse error" );
517 /* get 2nd vertex index */
519 if ( !_pico_parse_int( p,&indexes[1] ) ) {
520 _ase_error_return( "Face parse error" );
523 /* get 3rd vertex index */
525 if ( !_pico_parse_int( p,&indexes[2] ) ) {
526 _ase_error_return( "Face parse error" );
529 /* set face indexes (note interleaved offset!) */
530 PicoSetSurfaceIndex( surface, ( index * 9 + 0 ), indexes[2] );
531 PicoSetSurfaceIndex( surface, ( index * 9 + 1 ), indexes[1] );
532 PicoSetSurfaceIndex( surface, ( index * 9 + 2 ), indexes[0] );
534 /* parse to the subMaterial ID */
538 if ( !_pico_stricmp( p->token,"*MESH_MTLID" ) ) {
542 _pico_parse_int( p, &subMtlId );
543 newFace = _pico_calloc( 1, sizeof( aseFace_t ) );
545 /* we fix up the mtlId later when we parse the material_ref */
547 newFace->subMtlId = subMtlId;
548 newFace->index[0] = indexes[2];
549 newFace->index[1] = indexes[1];
550 newFace->index[2] = indexes[0];
552 _ase_add_face( &faces,&facesTail,newFace );
558 /* model texture vertex */
559 else if ( !_pico_stricmp( p->token,"*mesh_tvert" ) ) {
563 /* we must have a valid surface */
564 if ( surface == NULL ) {
568 /* get uv vertex index */
569 if ( !_pico_parse_int( p,&index ) ) {
570 _ase_error_return( "UV vertex parse error" );
573 /* get uv vertex s */
574 if ( !_pico_parse_float( p,&uv[0] ) ) {
575 _ase_error_return( "UV vertex parse error" );
578 /* get uv vertex t */
579 if ( !_pico_parse_float( p,&uv[1] ) ) {
580 _ase_error_return( "UV vertex parse error" );
583 /* ydnar: invert t */
584 uv[ 1 ] = 1.0f - uv[ 1 ];
586 /* set texture vertex */
587 PicoSetSurfaceST( surface,0,index,uv );
589 /* ydnar: model mesh texture face */
590 else if ( !_pico_stricmp( p->token, "*mesh_tface" ) ) {
591 picoIndex_t indexes[3];
595 /* we must have a valid surface */
596 if ( surface == NULL ) {
601 if ( !_pico_parse_int( p,&index ) ) {
602 _ase_error_return( "Texture face parse error" );
605 /* get 1st vertex index */
606 if ( !_pico_parse_int( p,&indexes[0] ) ) {
607 _ase_error_return( "Texture face parse error" );
610 /* get 2nd vertex index */
611 if ( !_pico_parse_int( p,&indexes[1] ) ) {
612 _ase_error_return( "Texture face parse error" );
615 /* get 3rd vertex index */
616 if ( !_pico_parse_int( p,&indexes[2] ) ) {
617 _ase_error_return( "Texture face parse error" );
620 /* set face indexes (note interleaved offset!) */
621 PicoSetSurfaceIndex( surface, ( index * 9 + 3 ), indexes[2] );
622 PicoSetSurfaceIndex( surface, ( index * 9 + 4 ), indexes[1] );
623 PicoSetSurfaceIndex( surface, ( index * 9 + 5 ), indexes[0] );
625 face = _ase_get_face_for_index( faces,index );
626 face->index[3] = indexes[2];
627 face->index[4] = indexes[1];
628 face->index[5] = indexes[0];
630 /* model color vertex */
631 else if ( !_pico_stricmp( p->token,"*mesh_vertcol" ) ) {
636 /* we must have a valid surface */
637 if ( surface == NULL ) {
641 /* get color vertex index */
642 if ( !_pico_parse_int( p,&index ) ) {
643 _ase_error_return( "UV vertex parse error" );
646 /* get R component */
647 if ( !_pico_parse_float( p,&colorInput ) ) {
648 _ase_error_return( "color vertex parse error" );
650 color[0] = (picoByte_t)( colorInput * 255 );
652 /* get G component */
653 if ( !_pico_parse_float( p,&colorInput ) ) {
654 _ase_error_return( "color vertex parse error" );
656 color[1] = (picoByte_t)( colorInput * 255 );
658 /* get B component */
659 if ( !_pico_parse_float( p,&colorInput ) ) {
660 _ase_error_return( "color vertex parse error" );
662 color[2] = (picoByte_t)( colorInput * 255 );
664 /* leave alpha alone since we don't get any data from the ASE format */
667 /* set texture vertex */
668 PicoSetSurfaceColor( surface,0,index,color );
670 /* model color face */
671 else if ( !_pico_stricmp( p->token,"*mesh_cface" ) ) {
672 picoIndex_t indexes[3];
676 /* we must have a valid surface */
677 if ( surface == NULL ) {
682 if ( !_pico_parse_int( p,&index ) ) {
683 _ase_error_return( "Face parse error" );
686 /* get 1st cvertex index */
687 // _pico_parse( p,0 );
688 if ( !_pico_parse_int( p,&indexes[0] ) ) {
689 _ase_error_return( "Face parse error" );
692 /* get 2nd cvertex index */
693 // _pico_parse( p,0 );
694 if ( !_pico_parse_int( p,&indexes[1] ) ) {
695 _ase_error_return( "Face parse error" );
698 /* get 3rd cvertex index */
699 // _pico_parse( p,0 );
700 if ( !_pico_parse_int( p,&indexes[2] ) ) {
701 _ase_error_return( "Face parse error" );
704 /* set face indexes (note interleaved offset!) */
705 PicoSetSurfaceIndex( surface, ( index * 9 + 6 ), indexes[2] );
706 PicoSetSurfaceIndex( surface, ( index * 9 + 7 ), indexes[1] );
707 PicoSetSurfaceIndex( surface, ( index * 9 + 8 ), indexes[0] );
709 face = _ase_get_face_for_index( faces,index );
710 face->index[6] = indexes[2];
711 face->index[7] = indexes[1];
712 face->index[8] = indexes[0];
715 else if ( !_pico_stricmp( p->token, "*material" ) ) {
716 aseSubMaterial_t* subMaterial = NULL;
717 picoShader_t *shader = NULL;
718 int level = 1, index;
719 char materialName[ 1024 ];
720 float transValue = 0.0f, shineValue = 1.0f;
721 picoColor_t ambientColor, diffuseColor, specularColor;
722 char *mapname = NULL;
723 int subMtlId, subMaterialLevel = -1;
726 /* get material index */
727 _pico_parse_int( p,&index );
730 if ( !_pico_parse_check( p,1,"{" ) ) {
731 _ase_error_return( "Material missing opening brace" );
734 /* parse material block */
738 if ( _pico_parse( p,1 ) == NULL ) {
741 if ( !strlen( p->token ) ) {
746 if ( p->token[0] == '{' ) {
749 if ( p->token[0] == '}' ) {
756 if ( level == subMaterialLevel ) {
757 /* set material name */
758 PicoSetShaderName( shader, materialName );
760 /* set shader's transparency */
761 PicoSetShaderTransparency( shader,transValue );
763 /* set shader's ambient color */
764 PicoSetShaderAmbientColor( shader,ambientColor );
766 /* set diffuse alpha to transparency */
767 diffuseColor[3] = (picoByte_t)( transValue * 255.0 );
769 /* set shader's diffuse color */
770 PicoSetShaderDiffuseColor( shader,diffuseColor );
772 /* set shader's specular color */
773 PicoSetShaderSpecularColor( shader,specularColor );
775 /* set shader's shininess */
776 PicoSetShaderShininess( shader,shineValue );
778 /* set material map name */
779 PicoSetShaderMapName( shader, mapname );
781 subMaterial = _ase_add_submaterial( &materials, index, subMtlId, shader );
782 subMaterialLevel = -1;
785 /* parse submaterial index */
786 if ( !_pico_stricmp( p->token,"*submaterial" ) ) {
787 /* allocate new pico shader */
788 _pico_parse_int( p, &subMtlId );
790 shader = PicoNewShader( model );
791 if ( shader == NULL ) {
792 PicoFreeModel( model );
795 subMaterialLevel = level;
797 /* parse material name */
798 else if ( !_pico_stricmp( p->token,"*material_name" ) ) {
799 char* name = _pico_parse( p,0 );
800 if ( name == NULL ) {
801 _ase_error_return( "Missing material name" );
804 strcpy( materialName, name );
805 /* skip rest and continue with next token */
806 _pico_parse_skip_rest( p );
809 /* parse material transparency */
810 else if ( !_pico_stricmp( p->token,"*material_transparency" ) ) {
811 /* get transparency value from ase */
812 if ( !_pico_parse_float( p,&transValue ) ) {
813 _ase_error_return( "Material transparency parse error" );
816 /* skip rest and continue with next token */
817 _pico_parse_skip_rest( p );
820 /* parse material shininess */
821 else if ( !_pico_stricmp( p->token,"*material_shine" ) ) {
823 * - not sure but instead of '*material_shine' i might
824 * need to use '*material_shinestrength' */
826 /* get shine value from ase */
827 if ( !_pico_parse_float( p,&shineValue ) ) {
828 _ase_error_return( "Material shine parse error" );
831 /* scale ase shine range 0..1 to pico range 0..127 */
834 /* skip rest and continue with next token */
835 _pico_parse_skip_rest( p );
838 /* parse ambient material color */
839 else if ( !_pico_stricmp( p->token,"*material_ambient" ) ) {
841 /* get r,g,b float values from ase */
842 if ( !_pico_parse_vec( p,vec ) ) {
843 _ase_error_return( "Material color parse error" );
846 /* setup 0..255 range color values */
847 ambientColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
848 ambientColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
849 ambientColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
850 ambientColor[ 3 ] = (int)( 255 );
852 /* skip rest and continue with next token */
853 _pico_parse_skip_rest( p );
856 /* parse diffuse material color */
857 else if ( !_pico_stricmp( p->token,"*material_diffuse" ) ) {
860 /* get r,g,b float values from ase */
861 if ( !_pico_parse_vec( p,vec ) ) {
862 _ase_error_return( "Material color parse error" );
865 /* setup 0..255 range color */
866 diffuseColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
867 diffuseColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
868 diffuseColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
869 diffuseColor[ 3 ] = (int)( 255 );
871 /* skip rest and continue with next token */
872 _pico_parse_skip_rest( p );
875 /* parse specular material color */
876 else if ( !_pico_stricmp( p->token,"*material_specular" ) ) {
879 /* get r,g,b float values from ase */
880 if ( !_pico_parse_vec( p,vec ) ) {
881 _ase_error_return( "Material color parse error" );
884 /* setup 0..255 range color */
885 specularColor[ 0 ] = (int)( vec[ 0 ] * 255 );
886 specularColor[ 1 ] = (int)( vec[ 1 ] * 255 );
887 specularColor[ 2 ] = (int)( vec[ 2 ] * 255 );
888 specularColor[ 3 ] = (int)( 255 );
890 /* skip rest and continue with next token */
891 _pico_parse_skip_rest( p );
894 /* material diffuse map */
895 else if ( !_pico_stricmp( p->token,"*map_diffuse" ) ) {
898 /* parse material block */
902 if ( _pico_parse( p,1 ) == NULL ) {
905 if ( !strlen( p->token ) ) {
910 if ( p->token[0] == '{' ) {
913 if ( p->token[0] == '}' ) {
920 /* parse diffuse map bitmap */
921 if ( !_pico_stricmp( p->token,"*bitmap" ) ) {
922 char* name = _pico_parse( p,0 );
923 if ( name == NULL ) {
924 _ase_error_return( "Missing material map bitmap name" );
926 mapname = _pico_alloc( strlen( name ) + 1 );
927 strcpy( mapname, name );
928 /* skip rest and continue with next token */
929 _pico_parse_skip_rest( p );
934 /* end map_diffuse block */
936 /* end material block */
938 if ( subMaterial == NULL ) {
939 /* allocate new pico shader */
940 shader = PicoNewShader( model );
941 if ( shader == NULL ) {
942 PicoFreeModel( model );
946 /* set material name */
947 PicoSetShaderName( shader,materialName );
949 /* set shader's transparency */
950 PicoSetShaderTransparency( shader,transValue );
952 /* set shader's ambient color */
953 PicoSetShaderAmbientColor( shader,ambientColor );
955 /* set diffuse alpha to transparency */
956 diffuseColor[3] = (picoByte_t)( transValue * 255.0 );
958 /* set shader's diffuse color */
959 PicoSetShaderDiffuseColor( shader,diffuseColor );
961 /* set shader's specular color */
962 PicoSetShaderSpecularColor( shader,specularColor );
964 /* set shader's shininess */
965 PicoSetShaderShininess( shader,shineValue );
967 /* set material map name */
968 PicoSetShaderMapName( shader, mapname );
970 /* this is just a material with 1 submaterial */
971 subMaterial = _ase_add_submaterial( &materials, index, 0, shader );
974 /* ydnar: free mapname */
975 if ( mapname != NULL ) {
976 _pico_free( mapname );
978 } // !_pico_stricmp ( "*material" )
980 /* skip unparsed rest of line and continue */
981 _pico_parse_skip_rest( p );
984 /* ydnar: finish existing surface */
985 // _ase_make_surface( model, &surface );
986 _ase_submit_triangles( surface, model,materials,faces );
987 _ase_free_faces( &faces,&facesTail );
990 _ase_print_materials( materials );
992 elapsed = (double)( finish - start ) / CLOCKS_PER_SEC;
993 _pico_printf( PICO_NORMAL, "Loaded model in in %-.2f second(s)\n", elapsed );
994 #endif //DEBUG_PM_ASE
996 _ase_free_materials( &materials );
998 /* return allocated pico model */
1002 /* pico file format module definition */
1003 const picoModule_t picoModuleASE =
1005 "1.0", /* module version string */
1006 "Autodesk 3DSMAX ASCII", /* module display name */
1007 "Jared Hefty, seaw0lf", /* author's name */
1008 "2003 Jared Hefty, 2002 seaw0lf", /* module copyright */
1010 "ase",NULL,NULL,NULL /* default extensions to use */
1012 _ase_canload, /* validation routine */
1013 _ase_load, /* load routine */
1014 NULL, /* save validation routine */
1015 NULL /* save routine */