diff --git a/tools/quake3/q3map2/convert_ase.c b/tools/quake3/q3map2/convert_ase.c index 8b5c8f70..d2137258 100644 --- a/tools/quake3/q3map2/convert_ase.c +++ b/tools/quake3/q3map2/convert_ase.c @@ -35,6 +35,7 @@ /* dependencies */ #include "q3map2.h" +#include "convert_obj.h" @@ -44,7 +45,8 @@ */ int numLightmapsASE = 0; -static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin ){ + +static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin, const int* lmIndices ){ int i, v, face, a, b, c; bspDrawVert_t *dv; vec3_t normal; @@ -170,11 +172,12 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur fprintf( f, "\t*PROP_CASTSHADOW\t1\r\n" ); fprintf( f, "\t*PROP_RECVSHADOW\t1\r\n" ); if ( lightmapsAsTexcoord ) { - if ( ds->lightmapNum[0] >= 0 && ds->lightmapNum[0] + (int)deluxemap < numLightmapsASE ) { - fprintf( f, "\t*MATERIAL_REF\t%d\r\n", ds->lightmapNum[0] + deluxemap ); + const int lmNum = ds->lightmapNum[0] >= 0? ds->lightmapNum[0]: lmIndices[ds->shaderNum] >= 0? lmIndices[ds->shaderNum] : ds->lightmapNum[0]; + if ( lmNum >= 0 && lmNum + (int)deluxemap < numLightmapsASE ) { + fprintf( f, "\t*MATERIAL_REF\t%d\r\n", lmNum + deluxemap ); } else{ - Sys_Warning( "lightmap %d out of range, not exporting\n", ds->lightmapNum[0] + deluxemap ); + Sys_Warning( "lightmap %d out of range, not exporting\n", lmNum + deluxemap ); } } else{ @@ -190,7 +193,7 @@ static void ConvertSurface( FILE *f, bspModel_t *model, int modelNum, bspDrawSur exports a bsp model to an ase chunk */ -static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origin ){ +static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, const int* lmIndices ){ int i, s; bspDrawSurface_t *ds; @@ -200,7 +203,7 @@ static void ConvertModel( FILE *f, bspModel_t *model, int modelNum, vec3_t origi { s = i + model->firstBSPSurface; ds = &bspDrawSurfaces[ s ]; - ConvertSurface( f, model, modelNum, ds, s, origin ); + ConvertSurface( f, model, modelNum, ds, s, origin, lmIndices ); } } @@ -342,6 +345,7 @@ int ConvertBSPToASE( char *bspName ){ vec3_t origin; const char *key; char name[ 1024 ], base[ 1024 ], dirname[ 1024 ]; + int lmIndices[ numBSPShaders ]; /* note it */ @@ -379,22 +383,11 @@ int ConvertBSPToASE( char *bspName ){ /* print materials */ fprintf( f, "*MATERIAL_LIST\t{\r\n" ); if ( lightmapsAsTexcoord ) { - int lightmapCount; - for ( lightmapCount = 0; lightmapCount < numBSPLightmaps; lightmapCount++ ) - ; - for ( ; ; lightmapCount++ ) - { - char buf[1024]; - snprintf( buf, sizeof( buf ), "%s/" EXTERNAL_LIGHTMAP, dirname, lightmapCount ); - buf[sizeof( buf ) - 1] = 0; - if ( !FileExists( buf ) ) { - break; - } - } - fprintf( f, "\t*MATERIAL_COUNT\t%d\r\n", lightmapCount ); - for ( i = 0; i < lightmapCount; i++ ) + numLightmapsASE = Convert_CountLightmaps( dirname ); + fprintf( f, "\t*MATERIAL_COUNT\t%d\r\n", numLightmapsASE ); + for ( i = 0; i < numLightmapsASE; i++ ) ConvertLightmap( f, base, i ); - numLightmapsASE = lightmapCount; + Convert_ReferenceLightmaps( base, lmIndices ); } else { @@ -435,7 +428,7 @@ int ConvertBSPToASE( char *bspName ){ } /* convert model */ - ConvertModel( f, model, modelNum, origin ); + ConvertModel( f, model, modelNum, origin, lmIndices ); } /* close the file and return */ diff --git a/tools/quake3/q3map2/convert_obj.c b/tools/quake3/q3map2/convert_obj.c index e5d76d9c..e76244a4 100644 --- a/tools/quake3/q3map2/convert_obj.c +++ b/tools/quake3/q3map2/convert_obj.c @@ -45,11 +45,11 @@ int firstLightmap = 0; int lastLightmap = -1; -static void ConvertLightmapToMTL( FILE *f, const char *base, int lightmapNum ); int objVertexCount = 0; int objLastShaderNum = -1; -static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin ){ + +static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin, const int* lmIndices ){ int i, v, a, b, c; bspDrawVert_t *dv; @@ -71,7 +71,7 @@ static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDr /* export shader */ if ( lightmapsAsTexcoord ) { - const int lmNum = ds->lightmapNum[0]; + const int lmNum = ds->lightmapNum[0] >= 0? ds->lightmapNum[0]: lmIndices[ds->shaderNum] >= 0? lmIndices[ds->shaderNum] : ds->lightmapNum[0]; if ( objLastShaderNum != lmNum ) { fprintf( f, "usemtl lm_%04d\r\n", lmNum + deluxemap ); objLastShaderNum = lmNum + deluxemap; @@ -132,7 +132,7 @@ static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDr exports a bsp model to an ase chunk */ -static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, vec3_t origin ){ +static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, vec3_t origin, const int* lmIndices ){ int i, s; bspDrawSurface_t *ds; @@ -142,7 +142,7 @@ static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, vec3_t { s = i + model->firstBSPSurface; ds = &bspDrawSurfaces[ s ]; - ConvertSurfaceToOBJ( f, model, modelNum, ds, s, origin ); + ConvertSurfaceToOBJ( f, model, modelNum, ds, s, origin, lmIndices ); } } @@ -208,6 +208,92 @@ static void ConvertLightmapToMTL( FILE *f, const char *base, int lightmapNum ){ } +int Convert_CountLightmaps( const char* dirname ){ + int lightmapCount; + //FIXME numBSPLightmaps is 0, must be bspLightBytes / ( game->lightmapSize * game->lightmapSize * 3 ) + for ( lightmapCount = 0; lightmapCount < numBSPLightmaps; lightmapCount++ ) + ; + for ( ; ; lightmapCount++ ) + { + char buf[1024]; + snprintf( buf, sizeof( buf ), "%s/" EXTERNAL_LIGHTMAP, dirname, lightmapCount ); + buf[sizeof( buf ) - 1] = 0; + if ( !FileExists( buf ) ) { + break; + } + } + return lightmapCount; +} + +/* manage external lms, possibly referenced by q3map2_%mapname%.shader */ +void Convert_ReferenceLightmaps( const char* base, int* lmIndices ){ + for( int i = 0; i < numBSPShaders; ++i ) // initialize + lmIndices[i] = -1; + + char shaderfile[256]; + sprintf( shaderfile, "%s/q3map2_%s.shader", game->shaderPath, base ); + LoadScriptFile( shaderfile, 0 ); + /* tokenize it */ + while ( 1 ) + { + /* test for end of file */ + if ( !GetToken( qtrue ) ) + break; + + char shadername[256]; + strcpy( shadername, token ); + + /* handle { } section */ + if ( !GetToken( qtrue ) ) + break; + if ( *token != '{' ) + Error( "ParseShaderFile: %s, line %d: { not found!\nFound instead: %s\nFile location be: %s", + shaderfile, scriptline, token, g_strLoadedFileLocation ); + while ( 1 ) + { + /* get the next token */ + if ( !GetToken( qtrue ) ) + break; + if ( *token == '}' ) + break; + /* parse stage directives */ + if ( *token == '{' ) { + while ( 1 ) + { + if ( !GetToken( qtrue ) ) + break; + if ( *token == '}' ) + break; + if ( *token == '{' ) + Sys_FPrintf( SYS_WRN, "WARNING9: %s : line %d : opening brace inside shader stage\n", shaderfile, scriptline ); + + /* digest any images */ + if ( !Q_stricmp( token, "map" ) ) { + /* get an image */ + GetToken( qfalse ); + if ( *token != '*' && *token != '$' ) { + // map maps/bake_test_1/lm_0004.tga + int lmindex; + int okcount = 0; + if( sscanf( token + strlen( token ) - ( strlen( EXTERNAL_LIGHTMAP ) + 1 ), "/" EXTERNAL_LIGHTMAP "%n", &lmindex, &okcount ) + && okcount == ( strlen( EXTERNAL_LIGHTMAP ) + 1 ) ){ + for ( int i = 0; i < numBSPShaders; ++i ){ // find bspShaders[i]<->lmindex pair + if( !strcmp( bspShaders[i].shader, shadername ) ){ + lmIndices[i] = lmindex; + break; + } + } + } + } + } + } + } + } + } +} + + + /* ConvertBSPToASE() @@ -223,6 +309,7 @@ int ConvertBSPToOBJ( char *bspName ){ vec3_t origin; const char *key; char name[ 1024 ], base[ 1024 ], mtlname[ 1024 ], dirname[ 1024 ]; + int lmIndices[ numBSPShaders ]; /* note it */ @@ -259,20 +346,8 @@ int ConvertBSPToOBJ( char *bspName ){ fprintf( fmtl, "# Generated by Q3Map2 (ydnar) -convert -format obj\r\n" ); if ( lightmapsAsTexcoord ) { - int lightmapCount; - //FIXME numBSPLightmaps must be bspLightBytes / ( game->lightmapSize * game->lightmapSize * 3 ) - for ( lightmapCount = 0; lightmapCount < numBSPLightmaps; lightmapCount++ ) - ; - for ( ; ; lightmapCount++ ) - { - char buf[1024]; - snprintf( buf, sizeof( buf ), "%s/" EXTERNAL_LIGHTMAP, dirname, lightmapCount ); - buf[sizeof( buf ) - 1] = 0; - if ( !FileExists( buf ) ) { - break; - } - } - lastLightmap = lightmapCount - 1; + lastLightmap = Convert_CountLightmaps( dirname ) - 1; + Convert_ReferenceLightmaps( base, lmIndices ); } else { @@ -311,7 +386,7 @@ int ConvertBSPToOBJ( char *bspName ){ } /* convert model */ - ConvertModelToOBJ( f, model, modelNum, origin ); + ConvertModelToOBJ( f, model, modelNum, origin, lmIndices ); } if ( lightmapsAsTexcoord ) { diff --git a/tools/quake3/q3map2/convert_obj.h b/tools/quake3/q3map2/convert_obj.h new file mode 100644 index 00000000..40ac25d4 --- /dev/null +++ b/tools/quake3/q3map2/convert_obj.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. + + This file is part of GtkRadiant. + + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined( INCLUDED_CONVERT_OBJ_H ) +#define INCLUDED_CONVERT_OBJ_H + +int Convert_CountLightmaps( const char* dirname ); +void Convert_ReferenceLightmaps( const char* base, int* lmIndices ); + +#endif