int BSPMain( int argc, char **argv ){ int i; char path[ 1024 ], tempSource[ 1024 ]; qboolean onlyents = qfalse; /* note it */ Sys_Printf( "--- BSP ---\n" ); SetDrawSurfacesBuffer(); mapDrawSurfs = safe_malloc( sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS ); memset( mapDrawSurfs, 0, sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS ); numMapDrawSurfs = 0; tempSource[ 0 ] = '\0'; globalCelShader[0] = 0; /* set standard game flags */ maxSurfaceVerts = game->maxSurfaceVerts; maxSurfaceIndexes = game->maxSurfaceIndexes; emitFlares = game->emitFlares; texturesRGB = game->texturesRGB; colorsRGB = game->colorsRGB; /* process arguments */ for ( i = 1; i < ( argc - 1 ); i++ ) { if ( !strcmp( argv[ i ], "-onlyents" ) ) { Sys_Printf( "Running entity-only compile\n" ); onlyents = qtrue; } else if ( !strcmp( argv[ i ], "-tempname" ) ) { strcpy( tempSource, argv[ ++i ] ); } else if ( !strcmp( argv[ i ], "-tmpout" ) ) { strcpy( outbase, "/tmp" ); } else if ( !strcmp( argv[ i ], "-nowater" ) ) { Sys_Printf( "Disabling water\n" ); nowater = qtrue; } else if ( !strcmp( argv[ i ], "-keeplights" ) ) { keepLights = qtrue; Sys_Printf( "Leaving light entities on map after compile\n" ); } else if ( !strcmp( argv[ i ], "-nodetail" ) ) { Sys_Printf( "Ignoring detail brushes\n" ) ; nodetail = qtrue; } else if ( !strcmp( argv[ i ], "-fulldetail" ) ) { Sys_Printf( "Turning detail brushes into structural brushes\n" ); fulldetail = qtrue; } else if ( !strcmp( argv[ i ], "-nofog" ) ) { Sys_Printf( "Fog volumes disabled\n" ); nofog = qtrue; } else if ( !strcmp( argv[ i ], "-nosubdivide" ) ) { Sys_Printf( "Disabling brush face subdivision\n" ); nosubdivide = qtrue; } else if ( !strcmp( argv[ i ], "-leaktest" ) ) { Sys_Printf( "Leaktest enabled\n" ); leaktest = qtrue; } else if ( !strcmp( argv[ i ], "-verboseentities" ) ) { Sys_Printf( "Verbose entities enabled\n" ); verboseEntities = qtrue; } else if ( !strcmp( argv[ i ], "-nocurves" ) ) { Sys_Printf( "Ignoring curved surfaces (patches)\n" ); noCurveBrushes = qtrue; } else if ( !strcmp( argv[ i ], "-notjunc" ) ) { Sys_Printf( "T-junction fixing disabled\n" ); notjunc = qtrue; } else if ( !strcmp( argv[ i ], "-fakemap" ) ) { Sys_Printf( "Generating fakemap.map\n" ); fakemap = qtrue; } else if ( !strcmp( argv[ i ], "-samplesize" ) ) { sampleSize = atoi( argv[ i + 1 ] ); if ( sampleSize < 1 ) { sampleSize = 1; } i++; Sys_Printf( "Lightmap sample size set to %dx%d units\n", sampleSize, sampleSize ); } else if ( !strcmp( argv[ i ], "-minsamplesize" ) ) { minSampleSize = atoi( argv[ i + 1 ] ); if ( minSampleSize < 1 ) { minSampleSize = 1; } i++; Sys_Printf( "Minimum lightmap sample size set to %dx%d units\n", minSampleSize, minSampleSize ); } else if ( !strcmp( argv[ i ], "-custinfoparms" ) ) { Sys_Printf( "Custom info parms enabled\n" ); useCustomInfoParms = qtrue; } /* sof2 args */ else if ( !strcmp( argv[ i ], "-rename" ) ) { Sys_Printf( "Appending _bsp suffix to misc_model shaders (SOF2)\n" ); renameModelShaders = qtrue; } /* ydnar args */ else if ( !strcmp( argv[ i ], "-ne" ) ) { normalEpsilon = atof( argv[ i + 1 ] ); i++; Sys_Printf( "Normal epsilon set to %f\n", normalEpsilon ); } else if ( !strcmp( argv[ i ], "-de" ) ) { distanceEpsilon = atof( argv[ i + 1 ] ); i++; Sys_Printf( "Distance epsilon set to %f\n", distanceEpsilon ); } else if ( !strcmp( argv[ i ], "-mv" ) ) { maxLMSurfaceVerts = atoi( argv[ i + 1 ] ); if ( maxLMSurfaceVerts < 3 ) { maxLMSurfaceVerts = 3; } if ( maxLMSurfaceVerts > maxSurfaceVerts ) { maxSurfaceVerts = maxLMSurfaceVerts; } i++; Sys_Printf( "Maximum lightmapped surface vertex count set to %d\n", maxLMSurfaceVerts ); } else if ( !strcmp( argv[ i ], "-mi" ) ) { maxSurfaceIndexes = atoi( argv[ i + 1 ] ); if ( maxSurfaceIndexes < 3 ) { maxSurfaceIndexes = 3; } i++; Sys_Printf( "Maximum per-surface index count set to %d\n", maxSurfaceIndexes ); } else if ( !strcmp( argv[ i ], "-np" ) ) { npDegrees = atof( argv[ i + 1 ] ); if ( npDegrees < 0.0f ) { npDegrees = 0.0f; } else if ( npDegrees > 0.0f ) { Sys_Printf( "Forcing nonplanar surfaces with a breaking angle of %f degrees\n", npDegrees ); } i++; } else if ( !strcmp( argv[ i ], "-snap" ) ) { bevelSnap = atoi( argv[ i + 1 ] ); if ( bevelSnap < 0 ) { bevelSnap = 0; } i++; if ( bevelSnap > 0 ) { Sys_Printf( "Snapping brush bevel planes to %d units\n", bevelSnap ); } } else if ( !strcmp( argv[ i ], "-texrange" ) ) { texRange = atoi( argv[ i + 1 ] ); if ( texRange < 0 ) { texRange = 0; } i++; Sys_Printf( "Limiting per-surface texture range to %d texels\n", texRange ); } else if ( !strcmp( argv[ i ], "-nohint" ) ) { Sys_Printf( "Hint brushes disabled\n" ); noHint = qtrue; } else if ( !strcmp( argv[ i ], "-flat" ) ) { Sys_Printf( "Flatshading enabled\n" ); flat = qtrue; } else if ( !strcmp( argv[ i ], "-celshader" ) ) { ++i; if ( argv[i][0] ) { sprintf( globalCelShader, "textures/%s", argv[ i ] ); } else{ *globalCelShader = 0; } Sys_Printf( "Global cel shader set to \"%s\"\n", globalCelShader ); } else if ( !strcmp( argv[ i ], "-meta" ) ) { Sys_Printf( "Creating meta surfaces from brush faces\n" ); meta = qtrue; } else if ( !strcmp( argv[ i ], "-metaadequatescore" ) ) { metaAdequateScore = atoi( argv[ i + 1 ] ); if ( metaAdequateScore < 0 ) { metaAdequateScore = -1; } i++; if ( metaAdequateScore >= 0 ) { Sys_Printf( "Setting ADEQUATE meta score to %d (see surface_meta.c)\n", metaAdequateScore ); } } else if ( !strcmp( argv[ i ], "-metagoodscore" ) ) { metaGoodScore = atoi( argv[ i + 1 ] ); if ( metaGoodScore < 0 ) { metaGoodScore = -1; } i++; if ( metaGoodScore >= 0 ) { Sys_Printf( "Setting GOOD meta score to %d (see surface_meta.c)\n", metaGoodScore ); } } else if ( !strcmp( argv[ i ], "-metamaxbboxdistance" ) ) { metaMaxBBoxDistance = atof( argv[ i + 1 ] ); if ( metaMaxBBoxDistance < 0 ) { metaMaxBBoxDistance = -1; } i++; if ( metaMaxBBoxDistance >= 0 ) { Sys_Printf( "Setting meta maximum bounding box distance to %f\n", metaMaxBBoxDistance ); } } else if ( !strcmp( argv[ i ], "-patchmeta" ) ) { Sys_Printf( "Creating meta surfaces from patches\n" ); patchMeta = qtrue; } else if ( !strcmp( argv[ i ], "-flares" ) ) { Sys_Printf( "Flare surfaces enabled\n" ); emitFlares = qtrue; } else if ( !strcmp( argv[ i ], "-noflares" ) ) { Sys_Printf( "Flare surfaces disabled\n" ); emitFlares = qfalse; } else if ( !strcmp( argv[ i ], "-skyfix" ) ) { Sys_Printf( "GL_CLAMP sky fix/hack/workaround enabled\n" ); skyFixHack = qtrue; } else if ( !strcmp( argv[ i ], "-debugsurfaces" ) ) { Sys_Printf( "emitting debug surfaces\n" ); debugSurfaces = qtrue; } else if ( !strcmp( argv[ i ], "-debuginset" ) ) { Sys_Printf( "Debug surface triangle insetting enabled\n" ); debugInset = qtrue; } else if ( !strcmp( argv[ i ], "-debugportals" ) ) { Sys_Printf( "Debug portal surfaces enabled\n" ); debugPortals = qtrue; } else if ( !strcmp( argv[ i ], "-sRGBtex" ) ) { texturesRGB = qtrue; Sys_Printf( "Textures are in sRGB\n" ); } else if ( !strcmp( argv[ i ], "-nosRGBtex" ) ) { texturesRGB = qfalse; Sys_Printf( "Textures are linear\n" ); } else if ( !strcmp( argv[ i ], "-sRGBcolor" ) ) { colorsRGB = qtrue; Sys_Printf( "Colors are in sRGB\n" ); } else if ( !strcmp( argv[ i ], "-nosRGBcolor" ) ) { colorsRGB = qfalse; Sys_Printf( "Colors are linear\n" ); } else if ( !strcmp( argv[ i ], "-nosRGB" ) ) { texturesRGB = qfalse; Sys_Printf( "Textures are linear\n" ); colorsRGB = qfalse; Sys_Printf( "Colors are linear\n" ); } else if ( !strcmp( argv[ i ], "-altsplit" ) ) { Sys_Printf( "Alternate BSP splitting (by 27) enabled\n" ); bspAlternateSplitWeights = qtrue; } else if ( !strcmp( argv[ i ], "-deep" ) ) { Sys_Printf( "Deep BSP tree generation enabled\n" ); deepBSP = qtrue; } else if ( !strcmp( argv[ i ], "-maxarea" ) ) { Sys_Printf( "Max Area face surface generation enabled\n" ); maxAreaFaceSurface = qtrue; } else if ( !strcmp( argv[ i ], "-bsp" ) ) { Sys_Printf( "-bsp argument unnecessary\n" ); } else { Sys_Printf( "WARNING: Unknown option \"%s\"\n", argv[ i ] ); } } /* fixme: print more useful usage here */ if ( i != ( argc - 1 ) ) { Error( "usage: q3map [options] mapfile" ); } /* copy source name */ strcpy( source, ExpandArg( argv[ i ] ) ); StripExtension( source ); /* ydnar: set default sample size */ SetDefaultSampleSize( sampleSize ); /* delete portal, line and surface files */ sprintf( path, "%s.prt", source ); remove( path ); sprintf( path, "%s.lin", source ); remove( path ); //% sprintf( path, "%s.srf", source ); /* ydnar */ //% remove( path ); /* expand mapname */ strcpy( name, ExpandArg( argv[ i ] ) ); if ( strcmp( name + strlen( name ) - 4, ".reg" ) ) { /* if we are doing a full map, delete the last saved region map */ sprintf( path, "%s.reg", source ); remove( path ); DefaultExtension( name, ".map" ); /* might be .reg */ } /* if onlyents, just grab the entites and resave */ if ( onlyents ) { OnlyEnts(); return 0; } /* load shaders */ LoadShaderInfo(); /* load original file from temp spot in case it was renamed by the editor on the way in */ if ( strlen( tempSource ) > 0 ) { LoadMapFile( tempSource, qfalse, qfalse ); } else{ LoadMapFile( name, qfalse, qfalse ); } /* div0: inject command line parameters */ InjectCommandLine( argv, 1, argc - 1 ); /* ydnar: decal setup */ ProcessDecals(); /* ydnar: cloned brush model entities */ SetCloneModelNumbers(); /* process world and submodels */ ProcessModels(); /* set light styles from targetted light entities */ SetLightStyles(); /* process in game advertisements */ ProcessAdvertisements(); /* finish and write bsp */ EndBSPFile( qtrue ); /* remove temp map source file if appropriate */ if ( strlen( tempSource ) > 0 ) { remove( tempSource ); } /* return to sender */ return 0; }
/* =========== VisMain =========== */ int VisMain(int argc, char **argv) { char portalfile[1024]; int i; /* note it */ Sys_Printf("--- Vis ---\n"); /* process arguments */ for(i = 1; i < (argc - 1); i++) { if(!strcmp(argv[i], "-fast")) { Sys_Printf("fastvis = true\n"); fastvis = qtrue; } else if(!strcmp(argv[i], "-merge")) { Sys_Printf("merge = true\n"); mergevis = qtrue; } else if(!strcmp(argv[i], "-mergeportals")) { Sys_Printf("mergeportals = true\n"); mergevisportals = qtrue; } else if(!strcmp(argv[i], "-nopassage")) { Sys_Printf("nopassage = true\n"); noPassageVis = qtrue; } else if(!strcmp(argv[i], "-passageOnly")) { Sys_Printf("passageOnly = true\n"); passageVisOnly = qtrue; } else if(!strcmp(argv[i], "-nosort")) { Sys_Printf("nosort = true\n"); nosort = qtrue; } else if(!strcmp(argv[i], "-v")) { debugCluster = qtrue; Sys_Printf("Extra verbose mode enabled\n"); } else if(!strcmp(argv[i], "-tmpin")) { strcpy(inbase, "/tmp"); } else if(!strcmp(argv[i], "-tmpout")) { strcpy(outbase, "/tmp"); } /* ydnar: -hint to merge all but hint portals */ else if(!strcmp(argv[i], "-hint")) { Sys_Printf("hint = true\n"); hint = qtrue; mergevis = qtrue; } else { Sys_Printf("WARNING: Unknown option \"%s\"\n", argv[i]); } } if(i != argc - 1) Error("usage: vis [-threads #] [-level 0-4] [-fast] [-v] bspfile"); /* load the bsp */ sprintf(source, "%s%s", inbase, ExpandArg(argv[i])); StripExtension(source); strcat(source, ".bsp"); Sys_Printf("Loading %s\n", source); LoadBSPFile(source); /* load the portal file */ sprintf(portalfile, "%s%s", inbase, ExpandArg(argv[i])); StripExtension(portalfile); strcat(portalfile, ".prt"); Sys_Printf("Loading %s\n", portalfile); LoadPortals(portalfile); /* ydnar: exit if no portals, hence no vis */ if(numportals == 0) { Sys_Printf("No portals means no vis, exiting.\n"); return 0; } /* ydnar: for getting far plane */ ParseEntities(); /* inject command line parameters */ InjectCommandLine(argv, 0, argc - 1); UnparseEntities(); if(mergevis) MergeLeaves(); if(mergevis || mergevisportals) MergeLeafPortals(); CountActivePortals(); /* WritePortals( "maps/hints.prs" ); */ Sys_Printf("visdatasize:%i\n", numBSPVisBytes); CalcVis(); /* write the bsp file */ Sys_Printf("Writing %s\n", source); WriteBSPFile(source); return 0; }
int ScaleBSPMain( int argc, char **argv ){ int i, j; float f, a; vec3_t scale; vec3_t vec; char str[ 1024 ]; int uniform, axis; qboolean texscale; float *old_xyzst = NULL; float spawn_ref = 0; /* arg checking */ if ( argc < 3 ) { Sys_Printf( "Usage: q3map [-v] -scale [-tex] [-spawn_ref <value>] <value> <mapname>\n" ); return 0; } texscale = qfalse; for ( i = 1; i < argc - 2; ++i ) { if ( !strcmp( argv[i], "-tex" ) ) { texscale = qtrue; } else if ( !strcmp( argv[i], "-spawn_ref" ) ) { spawn_ref = atof( argv[i + 1] ); ++i; } else{ break; } } /* get scale */ // if(argc-2 >= i) // always true scale[2] = scale[1] = scale[0] = atof( argv[ argc - 2 ] ); if ( argc - 3 >= i ) { scale[1] = scale[0] = atof( argv[ argc - 3 ] ); } if ( argc - 4 >= i ) { scale[0] = atof( argv[ argc - 4 ] ); } uniform = ( ( scale[0] == scale[1] ) && ( scale[1] == scale[2] ) ); if ( scale[0] == 0.0f || scale[1] == 0.0f || scale[2] == 0.0f ) { Sys_Printf( "Usage: q3map [-v] -scale [-tex] [-spawn_ref <value>] <value> <mapname>\n" ); Sys_Printf( "Non-zero scale value required.\n" ); return 0; } /* do some path mangling */ strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); StripExtension( source ); DefaultExtension( source, ".bsp" ); /* load the bsp */ Sys_Printf( "Loading %s\n", source ); LoadBSPFile( source ); ParseEntities(); /* note it */ Sys_Printf( "--- ScaleBSP ---\n" ); Sys_FPrintf( SYS_VRB, "%9d entities\n", numEntities ); /* scale entity keys */ for ( i = 0; i < numBSPEntities && i < numEntities; i++ ) { /* scale origin */ GetVectorForKey( &entities[ i ], "origin", vec ); if ( ( vec[ 0 ] || vec[ 1 ] || vec[ 2 ] ) ) { if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { vec[2] += spawn_ref; } vec[0] *= scale[0]; vec[1] *= scale[1]; vec[2] *= scale[2]; if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { vec[2] -= spawn_ref; } sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); SetKeyValue( &entities[ i ], "origin", str ); } a = FloatForKey( &entities[ i ], "angle" ); if ( a == -1 || a == -2 ) { // z scale axis = 2; } else if ( fabs( sin( DEG2RAD( a ) ) ) < 0.707 ) { axis = 0; } else{ axis = 1; } /* scale door lip */ f = FloatForKey( &entities[ i ], "lip" ); if ( f ) { f *= scale[axis]; sprintf( str, "%f", f ); SetKeyValue( &entities[ i ], "lip", str ); } /* scale plat height */ f = FloatForKey( &entities[ i ], "height" ); if ( f ) { f *= scale[2]; sprintf( str, "%f", f ); SetKeyValue( &entities[ i ], "height", str ); } // TODO maybe allow a definition file for entities to specify which values are scaled how? } /* scale models */ for ( i = 0; i < numBSPModels; i++ ) { bspModels[ i ].mins[0] *= scale[0]; bspModels[ i ].mins[1] *= scale[1]; bspModels[ i ].mins[2] *= scale[2]; bspModels[ i ].maxs[0] *= scale[0]; bspModels[ i ].maxs[1] *= scale[1]; bspModels[ i ].maxs[2] *= scale[2]; } /* scale nodes */ for ( i = 0; i < numBSPNodes; i++ ) { bspNodes[ i ].mins[0] *= scale[0]; bspNodes[ i ].mins[1] *= scale[1]; bspNodes[ i ].mins[2] *= scale[2]; bspNodes[ i ].maxs[0] *= scale[0]; bspNodes[ i ].maxs[1] *= scale[1]; bspNodes[ i ].maxs[2] *= scale[2]; } /* scale leafs */ for ( i = 0; i < numBSPLeafs; i++ ) { bspLeafs[ i ].mins[0] *= scale[0]; bspLeafs[ i ].mins[1] *= scale[1]; bspLeafs[ i ].mins[2] *= scale[2]; bspLeafs[ i ].maxs[0] *= scale[0]; bspLeafs[ i ].maxs[1] *= scale[1]; bspLeafs[ i ].maxs[2] *= scale[2]; } if ( texscale ) { Sys_Printf( "Using texture unlocking (and probably breaking texture alignment a lot)\n" ); old_xyzst = safe_malloc( sizeof( *old_xyzst ) * numBSPDrawVerts * 5 ); for ( i = 0; i < numBSPDrawVerts; i++ ) { old_xyzst[5 * i + 0] = bspDrawVerts[i].xyz[0]; old_xyzst[5 * i + 1] = bspDrawVerts[i].xyz[1]; old_xyzst[5 * i + 2] = bspDrawVerts[i].xyz[2]; old_xyzst[5 * i + 3] = bspDrawVerts[i].st[0]; old_xyzst[5 * i + 4] = bspDrawVerts[i].st[1]; } } /* scale drawverts */ for ( i = 0; i < numBSPDrawVerts; i++ ) { bspDrawVerts[i].xyz[0] *= scale[0]; bspDrawVerts[i].xyz[1] *= scale[1]; bspDrawVerts[i].xyz[2] *= scale[2]; bspDrawVerts[i].normal[0] /= scale[0]; bspDrawVerts[i].normal[1] /= scale[1]; bspDrawVerts[i].normal[2] /= scale[2]; VectorNormalize( bspDrawVerts[i].normal, bspDrawVerts[i].normal ); } if ( texscale ) { for ( i = 0; i < numBSPDrawSurfaces; i++ ) { switch ( bspDrawSurfaces[i].surfaceType ) { case SURFACE_FACE: case SURFACE_META: if ( bspDrawSurfaces[i].numIndexes % 3 ) { Error( "Not a triangulation!" ); } for ( j = bspDrawSurfaces[i].firstIndex; j < bspDrawSurfaces[i].firstIndex + bspDrawSurfaces[i].numIndexes; j += 3 ) { int ia = bspDrawIndexes[j] + bspDrawSurfaces[i].firstVert, ib = bspDrawIndexes[j + 1] + bspDrawSurfaces[i].firstVert, ic = bspDrawIndexes[j + 2] + bspDrawSurfaces[i].firstVert; bspDrawVert_t *a = &bspDrawVerts[ia], *b = &bspDrawVerts[ib], *c = &bspDrawVerts[ic]; float *oa = &old_xyzst[ia * 5], *ob = &old_xyzst[ib * 5], *oc = &old_xyzst[ic * 5]; // extrapolate: // a->xyz -> oa // b->xyz -> ob // c->xyz -> oc ExtrapolateTexcoords( &oa[0], &oa[3], &ob[0], &ob[3], &oc[0], &oc[3], a->xyz, a->st, b->xyz, b->st, c->xyz, c->st ); } break; } } } /* scale planes */ if ( uniform ) { for ( i = 0; i < numBSPPlanes; i++ ) { bspPlanes[ i ].dist *= scale[0]; } } else { for ( i = 0; i < numBSPPlanes; i++ ) { bspPlanes[ i ].normal[0] /= scale[0]; bspPlanes[ i ].normal[1] /= scale[1]; bspPlanes[ i ].normal[2] /= scale[2]; f = 1 / VectorLength( bspPlanes[i].normal ); VectorScale( bspPlanes[i].normal, f, bspPlanes[i].normal ); bspPlanes[ i ].dist *= f; } } /* scale gridsize */ GetVectorForKey( &entities[ 0 ], "gridsize", vec ); if ( ( vec[ 0 ] + vec[ 1 ] + vec[ 2 ] ) == 0.0f ) { VectorCopy( gridSize, vec ); } vec[0] *= scale[0]; vec[1] *= scale[1]; vec[2] *= scale[2]; sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); SetKeyValue( &entities[ 0 ], "gridsize", str ); /* inject command line parameters */ InjectCommandLine( argv, 0, argc - 1 ); /* write the bsp */ UnparseEntities(); StripExtension( source ); DefaultExtension( source, "_s.bsp" ); Sys_Printf( "Writing %s\n", source ); WriteBSPFile( source ); /* return to sender */ return 0; }