Exemplo n.º 1
0
static int DoNextEditorDataChunk (T3dsLoaderPers *pers, long endofs)
{
    T3dsChunk *chunk;

#ifdef DEBUG_PM_3DS_EX
    printf("DoNextEditorDataChunk: endofs %d\n",endofs);
#endif
    while (pers->cofs < endofs)
    {
        long nextofs = pers->cofs;
        if ((chunk = GetChunk(pers)) == NULL) return 0;
        if (!chunk->len) return 0;
        nextofs += chunk->len;

#ifdef DEBUG_PM_3DS_EX
        printf("Chunk %04x (%s), len %d pers->cofs %x\n",chunk->id,DebugGetChunkName(chunk->id),chunk->len,pers->cofs);
#endif
        /*** meshes ***/
        if (chunk->id == CHUNK_OBJECT)
        {
            picoSurface_t *surface;
            char surfaceName[ 0xff ] = { 0 };

            /* read in surface name */
            if( !GetASCIIZ(pers,surfaceName,sizeof(surfaceName)) )
                return 0; /* this is bad */

//PicoGetSurfaceName
            /* ignore NULL name surfaces */
//            if( surfaceName

            /* allocate a pico surface */
            surface = PicoNewSurface( pers->model );
            if( surface == NULL )
            {
                pers->surface = NULL;
                return 0; /* this is bad too */
            }
            /* assign ptr to current surface */
            pers->surface = surface;

            /* 3ds models surfaces are all triangle meshes */
            PicoSetSurfaceType( pers->surface,PICO_TRIANGLES );

            /* set surface name */
            PicoSetSurfaceName( pers->surface,surfaceName );

            /* continue mess with object's sub chunks */
            DoNextEditorDataChunk(pers,nextofs);
            continue;
        }
        if (chunk->id == CHUNK_OBJECT_MESH)
        {
            /* continue mess with mesh's sub chunks */
            if (!DoNextEditorDataChunk(pers,nextofs)) return 0;
            continue;
        }
        if (chunk->id == CHUNK_OBJECT_VERTICES)
        {
            if (!GetMeshVertices(pers)) return 0;
            continue;
        }
        if (chunk->id == CHUNK_OBJECT_FACES)
        {
            if (!GetMeshFaces(pers)) return 0;
            continue;
        }
        if (chunk->id == CHUNK_OBJECT_UV)
        {
            if (!GetMeshTexCoords(pers)) return 0;
            continue;
        }
        if (chunk->id == CHUNK_OBJECT_MATERIAL)
        {
            if (!GetMeshShader(pers)) return 0;
            continue;
        }
        /*** materials ***/
        if (chunk->id == CHUNK_MATERIAL)
        {
            /* new shader specific things should be */
            /* initialized right here */
            picoShader_t *shader;

            /* allocate a pico shader */
            shader = PicoNewShader( pers->model );    /* ydnar */
            if( shader == NULL )
            {
                pers->shader = NULL;
                return 0; /* this is bad too */
            }
            
            /* assign ptr to current shader */
            pers->shader = shader;

            /* continue and process the material's sub chunks */
            DoNextEditorDataChunk(pers,nextofs);
            continue;
        }
        if (chunk->id == CHUNK_MATNAME)
        {
            /* new material's names should be stored here. note that */
            /* GetMeshMaterial returns the name of the material that */
            /* is used by the mesh. new material names are set HERE. */
            /* but for now we skip the new material's name ... */
            if (pers->shader)
            {
                char *name = (char*) (pers->bufptr + pers->cofs);
                char *cleanedName = _pico_clone_alloc( name );
                _pico_first_token( cleanedName );
                PicoSetShaderName( pers->shader, cleanedName );
#ifdef DEBUG_PM_3DS
                printf( "NewShader: '%s'\n", cleanedName );
#endif
                _pico_free( cleanedName );
            }
        }
        if (chunk->id == CHUNK_MATDIFFUSE)
        {
            /* todo: color for last inserted new material should be */
            /* stored somewhere by GetDiffuseColor */
            if (!GetDiffuseColor(pers)) return 0;

            /* rest of chunk is skipped here */
        }
        if (chunk->id == CHUNK_MATMAP)
        {
            /* continue and process the material map sub chunks */
            DoNextEditorDataChunk(pers,nextofs);
            continue;
        }
        if (chunk->id == CHUNK_MATMAPFILE)
        {
            /* map file name for last inserted new material should */
            /* be stored here. but for now we skip this too ... */
            if( pers->shader )
            {
                char *name = (char *)(pers->bufptr + pers->cofs);
                PicoSetShaderMapName( pers->shader,name );
#ifdef DEBUG_PM_3DS
                printf("NewShaderMapfile: '%s'\n",name);
#endif
            }
        }
        /*** keyframes ***/
        if (chunk->id == CHUNK_KEYFRAME_DATA)
        {
            /* well umm, this is a bit too much since we don't really */
            /* need model animation sequences right now. we skip this */
#ifdef DEBUG_PM_3DS
            printf("KeyframeData: len %d\n",chunk->len);
#endif
        }
        /* skip unknown chunk */
        pers->cofs = nextofs;
        if (pers->cofs >= pers->maxofs) break;
    }
    return 1;
}
Exemplo n.º 2
0
/* _ase_load:
 *  loads a 3dsmax ase model file.
*/
static picoModel_t *_ase_load( PM_PARAMS_LOAD )
{
	picoModel_t    *model;
	picoParser_t   *p;
	char			lastNodeName[ 1024 ];

	aseVertex_t* vertices = NULL;
	aseTexCoord_t* texcoords = NULL;
	aseColor_t* colors = NULL;
	aseFace_t* faces = NULL;
	int numVertices = 0;
	int numFaces = 0;
	int numTextureVertices = 0;
	int numTextureVertexFaces = 0;
	int numColorVertices = 0;
	int numColorVertexFaces = 0;
	int vertexId = 0;
   int currentVertexFace=0;
   int currentVertexIndex=0;
   int counter=0;
   int submodel=0;

	aseMaterial_t* materials = NULL;

#ifdef DEBUG_PM_ASE
	clock_t start, finish;
	double elapsed;
	start = clock();
#endif

	/* helper */
	#define _ase_error_return(m) \
	{ \
		_pico_printf( PICO_ERROR,"%s in ASE, line %d.",m,p->curLine); \
		_pico_free_parser( p ); \
		PicoFreeModel( model ); \
		return NULL; \
	}
	/* create a new pico parser */
	p = _pico_new_parser( (picoByte_t *)buffer,bufSize );
	if (p == NULL) return NULL;

	/* create a new pico model */
	model = PicoNewModel();
	if (model == NULL)
	{
		_pico_free_parser( p );
		return NULL;
	}
	/* do model setup */
	PicoSetModelFrameNum( model, frameNum );
	PicoSetModelName( model, fileName );
	PicoSetModelFileName( model, fileName );

	/* initialize some stuff */
	memset( lastNodeName,0,sizeof(lastNodeName) );

	/* parse ase model file */
	while( 1 )
	{
		/* get first token on line */
		if (_pico_parse_first( p ) == NULL)
			break;

		/* we just skip empty lines */
		if (p->token == NULL || !strlen( p->token ))
			continue;

		/* we skip invalid ase statements */
		if (p->token[0] != '*' && p->token[0] != '{' && p->token[0] != '}')
		{
			_pico_parse_skip_rest( p );
			continue;
		}
		/* remember node name */
		if (!_pico_stricmp(p->token,"*node_name"))
		{
			/* read node name */
			char *ptr = _pico_parse( p,0 );
			if (ptr == NULL)
				_ase_error_return("Node name parse error");

			/* remember node name */
			strncpy( lastNodeName,ptr,sizeof(lastNodeName) );
		}
		/* model mesh (originally contained within geomobject) */
		else if (!_pico_stricmp(p->token,"*mesh"))
		{
			/* finish existing surface */
			_ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces,numVertices,submodel++);
			_pico_free(faces);
			_pico_free(vertices);
			_pico_free(texcoords);
			_pico_free(colors);
		}
		else if (!_pico_stricmp(p->token,"*mesh_numvertex"))
		{
  			if (!_pico_parse_int( p, &numVertices) )
				_ase_error_return("Missing MESH_NUMVERTEX value");

			vertices = _pico_calloc(numVertices, sizeof(aseVertex_t));
         currentVertexIndex=0;   
		}
		else if (!_pico_stricmp(p->token,"*mesh_numfaces"))
		{
			if (!_pico_parse_int( p, &numFaces) )
				_ase_error_return("Missing MESH_NUMFACES value");

			faces = _pico_calloc(numFaces, sizeof(aseFace_t));

		}
		else if (!_pico_stricmp(p->token,"*mesh_numtvertex"))
		{
			if (!_pico_parse_int( p, &numTextureVertices) )
				_ase_error_return("Missing MESH_NUMTVERTEX value");

			texcoords = _pico_calloc(numTextureVertices, sizeof(aseTexCoord_t));
		}
		else if (!_pico_stricmp(p->token,"*mesh_numtvfaces"))
		{
			if (!_pico_parse_int( p, &numTextureVertexFaces) )
				_ase_error_return("Missing MESH_NUMTVFACES value");
		}
		else if (!_pico_stricmp(p->token,"*mesh_numcvertex"))
		{
			if (!_pico_parse_int( p, &numColorVertices) )
				_ase_error_return("Missing MESH_NUMCVERTEX value");

			colors = _pico_calloc(numColorVertices, sizeof(aseColor_t));
			memset( colors, 255, numColorVertices * sizeof( aseColor_t ) );	/* ydnar: force colors to white initially */
		}
		else if (!_pico_stricmp(p->token,"*mesh_numcvfaces"))
		{
			if (!_pico_parse_int( p, &numColorVertexFaces) )
				_ase_error_return("Missing MESH_NUMCVFACES value");
		}
		/* mesh material reference. this usually comes at the end of */
		/* geomobjects after the mesh blocks. we must assume that the */
		/* new mesh was already created so all we can do here is assign */
		/* the material reference id (shader index) now. */
		else if (!_pico_stricmp(p->token,"*material_ref"))
		{
			int mtlId;

			/* get the material ref (0..n) */
			if (!_pico_parse_int( p,&mtlId) )
				_ase_error_return("Missing material reference ID");

			{
				int i = 0;
				/* fix up all of the aseFaceList in the surface to point to the parent material */
				/* we've already saved off their subMtl */
				for(; i < numFaces; ++i)
				{
					faces[i].materialId = mtlId;
				}
			}
		}
		/* model mesh vertex */
		else if (!_pico_stricmp(p->token,"*mesh_vertex"))
		{
			int			index;

			if( numVertices == 0 )
				_ase_error_return("Vertex parse error");

			/* get vertex data (orig: index +y -x +z) */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Vertex parse error");
			if (!_pico_parse_vec( p,vertices[index].xyz ))
				_ase_error_return("Vertex parse error");

			vertices[index].id = vertexId++;
		}
		else if (!_pico_stricmp(p->token,"*mesh_facenormal"))
		{
		   //Grab the faceindex for the next vertex normals.
         if( numVertices == 0 )
				_ase_error_return("Vertex parse error (facenormals)");

         if (!_pico_parse_int( p,&currentVertexFace ))
				_ase_error_return("Vertex parse error");

 			if (!_pico_parse_vec( p,faces[currentVertexFace].facenormal ))
				_ase_error_return("Vertex parse error");

      }
      /* model mesh vertex normal */
		else if (!_pico_stricmp(p->token,"*mesh_vertexnormal"))
		{
			int			index;

			if( numVertices == 0 )
				_ase_error_return("Vertex parse error");

			/* get vertex data (orig: index +y -x +z) */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Vertex parse error");

         //^^ Index is 'wrong' in .ase models.  they reference the same vert index with multiple normals..
         // I've tried, this is a lost cause.  Use the SG's
         // 
			/*
         
         if (!_pico_parse_vec( p,vertices[counter].normal ))
				_ase_error_return("Vertex parse error");
         vertices[counter].faceid=index;
         counter++;
         */
		}
		/* model mesh face */
		else if (!_pico_stricmp(p->token,"*mesh_normals"))
      {
      //   counter=0; //part of the above vertex normals fix
      }
         
      /* model mesh face */
		else if (!_pico_stricmp(p->token,"*mesh_face"))
		{
			picoIndex_t indexes[3];
			int index;
			
			if( numFaces == 0 )
				_ase_error_return("Face parse error");

			/* get face index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Face parse error");

			/* get 1st vertex index */
			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[0] ))
				_ase_error_return("Face parse error");

			/* get 2nd vertex index */
			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[1] ))
				_ase_error_return("Face parse error");

			/* get 3rd vertex index */
			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[2] ))
				_ase_error_return("Face parse error");
			
			/* parse to the subMaterial ID */
			while ( 1 )
			{
				if (!_pico_parse (p,0)) /* EOL */
				{
					break;
				}
				if (!_pico_stricmp (p->token,"*MESH_SMOOTHING" ))
				{
               int total=0;
               char* point;
               char* start;
               _pico_parse(p,0);

               point=p->token;
               start=point;
               faces[index].smoothingGroup=0;
              
               //Super dodgy comma delimited string parse
               while (*point<'A') 
               {
                  if (*point<=32 || *point==',')
                  {
                     total=atoi(start);
                     if (total!=0)
                     {
                        faces[index].smoothingGroup+=1<<total;
                     }
                     start=point+1;
                  }
                  
                  point++;
               }
               
               
			      
               
            }
				if (!_pico_stricmp (p->token,"*MESH_MTLID" ))
				{
					_pico_parse_int ( p , &faces[index].subMaterialId );
				}
			}
			
			faces[index].materialId = 0;
			faces[index].indices[0] = indexes[2];
			faces[index].indices[1] = indexes[1];
			faces[index].indices[2] = indexes[0];
		}
		/* model texture vertex */
		else if (!_pico_stricmp(p->token,"*mesh_tvert"))
		{
			int			index;

			if( numVertices == 0 )
				_ase_error_return("Vertex parse error");

			/* get uv vertex index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("UV vertex parse error");

			/* get uv vertex s */
			if (!_pico_parse_float( p,&texcoords[index].texcoord[0] ))
				_ase_error_return("UV vertex parse error");

			/* get uv vertex t */
			if (!_pico_parse_float( p,&texcoords[index].texcoord[1] ))
				_ase_error_return("UV vertex parse error");
			
			/* ydnar: invert t */
			texcoords[index].texcoord[ 1 ] = 1.0f - texcoords[index].texcoord[ 1 ];
		}
		/* ydnar: model mesh texture face */
		else if( !_pico_stricmp( p->token, "*mesh_tface" ) )
		{
			picoIndex_t indexes[3];
			int			index;
			
			if( numFaces == 0 )
				_ase_error_return("Texture face parse error");
			
			/* get face index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Texture face parse error");
			
			/* get 1st vertex index */
			if (!_pico_parse_int( p,&indexes[0] ))
				_ase_error_return("Texture face parse error");
			
			/* get 2nd vertex index */
			if (!_pico_parse_int( p,&indexes[1] ))
				_ase_error_return("Texture face parse error");
			
			/* get 3rd vertex index */
			if (!_pico_parse_int( p,&indexes[2] ))
				_ase_error_return("Texture face parse error");

			faces[index].indices[3] = indexes[2];
			faces[index].indices[4] = indexes[1];
			faces[index].indices[5] = indexes[0];
		}
		/* model color vertex */
		else if (!_pico_stricmp(p->token,"*mesh_vertcol"))
		{
			int			index;
			float		colorInput;

			if( numVertices == 0 )
				_ase_error_return("Color Vertex parse error");

			/* get color vertex index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Color vertex parse error");

			/* get R component */
			if (!_pico_parse_float( p,&colorInput ))
				_ase_error_return("Color vertex parse error");
			colors[index].color[0] = (picoByte_t)(colorInput * 255);

			/* get G component */
			if (!_pico_parse_float( p,&colorInput ))
				_ase_error_return("Color vertex parse error");
			colors[index].color[1] = (picoByte_t)(colorInput * 255);

			/* get B component */
			if (!_pico_parse_float( p,&colorInput ))
				_ase_error_return("Color vertex parse error");
			colors[index].color[2] = (picoByte_t)(colorInput * 255);
			
			/* leave alpha alone since we don't get any data from the ASE format */
			colors[index].color[3] = 255;

         /* 27 hack, red as alpha */
         colors[index].color[3]=colors[index].color[0];
         colors[index].color[0]=255;
         colors[index].color[1]=255;
         colors[index].color[2]=255;

		}
		/* model color face */
		else if (!_pico_stricmp(p->token,"*mesh_cface"))
		{
			picoIndex_t indexes[3];
			int			index;

			if( numFaces == 0 )
				_ase_error_return("Face parse error");

			/* get face index */
			if (!_pico_parse_int( p,&index ))
				_ase_error_return("Face parse error");

			/* get 1st cvertex index */
			//			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[0] ))
				_ase_error_return("Face parse error");

			/* get 2nd cvertex index */
			//			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[1] ))
				_ase_error_return("Face parse error");

			/* get 3rd cvertex index */
			//			_pico_parse( p,0 );
			if (!_pico_parse_int( p,&indexes[2] ))
				_ase_error_return("Face parse error");

			faces[index].indices[6] = indexes[2];
			faces[index].indices[7] = indexes[1];
			faces[index].indices[8] = indexes[0];
		}
		/* model material */
		else if( !_pico_stricmp( p->token, "*material" ) )
		{
			aseSubMaterial_t*	subMaterial = NULL;
			picoShader_t		*shader;
			int					level = 1, index;
			char				materialName[ 1024 ];
			float				transValue = 0.0f, shineValue = 1.0f;
			picoColor_t			ambientColor, diffuseColor, specularColor;
			char				*mapname = NULL;
			int					subMtlId, subMaterialLevel = -1;
			
			
			/* get material index */
			_pico_parse_int( p,&index );
			
			/* check brace */
			if (!_pico_parse_check(p,1,"{"))
				_ase_error_return("Material missing opening brace");
			
			/* parse material block */
			while( 1 )
			{
				/* get next token */
				if (_pico_parse(p,1) == NULL) break;
				if (!strlen(p->token)) continue;

				/* handle levels */
				if (p->token[0] == '{') level++;
				if (p->token[0] == '}') level--;
				if (!level) break;

				if( level == subMaterialLevel )
				{
					/* set material name */
					_pico_first_token( materialName );
					PicoSetShaderName( shader, materialName);

					/* set shader's transparency */
					PicoSetShaderTransparency( shader,transValue );

					/* set shader's ambient color */
					PicoSetShaderAmbientColor( shader,ambientColor );

					/* set diffuse alpha to transparency */
					diffuseColor[3] = (picoByte_t)( transValue * 255.0 );

					/* set shader's diffuse color */
					PicoSetShaderDiffuseColor( shader,diffuseColor );

					/* set shader's specular color */
					PicoSetShaderSpecularColor( shader,specularColor );

					/* set shader's shininess */
					PicoSetShaderShininess( shader,shineValue );

					/* set material map name */
					PicoSetShaderMapName( shader, mapname );

					subMaterial = _ase_add_submaterial( &materials, index, subMtlId, shader );
					subMaterialLevel = -1;
				}

				/* parse submaterial index */
				if (!_pico_stricmp(p->token,"*submaterial"))
				{											
					/* allocate new pico shader */
					_pico_parse_int( p , &subMtlId );

					shader = PicoNewShader( model );
					if (shader == NULL)
					{
						PicoFreeModel( model );
						return NULL;
					}			
					subMaterialLevel = level;
				}
				/* parse material name */
				else if (!_pico_stricmp(p->token,"*material_name"))
				{
					char* name = _pico_parse(p,0);
					if ( name == NULL)
						_ase_error_return("Missing material name");
					
					strcpy ( materialName , name );
					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse material transparency */
				else if (!_pico_stricmp(p->token,"*material_transparency"))
				{
					/* get transparency value from ase */
					if (!_pico_parse_float( p,&transValue ))
						_ase_error_return("Material transparency parse error");

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse material shininess */
				else if (!_pico_stricmp(p->token,"*material_shine"))
				{
					/* remark:
					 * - not sure but instead of '*material_shine' i might
					 *   need to use '*material_shinestrength' */

					/* get shine value from ase */
					if (!_pico_parse_float( p,&shineValue ))
						_ase_error_return("Material shine parse error");

					/* scale ase shine range 0..1 to pico range 0..127 */
					shineValue *= 128.0;

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse ambient material color */
				else if (!_pico_stricmp(p->token,"*material_ambient"))
				{
					picoVec3_t  vec;
					/* get r,g,b float values from ase */
					if (!_pico_parse_vec( p,vec ))
						_ase_error_return("Material color parse error");

					/* setup 0..255 range color values */
					ambientColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
					ambientColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
					ambientColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
					ambientColor[ 3 ] = (int)( 255 );

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse diffuse material color */
				else if (!_pico_stricmp(p->token,"*material_diffuse"))
				{
					picoVec3_t  vec;

					/* get r,g,b float values from ase */
					if (!_pico_parse_vec( p,vec ))
						_ase_error_return("Material color parse error");

					/* setup 0..255 range color */
					diffuseColor[ 0 ] = (int)( vec[ 0 ] * 255.0 );
					diffuseColor[ 1 ] = (int)( vec[ 1 ] * 255.0 );
					diffuseColor[ 2 ] = (int)( vec[ 2 ] * 255.0 );
					diffuseColor[ 3 ] = (int)( 255 );

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* parse specular material color */
				else if (!_pico_stricmp(p->token,"*material_specular"))
				{
					picoVec3_t  vec;

					/* get r,g,b float values from ase */
					if (!_pico_parse_vec( p,vec ))
						_ase_error_return("Material color parse error");

					/* setup 0..255 range color */
					specularColor[ 0 ] = (int)( vec[ 0 ] * 255 );
					specularColor[ 1 ] = (int)( vec[ 1 ] * 255 );
					specularColor[ 2 ] = (int)( vec[ 2 ] * 255 );
					specularColor[ 3 ] = (int)( 255 );

					/* skip rest and continue with next token */
					_pico_parse_skip_rest( p );
					continue;
				}
				/* material diffuse map */
				else if (!_pico_stricmp(p->token,"*map_diffuse") )
				{
					int sublevel = 0;

					/* parse material block */
					while( 1 )
					{
						/* get next token */
						if (_pico_parse(p,1) == NULL) break;
						if (!strlen(p->token)) continue;
						
						/* handle levels */
						if (p->token[0] == '{') sublevel++;
						if (p->token[0] == '}') sublevel--;
						if (!sublevel) break;
						
						/* parse diffuse map bitmap */
						if (!_pico_stricmp(p->token,"*bitmap"))
						{
							char* name = _pico_parse(p,0);
							if (name == NULL)
								_ase_error_return("Missing material map bitmap name");
							mapname = _pico_alloc ( strlen ( name ) + 1 );
							strcpy ( mapname, name );
							/* skip rest and continue with next token */
							_pico_parse_skip_rest( p );
							continue;
						}
					}
				}
				/* end map_diffuse block */
			}
			/* end material block */

			if( subMaterial == NULL )
			{
				/* allocate new pico shader */
				shader = PicoNewShader( model );
				if (shader == NULL)
				{
					PicoFreeModel( model );
					return NULL;
				}

				/* set material name */
				PicoSetShaderName( shader,materialName );

				/* set shader's transparency */
				PicoSetShaderTransparency( shader,transValue );

				/* set shader's ambient color */
				PicoSetShaderAmbientColor( shader,ambientColor );

				/* set diffuse alpha to transparency */
				diffuseColor[3] = (picoByte_t)( transValue * 255.0 );

				/* set shader's diffuse color */
				PicoSetShaderDiffuseColor( shader,diffuseColor );

				/* set shader's specular color */
				PicoSetShaderSpecularColor( shader,specularColor );

				/* set shader's shininess */
				PicoSetShaderShininess( shader,shineValue );

				/* set material map name */
				PicoSetShaderMapName( shader, mapname );

        /* extract shadername from bitmap path */
        if(mapname != NULL)
        {
          char* p = mapname;

          /* convert to shader-name format */
          {
            /* unix-style path separators */
            char* s = mapname;
            for(; *s != '\0'; ++s)
            {
              if(*s == '\\')
              {
                *s = '/';
              }
            }
          }
          {
            /* remove extension */
            char* last_period = strrchr(p, '.');
            if(last_period != NULL)
            {
              *last_period = '\0';
            }
          }

          /* find game root */
          for(; *p != '\0'; ++p)
          {
            if(_pico_strnicmp(p, "quake", 5) == 0 || _pico_strnicmp(p, "doom", 4) == 0)
            {
              break;
            }
          }
          /* root-relative */
          for(; *p != '\0'; ++p)
          {
            if(*p == '/')
            {
              ++p;
              break;
            }
          }
          /* game-relative */
          for(; *p != '\0'; ++p)
          {
            if(*p == '/')
            {
              ++p;
              break;
            }
          }

          if(*p != '\0')
          {
				    /* set material name */
				    PicoSetShaderName( shader,p );
          }
        }

        /* this is just a material with 1 submaterial */
				subMaterial = _ase_add_submaterial( &materials, index, 0, shader );
			}
			
			/* ydnar: free mapname */
			if( mapname != NULL )
				_pico_free( mapname );
		}	// !_pico_stricmp ( "*material" )

		/* skip unparsed rest of line and continue */
		_pico_parse_skip_rest( p );
	}
	
	/* ydnar: finish existing surface */
	_ase_submit_triangles(model, materials, vertices, texcoords, colors, faces, numFaces,numVertices,submodel++);
	_pico_free(faces);
	_pico_free(vertices);
	_pico_free(texcoords);
	_pico_free(colors);

#ifdef DEBUG_PM_ASE
	_ase_print_materials(materials);
	finish = clock();
	elapsed = (double)(finish - start) / CLOCKS_PER_SEC;
	_pico_printf( PICO_NORMAL, "Loaded model in in %-.2f second(s)\n", elapsed );
#endif //DEBUG_PM_ASE

	_ase_free_materials(&materials);

  _pico_free_parser( p );

	/* return allocated pico model */
	return model;
}
Exemplo n.º 3
0
static int GetMeshShader (T3dsLoaderPers *pers)
{
    char shaderName[255] = { 0 };
    picoShader_t  *shader;
    int  numSharedVerts;
    int  setShaderName = 0;
    int  i;
    
    /* the shader is either the color or the texture map of the */
    /* object. it can also hold other information like the brightness, */
    /* shine, etc. stuff we don't really care about. we just want the */
    /* color, or the texture map file name really */

    /* get in the shader name */
    if (!GetASCIIZ(pers,shaderName,sizeof(shaderName)))
        return 0;
    
    /* ydnar: trim to first whitespace */
    _pico_first_token( shaderName );
    
    /* now that we have the shader name we need to go through all of */
    /* the shaders and check the name against each shader. when we */
    /* find a shader in our shader list that matches this name we */
    /* just read in, then we assign the shader's id of the object to */
    /* that shader */

    /* get shader id for shader name */
    shader = PicoFindShader( pers->model, shaderName, 1 );

    /* we've found a matching shader */
    if ((shader != NULL) && pers->surface)
    {
        char  mapName[1024+1];
        char *mapNamePtr;
        memset( mapName,0,sizeof(mapName) );

        /* get ptr to shader's map name */
        mapNamePtr = PicoGetShaderMapName( shader );

        /* we have a valid map name ptr */
        if (mapNamePtr != NULL)
        {
            char  temp[128];
            const char *name;

            /* copy map name to local buffer */
            strcpy( mapName,mapNamePtr );

            /* extract file name */
            name = _pico_nopath( mapName );
            strncpy( temp, name, sizeof(temp) );

            /* remove file extension */
            /* name = _pico_setfext( name,"" ); */

            /* assign default name if no name available */
            if (strlen(temp) < 1)
                strcpy(temp,pers->basename);

            /* build shader name */
            _pico_strlwr( temp ); /* gaynux update -sea */
            sprintf( mapName,"models/mapobjects/%s/%s",pers->basename,temp );

            /* set shader name */
            /* PicoSetShaderName( shader,mapName ); */    /* ydnar: this will screw up the named shader */

            /* set surface's shader index */
            PicoSetSurfaceShader( pers->surface, shader );

            setShaderName = 1;
        }
    }
    /* we didn't set a shader name; throw out warning */
    if (!setShaderName)
    {
        _pico_printf( PICO_WARNING,"3DS mesh is missing shader name");
    }
    /* we don't process the list of shared vertices here; there is a */
    /* short int that gives the number of faces of the mesh concerned */
    /* by this shader, then there is the list itself of these faces. */
    /* 0000 means the first face of the (4120) face list */

    /* get number of shared verts */
    numSharedVerts = GetWord(pers);

#ifdef DEBUG_PM_3DS
    printf("GetMeshShader: uses shader '%s' (nsv %d)\n",shaderName,numSharedVerts);
#endif
    /* skip list of shared verts */
    for (i=0; i<numSharedVerts; i++)
    {
        GetWord(pers);
    }
    /* success (no errors occured) */
    return 1;
}