⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bspc.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
===========================================================================
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:		-
//===========================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -