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 )
77 aseMaterial_t* mtl = list;
81 if ( mtlIdParent == mtl->mtlId )
90 static aseSubMaterial_t* _ase_get_submaterial ( aseMaterial_t* list, int mtlIdParent , int subMtlId )
92 aseMaterial_t* parent = _ase_get_material ( list , mtlIdParent );
93 aseSubMaterial_t* subMtl = NULL;
97 _pico_printf ( PICO_ERROR , "No ASE material exists with id %i\n" , mtlIdParent );
101 subMtl = parent->subMtls;
104 if ( subMtlId == subMtl->subMtlId )
108 subMtl = subMtl->next;
113 static aseMaterial_t* _ase_add_material( aseMaterial_t **list, int mtlIdParent )
115 aseMaterial_t *mtl = _pico_calloc( 1, sizeof( aseMaterial_t ) );
116 mtl->mtlId = mtlIdParent;
124 static aseSubMaterial_t* _ase_add_submaterial( aseMaterial_t **list, int mtlIdParent, int subMtlId, picoShader_t* shader )
126 aseMaterial_t *parent = _ase_get_material( *list, mtlIdParent );
127 aseSubMaterial_t *subMtl = _pico_calloc( 1, sizeof ( aseSubMaterial_t ) );
131 parent = _ase_add_material ( list , mtlIdParent );
134 subMtl->shader = shader;
135 subMtl->subMtlId = subMtlId;
136 subMtl->next = parent->subMtls;
137 parent->subMtls = subMtl;
142 static void _ase_free_materials( aseMaterial_t **list )
144 aseMaterial_t* mtl = *list;
145 aseSubMaterial_t* subMtl = NULL;
147 aseMaterial_t* mtlTemp = NULL;
148 aseSubMaterial_t* subMtlTemp = NULL;
152 subMtl = mtl->subMtls;
155 subMtlTemp = subMtl->next;
156 _pico_free ( subMtl );
167 static void _ase_print_materials( aseMaterial_t *list )
169 aseMaterial_t* mtl = list;
170 aseSubMaterial_t* subMtl = NULL;
174 _pico_printf ( PICO_NORMAL , "ASE Material %i" , mtl->mtlId );
175 subMtl = mtl->subMtls;
178 _pico_printf ( PICO_NORMAL , " -- ASE SubMaterial %i - %s\n" , subMtl->subMtlId , subMtl->shader->name );
179 subMtl = subMtl->next;
184 #endif //DEBUG_PM_ASE
186 /* ASE Face management */
187 /* These are used to keep an association between a submaterial and a face definition */
188 /* They are kept in parallel with the current picoSurface, */
189 /* and are used by _ase_submit_triangles to lookup the proper material/submaterial IDs */
190 typedef struct aseFace_s
192 struct aseFace_s* next;
198 /* ASE Face management functions */
199 void _ase_add_face( aseFace_t **list, aseFace_t **tail, aseFace_t *newFace )
201 /* insert as head of list */
208 (*tail)->next = newFace;
212 newFace->next = NULL;
214 //tag the color indices so we can detect them and apply the default color to them
215 newFace->index[6] = -1;
216 newFace->index[7] = -1;
217 newFace->index[8] = -1;
220 aseFace_t* _ase_get_face_for_index( aseFace_t *list, int index )
223 aseFace_t* face = list;
225 while ( counter < index )
232 static void _ase_free_faces (aseFace_t** list, aseFace_t** tail )
234 aseFace_t* face = *list;
235 aseFace_t* tempFace = NULL;
239 tempFace = face->next;
249 * - apply material specific uv offsets to uv coordinates
253 * validates a 3dsmax ase model file.
255 static int _ase_canload( PM_PARAMS_CANLOAD )
260 /* quick data length validation */
262 return PICO_PMV_ERROR_SIZE;
264 /* keep the friggin compiler happy */
265 *fileName = *fileName;
267 /* create pico parser */
268 p = _pico_new_parser( (picoByte_t*) buffer, bufSize );
270 return PICO_PMV_ERROR_MEMORY;
272 /* get first token */
273 if( _pico_parse_first( p ) == NULL)
275 return PICO_PMV_ERROR_IDENT;
278 /* check first token */
279 if( _pico_stricmp( p->token, "*3dsmax_asciiexport" ) )
281 _pico_free_parser( p );
282 return PICO_PMV_ERROR_IDENT;
285 /* free the pico parser object */
286 _pico_free_parser( p );
288 /* file seems to be a valid ase file */
294 /* _ase_submit_triangles - jhefty
295 use the surface and the current face list to look up material/submaterial IDs
296 and submit them to the model for proper processing
298 The following still holds from ydnar's _ase_make_surface:
299 indexes 0 1 2 = vert indexes
300 indexes 3 4 5 = st indexes
301 indexes 6 7 8 = color indexes (new)
304 static void _ase_submit_triangles ( picoSurface_t* surface , picoModel_t* model , aseMaterial_t* materials , aseFace_t* faces )
307 aseSubMaterial_t* subMtl;
309 picoVec3_t* normal[3];
311 picoColor_t* color[3];
315 while ( face != NULL )
317 /* look up the shader for the material/submaterial pair */
318 subMtl = _ase_get_submaterial( materials, face->mtlId, face->subMtlId );
321 /* ydnar: trying default submaterial */
322 subMtl = _ase_get_submaterial( materials, face->mtlId, 0 );
325 _pico_printf( PICO_ERROR, "Could not find material/submaterial for id %d/%d\n", face->mtlId, face->subMtlId );
330 /* we pull the data from the surface using the facelist data */
331 for ( i = 0 ; i < 3 ; i ++ )
333 xyz[i] = (picoVec3_t*) PicoGetSurfaceXYZ ( surface, face->index[ i ] );
334 normal[i] = (picoVec3_t*) PicoGetSurfaceNormal( surface, face->index[ i ] );
335 st[i] = (picoVec2_t*) PicoGetSurfaceST ( surface, 0, face->index[ i + 3 ] );
337 if ( face->index [ i + 6] >= 0 )
339 color[i] = (picoColor_t*)PicoGetSurfaceColor ( surface, 0, face->index[ i + 6 ] );
348 /* submit the triangle to the model */
349 PicoAddTriangleToModel ( model , xyz , normal , 1 , st , 1 , color , subMtl->shader );
351 /* advance to the next face */
357 * loads a 3dsmax ase model file.
359 static picoModel_t *_ase_load( PM_PARAMS_LOAD )
362 picoSurface_t *surface = NULL;
364 char lastNodeName[ 1024 ];
366 aseFace_t* faces = NULL;
367 aseFace_t* facesTail = NULL;
368 aseMaterial_t* materials = NULL;
371 clock_t start, finish;
377 #define _ase_error_return(m) \
379 _pico_printf( PICO_ERROR,"%s in ASE, line %d.",m,p->curLine); \
380 _pico_free_parser( p ); \
381 PicoFreeModel( model ); \
384 /* create a new pico parser */
385 p = _pico_new_parser( (picoByte_t *)buffer,bufSize );
386 if (p == NULL) return NULL;
388 /* create a new pico model */
389 model = PicoNewModel();
392 _pico_free_parser( p );
396 PicoSetModelFrameNum( model, frameNum );
397 PicoSetModelName( model, fileName );
398 PicoSetModelFileName( model, fileName );
400 /* initialize some stuff */
401 memset( lastNodeName,0,sizeof(lastNodeName) );
403 /* parse ase model file */
406 /* get first token on line */
407 if (_pico_parse_first( p ) == NULL)
410 /* we just skip empty lines */
411 if (p->token == NULL || !strlen( p->token ))
414 /* we skip invalid ase statements */
415 if (p->token[0] != '*' && p->token[0] != '{' && p->token[0] != '}')
417 _pico_parse_skip_rest( p );
420 /* remember node name */
421 if (!_pico_stricmp(p->token,"*node_name"))
424 char *ptr = _pico_parse( p,0 );
426 _ase_error_return("Node name parse error");
428 /* remember node name */
429 strncpy( lastNodeName,ptr,sizeof(lastNodeName) );
431 /* model mesh (originally contained within geomobject) */
432 else if (!_pico_stricmp(p->token,"*mesh"))
434 /* finish existing surface */
435 //_ase_make_surface( model, &surface );
436 _ase_submit_triangles (surface, model ,materials,faces);
437 _ase_free_faces (&faces,&facesTail);
439 /* allocate new pico surface */
440 surface = PicoNewSurface( NULL );
443 PicoFreeModel( model );
447 /* mesh material reference. this usually comes at the end of */
448 /* geomobjects after the mesh blocks. we must assume that the */
449 /* new mesh was already created so all we can do here is assign */
450 /* the material reference id (shader index) now. */
451 else if (!_pico_stricmp(p->token,"*material_ref"))
456 /* we must have a valid surface */
457 if( surface == NULL )
458 _ase_error_return("Missing mesh for material reference");
460 /* get the material ref (0..n) */
461 if (!_pico_parse_int( p,&mtlId) )
462 _ase_error_return("Missing material reference ID");
464 /* fix up all of the aseFaceList in the surface to point to the parent material */
465 /* we've already saved off their subMtl */
467 while ( face != NULL )
473 /* model mesh vertex */
474 else if (!_pico_stricmp(p->token,"*mesh_vertex"))
479 /* we must have a valid surface */
480 if( surface == NULL )
483 /* get vertex data (orig: index +y -x +z) */
484 if (!_pico_parse_int( p,&index ))
485 _ase_error_return("Vertex parse error");
486 if (!_pico_parse_vec( p,v ))
487 _ase_error_return("Vertex parse error");
490 PicoSetSurfaceXYZ( surface,index,v );
492 /* model mesh vertex normal */
493 else if (!_pico_stricmp(p->token,"*mesh_vertexnormal"))
498 /* we must have a valid surface */
499 if( surface == NULL )
502 /* get vertex data (orig: index +y -x +z) */
503 if (!_pico_parse_int( p,&index ))
504 _ase_error_return("Vertex parse error");
505 if (!_pico_parse_vec( p,v ))
506 _ase_error_return("Vertex parse error");
509 PicoSetSurfaceNormal( surface,index,v );
511 /* model mesh face */
512 else if (!_pico_stricmp(p->token,"*mesh_face"))
514 picoIndex_t indexes[3];
517 /* we must have a valid surface */
518 if( surface == NULL )
522 if (!_pico_parse_int( p,&index ))
523 _ase_error_return("Face parse error");
525 /* get 1st vertex index */
527 if (!_pico_parse_int( p,&indexes[0] ))
528 _ase_error_return("Face parse error");
530 /* get 2nd vertex index */
532 if (!_pico_parse_int( p,&indexes[1] ))
533 _ase_error_return("Face parse error");
535 /* get 3rd vertex index */
537 if (!_pico_parse_int( p,&indexes[2] ))
538 _ase_error_return("Face parse error");
540 /* set face indexes (note interleaved offset!) */
541 PicoSetSurfaceIndex( surface, (index * 9 + 0), indexes[2] );
542 PicoSetSurfaceIndex( surface, (index * 9 + 1), indexes[1] );
543 PicoSetSurfaceIndex( surface, (index * 9 + 2), indexes[0] );
545 /* parse to the subMaterial ID */
549 if (!_pico_stricmp (p->token,"*MESH_MTLID" ))
554 _pico_parse_int ( p , &subMtlId );
555 newFace = _pico_calloc ( 1 , sizeof ( aseFace_t ));
557 /* we fix up the mtlId later when we parse the material_ref */
559 newFace->subMtlId = subMtlId;
560 newFace->index[0] = indexes[2];
561 newFace->index[1] = indexes[1];
562 newFace->index[2] = indexes[0];
564 _ase_add_face ( &faces,&facesTail,newFace );
570 /* model texture vertex */
571 else if (!_pico_stricmp(p->token,"*mesh_tvert"))
576 /* we must have a valid surface */
577 if( surface == NULL )
580 /* get uv vertex index */
581 if (!_pico_parse_int( p,&index ))
582 _ase_error_return("UV vertex parse error");
584 /* get uv vertex s */
585 if (!_pico_parse_float( p,&uv[0] ))
586 _ase_error_return("UV vertex parse error");
588 /* get uv vertex t */
589 if (!_pico_parse_float( p,&uv[1] ))
590 _ase_error_return("UV vertex parse error");
592 /* ydnar: invert t */
593 uv[ 1 ] = 1.0f - uv[ 1 ];
595 /* set texture vertex */
596 PicoSetSurfaceST( surface,0,index,uv );
598 /* ydnar: model mesh texture face */
599 else if( !_pico_stricmp( p->token, "*mesh_tface" ) )
601 picoIndex_t indexes[3];
605 /* we must have a valid surface */
606 if( surface == NULL )
610 if (!_pico_parse_int( p,&index ))
611 _ase_error_return("Texture face parse error");
613 /* get 1st vertex index */
614 if (!_pico_parse_int( p,&indexes[0] ))
615 _ase_error_return("Texture face parse error");
617 /* get 2nd vertex index */
618 if (!_pico_parse_int( p,&indexes[1] ))
619 _ase_error_return("Texture face parse error");
621 /* get 3rd vertex index */
622 if (!_pico_parse_int( p,&indexes[2] ))
623 _ase_error_return("Texture face parse error");
625 /* set face indexes (note interleaved offset!) */
626 PicoSetSurfaceIndex( surface, (index * 9 + 3), indexes[2] );
627 PicoSetSurfaceIndex( surface, (index * 9 + 4), indexes[1] );
628 PicoSetSurfaceIndex( surface, (index * 9 + 5), indexes[0] );
630 face = _ase_get_face_for_index(faces,index);
631 face->index[3] = indexes[2];
632 face->index[4] = indexes[1];
633 face->index[5] = indexes[0];
635 /* model color vertex */
636 else if (!_pico_stricmp(p->token,"*mesh_vertcol"))
642 /* we must have a valid surface */
643 if( surface == NULL )
646 /* get color vertex index */
647 if (!_pico_parse_int( p,&index ))
648 _ase_error_return("UV vertex parse error");
650 /* get R component */
651 if (!_pico_parse_float( p,&colorInput ))
652 _ase_error_return("color vertex parse error");
653 color[0] = (picoByte_t)(colorInput * 255);
655 /* get G component */
656 if (!_pico_parse_float( p,&colorInput ))
657 _ase_error_return("color vertex parse error");
658 color[1] = (picoByte_t)(colorInput * 255);
660 /* get B component */
661 if (!_pico_parse_float( p,&colorInput ))
662 _ase_error_return("color vertex parse error");
663 color[2] = (picoByte_t)(colorInput * 255);
665 /* leave alpha alone since we don't get any data from the ASE format */
668 /* set texture vertex */
669 PicoSetSurfaceColor( surface,0,index,color );
671 /* model color face */
672 else if (!_pico_stricmp(p->token,"*mesh_cface"))
674 picoIndex_t indexes[3];
678 /* we must have a valid surface */
679 if( surface == NULL )
683 if (!_pico_parse_int( p,&index ))
684 _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");
691 /* get 2nd cvertex index */
692 // _pico_parse( p,0 );
693 if (!_pico_parse_int( p,&indexes[1] ))
694 _ase_error_return("Face parse error");
696 /* get 3rd cvertex index */
697 // _pico_parse( p,0 );
698 if (!_pico_parse_int( p,&indexes[2] ))
699 _ase_error_return("Face parse error");
701 /* set face indexes (note interleaved offset!) */
702 PicoSetSurfaceIndex( surface, (index * 9 + 6), indexes[2] );
703 PicoSetSurfaceIndex( surface, (index * 9 + 7), indexes[1] );
704 PicoSetSurfaceIndex( surface, (index * 9 + 8), indexes[0] );
706 face = _ase_get_face_for_index(faces,index);
707 face->index[6] = indexes[2];
708 face->index[7] = indexes[1];
709 face->index[8] = indexes[0];
712 else if( !_pico_stricmp( p->token, "*material" ) )
714 aseSubMaterial_t* subMaterial = NULL;
715 picoShader_t *shader = NULL;
716 int level = 1, index;
717 char materialName[ 1024 ];
718 float transValue = 0.0f, shineValue = 1.0f;
719 picoColor_t ambientColor, diffuseColor, specularColor;
720 char *mapname = NULL;
721 int subMtlId, subMaterialLevel = -1;
724 /* get material index */
725 _pico_parse_int( p,&index );
728 if (!_pico_parse_check(p,1,"{"))
729 _ase_error_return("Material missing opening brace");
731 /* parse material block */
735 if (_pico_parse(p,1) == NULL) break;
736 if (!strlen(p->token)) continue;
739 if (p->token[0] == '{') level++;
740 if (p->token[0] == '}') level--;
743 if( level == subMaterialLevel )
745 /* set material name */
746 PicoSetShaderName( shader, materialName);
748 /* set shader's transparency */
749 PicoSetShaderTransparency( shader,transValue );
751 /* set shader's ambient color */
752 PicoSetShaderAmbientColor( shader,ambientColor );
754 /* set diffuse alpha to transparency */
755 diffuseColor[3] = (picoByte_t)( transValue * 255.0 );
757 /* set shader's diffuse color */
758 PicoSetShaderDiffuseColor( shader,diffuseColor );
760 /* set shader's specular color */
761 PicoSetShaderSpecularColor( shader,specularColor );
763 /* set shader's shininess */
764 PicoSetShaderShininess( shader,shineValue );
766 /* set material map name */
767 PicoSetShaderMapName( shader, mapname );
769 subMaterial = _ase_add_submaterial( &materials, index, subMtlId, shader );
770 subMaterialLevel = -1;
773 /* parse submaterial index */
774 if (!_pico_stricmp(p->token,"*submaterial"))
776 /* allocate new pico shader */
777 _pico_parse_int( p , &subMtlId );
779 shader = PicoNewShader( model );
782 PicoFreeModel( model );
785 subMaterialLevel = level;
787 /* parse material name */
788 else if (!_pico_stricmp(p->token,"*material_name"))
790 char* name = _pico_parse(p,0);
792 _ase_error_return("Missing material name");
794 strcpy ( materialName , name );
795 /* skip rest and continue with next token */
796 _pico_parse_skip_rest( p );
799 /* parse material transparency */
800 else if (!_pico_stricmp(p->token,"*material_transparency"))
802 /* get transparency value from ase */
803 if (!_pico_parse_float( p,&transValue ))
804 _ase_error_return("Material transparency parse error");
806 /* skip rest and continue with next token */
807 _pico_parse_skip_rest( p );
810 /* parse material shininess */
811 else if (!_pico_stricmp(p->token,"*material_shine"))
814 * - not sure but instead of '*material_shine' i might
815 * need to use '*material_shinestrength' */
817 /* get shine value from ase */
818 if (!_pico_parse_float( p,&shineValue ))
819 _ase_error_return("Material shine parse error");
821 /* scale ase shine range 0..1 to pico range 0..127 */
824 /* skip rest and continue with next token */
825 _pico_parse_skip_rest( p );
828 /* parse ambient material color */
829 else if (!_pico_stricmp(p->token,"*material_ambient"))
832 /* get r,g,b float values from ase */
833 if (!_pico_parse_vec( p,vec ))
834 _ase_error_return("Material color parse error");
836 /* setup 0..255 range color values */
837 ambientColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
838 ambientColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
839 ambientColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
840 ambientColor[ 3 ] = (int)( 255 );
842 /* skip rest and continue with next token */
843 _pico_parse_skip_rest( p );
846 /* parse diffuse material color */
847 else if (!_pico_stricmp(p->token,"*material_diffuse"))
851 /* get r,g,b float values from ase */
852 if (!_pico_parse_vec( p,vec ))
853 _ase_error_return("Material color parse error");
855 /* setup 0..255 range color */
856 diffuseColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
857 diffuseColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
858 diffuseColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
859 diffuseColor[ 3 ] = (int)( 255 );
861 /* skip rest and continue with next token */
862 _pico_parse_skip_rest( p );
865 /* parse specular material color */
866 else if (!_pico_stricmp(p->token,"*material_specular"))
870 /* get r,g,b float values from ase */
871 if (!_pico_parse_vec( p,vec ))
872 _ase_error_return("Material color parse error");
874 /* setup 0..255 range color */
875 specularColor[ 0 ] = (int)( vec[ 0 ] * 255 );
876 specularColor[ 1 ] = (int)( vec[ 1 ] * 255 );
877 specularColor[ 2 ] = (int)( vec[ 2 ] * 255 );
878 specularColor[ 3 ] = (int)( 255 );
880 /* skip rest and continue with next token */
881 _pico_parse_skip_rest( p );
884 /* material diffuse map */
885 else if (!_pico_stricmp(p->token,"*map_diffuse") )
889 /* parse material block */
893 if (_pico_parse(p,1) == NULL) break;
894 if (!strlen(p->token)) continue;
897 if (p->token[0] == '{') sublevel++;
898 if (p->token[0] == '}') sublevel--;
899 if (!sublevel) break;
901 /* parse diffuse map bitmap */
902 if (!_pico_stricmp(p->token,"*bitmap"))
904 char* name = _pico_parse(p,0);
906 _ase_error_return("Missing material map bitmap name");
907 mapname = _pico_alloc ( strlen ( name ) + 1 );
908 strcpy ( mapname, name );
909 /* skip rest and continue with next token */
910 _pico_parse_skip_rest( p );
915 /* end map_diffuse block */
917 /* end material block */
919 if( subMaterial == NULL )
921 /* allocate new pico shader */
922 shader = PicoNewShader( model );
925 PicoFreeModel( model );
929 /* set material name */
930 PicoSetShaderName( shader,materialName );
932 /* set shader's transparency */
933 PicoSetShaderTransparency( shader,transValue );
935 /* set shader's ambient color */
936 PicoSetShaderAmbientColor( shader,ambientColor );
938 /* set diffuse alpha to transparency */
939 diffuseColor[3] = (picoByte_t)( transValue * 255.0 );
941 /* set shader's diffuse color */
942 PicoSetShaderDiffuseColor( shader,diffuseColor );
944 /* set shader's specular color */
945 PicoSetShaderSpecularColor( shader,specularColor );
947 /* set shader's shininess */
948 PicoSetShaderShininess( shader,shineValue );
950 /* set material map name */
951 PicoSetShaderMapName( shader, mapname );
953 /* this is just a material with 1 submaterial */
954 subMaterial = _ase_add_submaterial( &materials, index, 0, shader );
957 /* ydnar: free mapname */
958 if( mapname != NULL )
959 _pico_free( mapname );
960 } // !_pico_stricmp ( "*material" )
962 /* skip unparsed rest of line and continue */
963 _pico_parse_skip_rest( p );
966 /* ydnar: finish existing surface */
967 // _ase_make_surface( model, &surface );
968 _ase_submit_triangles (surface, model ,materials,faces);
969 _ase_free_faces (&faces,&facesTail);
972 _ase_print_materials(materials);
974 elapsed = (double)(finish - start) / CLOCKS_PER_SEC;
975 _pico_printf( PICO_NORMAL, "Loaded model in in %-.2f second(s)\n", elapsed );
976 #endif //DEBUG_PM_ASE
978 _ase_free_materials(&materials);
980 /* return allocated pico model */
984 /* pico file format module definition */
985 const picoModule_t picoModuleASE =
987 "1.0", /* module version string */
988 "Autodesk 3DSMAX ASCII", /* module display name */
989 "Jared Hefty, seaw0lf", /* author's name */
990 "2003 Jared Hefty, 2002 seaw0lf", /* module copyright */
992 "ase",NULL,NULL,NULL /* default extensions to use */
994 _ase_canload, /* validation routine */
995 _ase_load, /* load routine */
996 NULL, /* save validation routine */
997 NULL /* save routine */