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'; /* set standard game flags */ maxSurfaceVerts = game->maxSurfaceVerts; maxSurfaceIndexes = game->maxSurfaceIndexes; emitFlares = game->emitFlares; /* 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 ], "-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 ], "-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 ) shadeAngleDegrees = 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 ], "-meta" ) ) { Sys_Printf( "Creating meta surfaces from brush faces\n" ); meta = qtrue; } 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 ], "-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 ); else LoadMapFile( name, qfalse ); /* ydnar: decal setup */ ProcessDecals(); /* ydnar: cloned brush model entities */ SetCloneModelNumbers(); /* process world and submodels */ ProcessModels(); /* set light styles from targetted light entities */ SetLightStyles(); /* finish and write bsp */ EndBSPFile(); /* remove temp map source file if appropriate */ if( strlen( tempSource ) > 0) remove( tempSource ); /* return to sender */ return 0; }
/* PseudoCompileBSP() a stripped down ProcessModels */ void PseudoCompileBSP( qboolean need_tree, const char *BSPFilePath, const char *surfaceFilePath ){ int models; char modelValue[10]; entity_t *entity; face_t *faces; tree_t *tree; node_t *node; brush_t *brush; side_t *side; int i; SetDrawSurfacesBuffer(); mapDrawSurfs = safe_malloc( sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS ); memset( mapDrawSurfs, 0, sizeof( mapDrawSurface_t ) * MAX_MAP_DRAW_SURFS ); numMapDrawSurfs = 0; BeginBSPFile(); models = 1; for ( mapEntityNum = 0; mapEntityNum < numEntities; mapEntityNum++ ) { /* get entity */ entity = &entities[ mapEntityNum ]; if ( entity->brushes == NULL && entity->patches == NULL ) { continue; } if ( mapEntityNum != 0 ) { sprintf( modelValue, "*%d", models++ ); SetKeyValue( entity, "model", modelValue ); } /* process the model */ Sys_FPrintf( SYS_VRB, "############### model %i ###############\n", numBSPModels ); BeginModel(); entity->firstDrawSurf = numMapDrawSurfs; ClearMetaTriangles(); PatchMapDrawSurfs( entity ); if ( mapEntityNum == 0 && need_tree ) { faces = MakeStructuralBSPFaceList( entities[0].brushes ); tree = FaceBSP( faces ); node = tree->headnode; } else { node = AllocNode(); node->planenum = PLANENUM_LEAF; tree = AllocTree(); tree->headnode = node; } /* a minimized ClipSidesIntoTree */ for ( brush = entity->brushes; brush; brush = brush->next ) { /* walk the brush sides */ for ( i = 0; i < brush->numsides; i++ ) { /* get side */ side = &brush->sides[ i ]; if ( side->winding == NULL ) { continue; } /* shader? */ if ( side->shaderInfo == NULL ) { continue; } /* save this winding as a visible surface */ DrawSurfaceForSide( entity, brush, side, side->winding ); } } if ( meta ) { ClassifyEntitySurfaces( entity ); MakeEntityDecals( entity ); MakeEntityMetaTriangles( entity ); SmoothMetaTriangles(); MergeMetaTriangles(); } FilterDrawsurfsIntoTree( entity, tree ); FilterStructuralBrushesIntoTree( entity, tree ); FilterDetailBrushesIntoTree( entity, tree ); EmitBrushes( entity->brushes, &entity->firstBrush, &entity->numBrushes ); EndModel( entity, node ); } EndBSPFile( qfalse, BSPFilePath, surfaceFilePath ); }