123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992 |
- /*
- ===========================================================================
- Copyright (C) 1999-2005 Id Software, Inc.
- This file is part of Quake III Arena source code.
- Quake III Arena source code 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.
- Quake III Arena source code 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 Foobar; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- ===========================================================================
- */
- #if defined(WIN32) || defined(_WIN32)
- #include <direct.h>
- #include <windows.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #else
- #include <unistd.h>
- #include <glob.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #endif
- #include "qbsp.h"
- #include "l_mem.h"
- #include "../botlib/aasfile.h"
- #include "../botlib/be_aas_cluster.h"
- #include "../botlib/be_aas_optimize.h"
- #include "aas_create.h"
- #include "aas_store.h"
- #include "aas_file.h"
- #include "aas_cfg.h"
- #include "be_aas_bspc.h"
- extern int use_nodequeue; //brushbsp.c
- extern int calcgrapplereach; //be_aas_reach.c
- float subdivide_size = 240;
- char source[1024];
- char name[1024];
- vec_t microvolume = 1.0;
- char outbase[32];
- int entity_num;
- aas_settings_t aassettings;
- qboolean noprune; //don't prune nodes (bspc.c)
- qboolean glview; //create a gl view
- qboolean nodetail; //don't use detail brushes (map.c)
- qboolean fulldetail; //use but don't mark detail brushes (map.c)
- qboolean onlyents; //only process the entities (bspc.c)
- qboolean nomerge; //don't merge bsp node faces (faces.c)
- qboolean nowater; //don't use the water brushes (map.c)
- qboolean nocsg; //don't carve intersecting brushes (bspc.c)
- qboolean noweld; //use unique face vertexes (faces.c)
- qboolean noshare; //don't share bsp edges (faces.c)
- qboolean nosubdiv; //don't subdivide bsp node faces (faces.c)
- qboolean notjunc; //don't create tjunctions (edge melting) (faces.c)
- qboolean optimize; //enable optimisation
- qboolean leaktest; //perform a leak test
- qboolean verboseentities;
- qboolean freetree; //free the bsp tree when not needed anymore
- qboolean create_aas; //create an .AAS file
- qboolean nobrushmerge; //don't merge brushes
- qboolean lessbrushes; //create less brushes instead of correct texture placement
- qboolean cancelconversion; //true if the conversion is being cancelled
- qboolean noliquids; //no liquids when writing map file
- qboolean forcesidesvisible; //force all brush sides to be visible when loaded from bsp
- qboolean capsule_collision = 0;
- /*
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- void ProcessWorldModel (void)
- {
- entity_t *e;
- tree_t *tree;
- qboolean leaked;
- int brush_start, brush_end;
- e = &entities[entity_num];
- brush_start = e->firstbrush;
- brush_end = brush_start + e->numbrushes;
- leaked = false;
- //process the whole world in one time
- tree = ProcessWorldBrushes(brush_start, brush_end);
- //create the bsp tree portals
- MakeTreePortals(tree);
- //mark all leafs that can be reached by entities
- if (FloodEntities(tree))
- {
- FillOutside(tree->headnode);
- } //end if
- else
- {
- Log_Print("**** leaked ****\n");
- leaked = true;
- LeakFile(tree);
- if (leaktest)
- {
- Log_Print("--- MAP LEAKED ---\n");
- exit(0);
- } //end if
- } //end else
- MarkVisibleSides (tree, brush_start, brush_end);
- FloodAreas (tree);
- #ifndef ME
- if (glview) WriteGLView(tree, source);
- #endif
- MakeFaces(tree->headnode);
- FixTjuncs(tree->headnode);
- //NOTE: Never prune the nodes because the portals
- // are screwed when prunning is done and as
- // a result portal writing will crash
- //if (!noprune) PruneNodes(tree->headnode);
- WriteBSP(tree->headnode);
- if (!leaked) WritePortalFile(tree);
- Tree_Free(tree);
- } //end of the function ProcessWorldModel
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- void ProcessSubModel (void)
- {
- entity_t *e;
- int start, end;
- tree_t *tree;
- bspbrush_t *list;
- vec3_t mins, maxs;
- e = &entities[entity_num];
- start = e->firstbrush;
- end = start + e->numbrushes;
- mins[0] = mins[1] = mins[2] = -4096;
- maxs[0] = maxs[1] = maxs[2] = 4096;
- list = MakeBspBrushList(start, end, mins, maxs);
- if (!nocsg) list = ChopBrushes (list);
- tree = BrushBSP (list, mins, maxs);
- MakeTreePortals (tree);
- MarkVisibleSides (tree, start, end);
- MakeFaces (tree->headnode);
- FixTjuncs (tree->headnode);
- WriteBSP (tree->headnode);
- Tree_Free(tree);
- } //end of the function ProcessSubModel
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- void ProcessModels (void)
- {
- BeginBSPFile();
- for (entity_num = 0; entity_num < num_entities; entity_num++)
- {
- if (!entities[entity_num].numbrushes)
- continue;
- Log_Print("############### model %i ###############\n", nummodels);
- BeginModel();
- if (entity_num == 0) ProcessWorldModel();
- else ProcessSubModel();
- EndModel();
- if (!verboseentities)
- verbose = false; // don't bother printing submodels
- } //end for
- EndBSPFile();
- } //end of the function ProcessModels
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- void Win_Map2Bsp(char *bspfilename)
- {
- double start, end;
- char path[1024];
- start = I_FloatTime();
- ThreadSetDefault();
- //yeah sure Carmack
- //numthreads = 1; // multiple threads aren't helping...
- strcpy(source, ExpandArg(bspfilename));
- StripExtension(source);
- //delete portal and line files
- sprintf(path, "%s.prt", source);
- remove(path);
- sprintf(path, "%s.lin", source);
- remove(path);
- strcpy(name, ExpandArg(bspfilename));
- DefaultExtension(name, ".map"); // might be .reg
- Q2_AllocMaxBSP();
- //
- SetModelNumbers();
- SetLightStyles();
- ProcessModels();
- //write the BSP
- Q2_WriteBSPFile(bspfilename);
- Q2_FreeMaxBSP();
- end = I_FloatTime();
- Log_Print("%5.0f seconds elapsed\n", end-start);
- } //end of the function Win_Map2Bsp
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- void Map2Bsp(char *mapfilename, char *outputfilename)
- {
- double start, end;
- char path[1024];
- start = I_FloatTime ();
- ThreadSetDefault ();
- //yeah sure Carmack
- //numthreads = 1; //multiple threads aren't helping...
- //SetQdirFromPath(bspfilename);
- strcpy(source, ExpandArg(mapfilename));
- StripExtension(source);
- // delete portal and line files
- sprintf(path, "%s.prt", source);
- remove(path);
- sprintf(path, "%s.lin", source);
- remove(path);
- strcpy(name, ExpandArg(mapfilename));
- DefaultExtension(name, ".map"); // might be .reg
- //
- // if onlyents, just grab the entites and resave
- //
- if (onlyents)
- {
- char out[1024];
- Q2_AllocMaxBSP();
- sprintf (out, "%s.bsp", source);
- Q2_LoadBSPFile(out, 0, 0);
- num_entities = 0;
- Q2_LoadMapFile(name);
- SetModelNumbers();
- SetLightStyles();
- Q2_UnparseEntities();
- Q2_WriteBSPFile(out);
- //
- Q2_FreeMaxBSP();
- } //end if
- else
- {
- //
- // start from scratch
- //
- Q2_AllocMaxBSP();
- //load the map
- Q2_LoadMapFile(name);
- //create the .bsp file
- SetModelNumbers();
- SetLightStyles();
- ProcessModels();
- //write the BSP
- Q2_WriteBSPFile(outputfilename);
- //
- Q2_FreeMaxBSP();
- } //end else
- end = I_FloatTime();
- Log_Print("%5.0f seconds elapsed\n", end-start);
- } //end of the function Map2Bsp
- */
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- void AASOuputFile(quakefile_t *qf, char *outputpath, char *filename)
- {
- char ext[MAX_PATH];
- //
- if (strlen(outputpath))
- {
- strcpy(filename, outputpath);
- //append the bsp file base
- AppendPathSeperator(filename, MAX_PATH);
- ExtractFileBase(qf->origname, &filename[strlen(filename)]);
- //append .aas
- strcat(filename, ".aas");
- return;
- } //end if
- //
- ExtractFileExtension(qf->filename, ext);
- if (!stricmp(ext, "pk3") || !stricmp(ext, "pak") || !stricmp(ext, "sin"))
- {
- strcpy(filename, qf->filename);
- while(strlen(filename) &&
- filename[strlen(filename)-1] != '\\' &&
- filename[strlen(filename)-1] != '/')
- {
- filename[strlen(filename)-1] = '\0';
- } //end while
- strcat(filename, "maps");
- if (access(filename, 0x04)) CreatePath(filename);
- //append the bsp file base
- AppendPathSeperator(filename, MAX_PATH);
- ExtractFileBase(qf->origname, &filename[strlen(filename)]);
- //append .aas
- strcat(filename, ".aas");
- } //end if
- else
- {
- strcpy(filename, qf->filename);
- while(strlen(filename) &&
- filename[strlen(filename)-1] != '.')
- {
- filename[strlen(filename)-1] = '\0';
- } //end while
- strcat(filename, "aas");
- } //end else
- } //end of the function AASOutputFile
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- void CreateAASFilesForAllBSPFiles(char *quakepath)
- {
- #if defined(WIN32)|defined(_WIN32)
- WIN32_FIND_DATA filedata;
- HWND handle;
- struct _stat statbuf;
- #else
- glob_t globbuf;
- struct stat statbuf;
- int j;
- #endif
- int done;
- char filter[_MAX_PATH], bspfilter[_MAX_PATH], aasfilter[_MAX_PATH];
- char aasfile[_MAX_PATH], buf[_MAX_PATH], foldername[_MAX_PATH];
- quakefile_t *qf, *qf2, *files, *bspfiles, *aasfiles;
- strcpy(filter, quakepath);
- AppendPathSeperator(filter, sizeof(filter));
- strcat(filter, "*");
- #if defined(WIN32)|defined(_WIN32)
- handle = FindFirstFile(filter, &filedata);
- done = (handle == INVALID_HANDLE_VALUE);
- while(!done)
- {
- _splitpath(filter, foldername, NULL, NULL, NULL);
- _splitpath(filter, NULL, &foldername[strlen(foldername)], NULL, NULL);
- AppendPathSeperator(foldername, _MAX_PATH);
- strcat(foldername, filedata.cFileName);
- _stat(foldername, &statbuf);
- #else
- glob(filter, 0, NULL, &globbuf);
- for (j = 0; j < globbuf.gl_pathc; j++)
- {
- strcpy(foldername, globbuf.gl_pathv[j]);
- stat(foldername, &statbuf);
- #endif
- //if it is a folder
- if (statbuf.st_mode & S_IFDIR)
- {
- //
- AppendPathSeperator(foldername, sizeof(foldername));
- //get all the bsp files
- strcpy(bspfilter, foldername);
- strcat(bspfilter, "maps/*.bsp");
- files = FindQuakeFiles(bspfilter);
- strcpy(bspfilter, foldername);
- strcat(bspfilter, "*.pk3/maps/*.bsp");
- bspfiles = FindQuakeFiles(bspfilter);
- for (qf = bspfiles; qf; qf = qf->next) if (!qf->next) break;
- if (qf) qf->next = files;
- else bspfiles = files;
- //get all the aas files
- strcpy(aasfilter, foldername);
- strcat(aasfilter, "maps/*.aas");
- files = FindQuakeFiles(aasfilter);
- strcpy(aasfilter, foldername);
- strcat(aasfilter, "*.pk3/maps/*.aas");
- aasfiles = FindQuakeFiles(aasfilter);
- for (qf = aasfiles; qf; qf = qf->next) if (!qf->next) break;
- if (qf) qf->next = files;
- else aasfiles = files;
- //
- for (qf = bspfiles; qf; qf = qf->next)
- {
- sprintf(aasfile, "%s/%s", qf->pakfile, qf->origname);
- Log_Print("found %s\n", aasfile);
- strcpy(&aasfile[strlen(aasfile)-strlen(".bsp")], ".aas");
- for (qf2 = aasfiles; qf2; qf2 = qf2->next)
- {
- sprintf(buf, "%s/%s", qf2->pakfile, qf2->origname);
- if (!stricmp(aasfile, buf))
- {
- Log_Print("found %s\n", buf);
- break;
- } //end if
- } //end for
- } //end for
- } //end if
- #if defined(WIN32)|defined(_WIN32)
- //find the next file
- done = !FindNextFile(handle, &filedata);
- } //end while
- #else
- } //end for
- globfree(&globbuf);
- #endif
- } //end of the function CreateAASFilesForAllBSPFiles
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- quakefile_t *GetArgumentFiles(int argc, char *argv[], int *i, char *ext)
- {
- quakefile_t *qfiles, *lastqf, *qf;
- int j;
- char buf[1024];
- qfiles = NULL;
- lastqf = NULL;
- for (; (*i)+1 < argc && argv[(*i)+1][0] != '-'; (*i)++)
- {
- strcpy(buf, argv[(*i)+1]);
- for (j = strlen(buf)-1; j >= strlen(buf)-4; j--)
- if (buf[j] == '.') break;
- if (j >= strlen(buf)-4)
- strcpy(&buf[j+1], ext);
- qf = FindQuakeFiles(buf);
- if (!qf) continue;
- if (lastqf) lastqf->next = qf;
- else qfiles = qf;
- lastqf = qf;
- while(lastqf->next) lastqf = lastqf->next;
- } //end for
- return qfiles;
- } //end of the function GetArgumentFiles
- //===========================================================================
- //
- // Parameter: -
- // Returns: -
- // Changes Globals: -
- //===========================================================================
- #define COMP_BSP2MAP 1
- #define COMP_BSP2AAS 2
- #define COMP_REACH 3
- #define COMP_CLUSTER 4
- #define COMP_AASOPTIMIZE 5
- #define COMP_AASINFO 6
- int main (int argc, char **argv)
- {
- int i, comp = 0;
- char outputpath[MAX_PATH] = "";
- char filename[MAX_PATH] = "unknown";
- quakefile_t *qfiles, *qf;
- double start_time;
- myargc = argc;
- myargv = argv;
- start_time = I_FloatTime();
- Log_Open("bspc.log"); //open a log file
- Log_Print("BSPC version "BSPC_VERSION", %s %s\n", __DATE__, __TIME__);
- DefaultCfg();
- for (i = 1; i < argc; i++)
- {
- if (!stricmp(argv[i],"-threads"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- numthreads = atoi(argv[++i]);
- Log_Print("threads = %d\n", numthreads);
- } //end if
- else if (!stricmp(argv[i], "-noverbose"))
- {
- Log_Print("verbose = false\n");
- verbose = false;
- } //end else if
- else if (!stricmp(argv[i], "-nocsg"))
- {
- Log_Print("nocsg = true\n");
- nocsg = true;
- } //end else if
- else if (!stricmp(argv[i], "-optimize"))
- {
- Log_Print("optimize = true\n");
- optimize = true;
- } //end else if
- /*
- else if (!stricmp(argv[i],"-glview"))
- {
- glview = true;
- } //end else if
- else if (!stricmp(argv[i], "-draw"))
- {
- Log_Print("drawflag = true\n");
- drawflag = true;
- } //end else if
- else if (!stricmp(argv[i], "-noweld"))
- {
- Log_Print("noweld = true\n");
- noweld = true;
- } //end else if
- else if (!stricmp(argv[i], "-noshare"))
- {
- Log_Print("noshare = true\n");
- noshare = true;
- } //end else if
- else if (!stricmp(argv[i], "-notjunc"))
- {
- Log_Print("notjunc = true\n");
- notjunc = true;
- } //end else if
- else if (!stricmp(argv[i], "-nowater"))
- {
- Log_Print("nowater = true\n");
- nowater = true;
- } //end else if
- else if (!stricmp(argv[i], "-noprune"))
- {
- Log_Print("noprune = true\n");
- noprune = true;
- } //end else if
- else if (!stricmp(argv[i], "-nomerge"))
- {
- Log_Print("nomerge = true\n");
- nomerge = true;
- } //end else if
- else if (!stricmp(argv[i], "-nosubdiv"))
- {
- Log_Print("nosubdiv = true\n");
- nosubdiv = true;
- } //end else if
- else if (!stricmp(argv[i], "-nodetail"))
- {
- Log_Print("nodetail = true\n");
- nodetail = true;
- } //end else if
- else if (!stricmp(argv[i], "-fulldetail"))
- {
- Log_Print("fulldetail = true\n");
- fulldetail = true;
- } //end else if
- else if (!stricmp(argv[i], "-onlyents"))
- {
- Log_Print("onlyents = true\n");
- onlyents = true;
- } //end else if
- else if (!stricmp(argv[i], "-micro"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- microvolume = atof(argv[++i]);
- Log_Print("microvolume = %f\n", microvolume);
- } //end else if
- else if (!stricmp(argv[i], "-leaktest"))
- {
- Log_Print("leaktest = true\n");
- leaktest = true;
- } //end else if
- else if (!stricmp(argv[i], "-verboseentities"))
- {
- Log_Print("verboseentities = true\n");
- verboseentities = true;
- } //end else if
- else if (!stricmp(argv[i], "-chop"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- subdivide_size = atof(argv[++i]);
- Log_Print("subdivide_size = %f\n", subdivide_size);
- } //end else if
- else if (!stricmp (argv[i], "-tmpout"))
- {
- strcpy (outbase, "/tmp");
- Log_Print("temp output\n");
- } //end else if
- */
- #ifdef ME
- else if (!stricmp(argv[i], "-freetree"))
- {
- freetree = true;
- Log_Print("freetree = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-grapplereach"))
- {
- calcgrapplereach = true;
- Log_Print("grapplereach = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-nobrushmerge"))
- {
- nobrushmerge = true;
- Log_Print("nobrushmerge = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-noliquids"))
- {
- noliquids = true;
- Log_Print("noliquids = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-forcesidesvisible"))
- {
- forcesidesvisible = true;
- Log_Print("forcesidesvisible = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-output"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- if (access(argv[i+1], 0x04)) Warning("the folder %s does not exist", argv[i+1]);
- strcpy(outputpath, argv[++i]);
- } //end else if
- else if (!stricmp(argv[i], "-breadthfirst"))
- {
- use_nodequeue = true;
- Log_Print("breadthfirst = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-capsule"))
- {
- capsule_collision = true;
- Log_Print("capsule_collision = true\n");
- } //end else if
- else if (!stricmp(argv[i], "-cfg"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- if (!LoadCfgFile(argv[++i]))
- exit(0);
- } //end else if
- else if (!stricmp(argv[i], "-bsp2map"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_BSP2MAP;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-bsp2aas"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_BSP2AAS;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-aasall"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- CreateAASFilesForAllBSPFiles(argv[++i]);
- } //end else if
- else if (!stricmp(argv[i], "-reach"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_REACH;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-cluster"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_CLUSTER;
- qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
- } //end else if
- else if (!stricmp(argv[i], "-aasinfo"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_AASINFO;
- qfiles = GetArgumentFiles(argc, argv, &i, "aas");
- } //end else if
- else if (!stricmp(argv[i], "-aasopt"))
- {
- if (i + 1 >= argc) {i = 0; break;}
- comp = COMP_AASOPTIMIZE;
- qfiles = GetArgumentFiles(argc, argv, &i, "aas");
- } //end else if
- #endif //ME
- else
- {
- Log_Print("unknown parameter %s\n", argv[i]);
- break;
- } //end else
- } //end for
- //if there are parameters and there's no mismatch in one of the parameters
- if (argc > 1 && i == argc)
- {
- switch(comp)
- {
- case COMP_BSP2MAP:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- //copy the output path
- strcpy(filename, outputpath);
- //append the bsp file base
- AppendPathSeperator(filename, MAX_PATH);
- ExtractFileBase(qf->origname, &filename[strlen(filename)]);
- //append .map
- strcat(filename, ".map");
- //
- Log_Print("bsp2map: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //
- LoadMapFromBSP(qf);
- //write the map file
- WriteMapFile(filename);
- } //end for
- break;
- } //end case
- case COMP_BSP2AAS:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("bsp2aas: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //set before map loading
- create_aas = 1;
- LoadMapFromBSP(qf);
- //create the AAS file
- AAS_Create(filename);
- //if it's a Quake3 map calculate the reachabilities and clusters
- if (loadedmaptype == MAPTYPE_QUAKE3) AAS_CalcReachAndClusters(qf);
- //
- if (optimize) AAS_Optimize();
- //
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_REACH:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("reach: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //if the AAS file exists in the output directory
- if (!access(filename, 0x04))
- {
- if (!AAS_LoadAASFile(filename, 0, 0))
- {
- Error("error loading aas file %s\n", filename);
- } //end if
- //assume it's a Quake3 BSP file
- loadedmaptype = MAPTYPE_QUAKE3;
- } //end if
- else
- {
- Warning("AAS file %s not found in output folder\n", filename);
- Log_Print("creating %s...\n", filename);
- //set before map loading
- create_aas = 1;
- LoadMapFromBSP(qf);
- //create the AAS file
- AAS_Create(filename);
- } //end else
- //if it's a Quake3 map calculate the reachabilities and clusters
- if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- AAS_CalcReachAndClusters(qf);
- } //end if
- //
- if (optimize) AAS_Optimize();
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_CLUSTER:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("cluster: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
- //if the AAS file exists in the output directory
- if (!access(filename, 0x04))
- {
- if (!AAS_LoadAASFile(filename, 0, 0))
- {
- Error("error loading aas file %s\n", filename);
- } //end if
- //assume it's a Quake3 BSP file
- loadedmaptype = MAPTYPE_QUAKE3;
- //if it's a Quake3 map calculate the clusters
- if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- aasworld.numclusters = 0;
- AAS_InitBotImport();
- AAS_InitClustering();
- } //end if
- } //end if
- else
- {
- Warning("AAS file %s not found in output folder\n", filename);
- Log_Print("creating %s...\n", filename);
- //set before map loading
- create_aas = 1;
- LoadMapFromBSP(qf);
- //create the AAS file
- AAS_Create(filename);
- //if it's a Quake3 map calculate the reachabilities and clusters
- if (loadedmaptype == MAPTYPE_QUAKE3) AAS_CalcReachAndClusters(qf);
- } //end else
- //
- if (optimize) AAS_Optimize();
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_AASOPTIMIZE:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("optimizing: %s to %s\n", qf->origname, filename);
- if (qf->type != QFILETYPE_AAS) Warning("%s is probably not a AAS file\n", qf->origname);
- //
- AAS_InitBotImport();
- //
- if (!AAS_LoadAASFile(qf->filename, qf->offset, qf->length))
- {
- Error("error loading aas file %s\n", qf->filename);
- } //end if
- AAS_Optimize();
- //write out the stored AAS file
- if (!AAS_WriteAASFile(filename))
- {
- Error("error writing %s\n", filename);
- } //end if
- //deallocate memory
- AAS_FreeMaxAAS();
- } //end for
- break;
- } //end case
- case COMP_AASINFO:
- {
- if (!qfiles) Log_Print("no files found\n");
- for (qf = qfiles; qf; qf = qf->next)
- {
- AASOuputFile(qf, outputpath, filename);
- //
- Log_Print("aas info for: %s\n", filename);
- if (qf->type != QFILETYPE_AAS) Warning("%s is probably not a AAS file\n", qf->origname);
- //
- AAS_InitBotImport();
- //
- if (!AAS_LoadAASFile(qf->filename, qf->offset, qf->length))
- {
- Error("error loading aas file %s\n", qf->filename);
- } //end if
- AAS_ShowTotals();
- } //end for
- } //end case
- default:
- {
- Log_Print("don't know what to do\n");
- break;
- } //end default
- } //end switch
- } //end if
- else
- {
- Log_Print("Usage: bspc [-<switch> [-<switch> ...]]\n"
- #if defined(WIN32) || defined(_WIN32)
- "Example 1: bspc -bsp2aas d:\\quake3\\baseq3\\maps\\mymap?.bsp\n"
- "Example 2: bspc -bsp2aas d:\\quake3\\baseq3\\pak0.pk3\\maps/q3dm*.bsp\n"
- #else
- "Example 1: bspc -bsp2aas /quake3/baseq3/maps/mymap?.bsp\n"
- "Example 2: bspc -bsp2aas /quake3/baseq3/pak0.pk3/maps/q3dm*.bsp\n"
- #endif
- "\n"
- "Switches:\n"
- //" bsp2map <[pakfilter/]filter.bsp> = convert BSP to MAP\n"
- //" aasall <quake3folder> = create AAS files for all BSPs\n"
- " bsp2aas <[pakfilter/]filter.bsp> = convert BSP to AAS\n"
- " reach <filter.bsp> = compute reachability & clusters\n"
- " cluster <filter.aas> = compute clusters\n"
- " aasopt <filter.aas> = optimize aas file\n"
- " aasinfo <filter.aas> = show AAS file info\n"
- " output <output path> = set output path\n"
- " threads <X> = set number of threads to X\n"
- " cfg <filename> = use this cfg file\n"
- " optimize = enable optimization\n"
- " noverbose = disable verbose output\n"
- " breadthfirst = breadth first bsp building\n"
- " nobrushmerge = don't merge brushes\n"
- " noliquids = don't write liquids to map\n"
- " freetree = free the bsp tree\n"
- " nocsg = disables brush chopping\n"
- " forcesidesvisible = force all sides to be visible\n"
- " grapplereach = calculate grapple reachabilities\n"
- /* " glview = output a GL view\n"
- " draw = enables drawing\n"
- " noweld = disables weld\n"
- " noshare = disables sharing\n"
- " notjunc = disables juncs\n"
- " nowater = disables water brushes\n"
- " noprune = disables node prunes\n"
- " nomerge = disables face merging\n"
- " nosubdiv = disables subdeviding\n"
- " nodetail = disables detail brushes\n"
- " fulldetail = enables full detail\n"
- " onlyents = only compile entities with bsp\n"
- " micro <volume>\n"
- " = sets the micro volume to the given float\n"
- " leaktest = perform a leak test\n"
- " verboseentities\n"
- " = enable entity verbose mode\n"
- " chop <subdivide_size>\n"
- " = sets the subdivide size to the given float\n"*/
- "\n");
- } //end else
- Log_Print("BSPC run time is %5.0f seconds\n", I_FloatTime() - start_time);
- Log_Close(); //close the log file
- return 0;
- } //end of the function main
|