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

📄 map_q1.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 3 页
字号:
			//
			if (side->flags & SFL_TEXTURED) continue;
			//number of the node that created this brush side
			sidenodenum = side->surf;	//see midwinding in Q1_SplitBrush
			//no face found yet
			bestfacenum = -1;
			//minimum face size
			largestarea = 1;
			//if optimizing the texture placement and not going for the
			//least number of brushes
			if (!lessbrushes)
			{
				for (i = 0; i < q1_numfaces; i++)
				{
					//the face must be in the same plane as the node plane that created
					//this brush side
					if (q1_dfaces[i].planenum == q1_dnodes[sidenodenum].planenum)
					{
						//get the area the face and the brush side overlap
						area = Q1_FaceOnWinding(&q1_dfaces[i], side->winding);
						//if this face overlaps the brush side winding more than previous faces
						if (area > largestarea)
						{
							//if there already was a face for texturing this brush side with
							//a different texture
							if (bestfacenum >= 0 &&
									(q1_dfaces[bestfacenum].texinfo != q1_dfaces[i].texinfo))
							{
								//split the brush to fit the texture
								newbrushes = Q1_SplitBrushWithFace(brush, &q1_dfaces[i]);
								//if new brushes where created
								if (newbrushes)
								{
									//remove the current brush from the list
									if (prevbrush) prevbrush->next = brush->next;
									else brushlist = brush->next;
									if (brushlistend == brush)
									{
										brushlistend = prevbrush;
										nextbrush = newbrushes;
									} //end if
									//add the new brushes to the end of the list
									if (brushlistend) brushlistend->next = newbrushes;
									else brushlist = newbrushes;
									//free the current brush
									FreeBrush(brush);
									//don't forget about the prevbrush pointer at the bottom of
									//the outer loop
									brush = prevbrush;
									//find the end of the list
									for (brushlistend = brushlist; brushlistend; brushlistend = brushlistend->next)
									{
										if (!brushlistend->next) break;
									} //end for
									break;
								} //end if
								else
								{
									Log_Write("brush %d: no real texture split", numbrushes);
								} //end else
							} //end if
							else
							{
								//best face for texturing this brush side
								bestfacenum = i;
							} //end else
						} //end if
					} //end if
				} //end for
				//if the brush was split the original brush is removed
				//and we just continue with the next one in the list
				if (i < q1_numfaces) break;
			} //end if
			else
			{
				//find the face with the largest overlap with this brush side
				//for texturing the brush side
				for (i = 0; i < q1_numfaces; i++)
				{
					//the face must be in the same plane as the node plane that created
					//this brush side
					if (q1_dfaces[i].planenum == q1_dnodes[sidenodenum].planenum)
					{
						//get the area the face and the brush side overlap
						area = Q1_FaceOnWinding(&q1_dfaces[i], side->winding);
						//if this face overlaps the brush side winding more than previous faces
						if (area > largestarea)
						{
							largestarea = area;
							bestfacenum = i;
						} //end if
					} //end if
				} //end for
			} //end else
			//if a face was found for texturing this brush side
			if (bestfacenum >= 0)
			{
				//set the MAP texinfo values
				texinfonum = q1_dfaces[bestfacenum].texinfo;
				for (n = 0; n < 4; n++)
				{
					map_texinfo[texinfonum].vecs[0][n] = q1_texinfo[texinfonum].vecs[0][n];
					map_texinfo[texinfonum].vecs[1][n] = q1_texinfo[texinfonum].vecs[1][n];
				} //end for
				//make sure the two vectors aren't of zero length otherwise use the default
				//vector to prevent a divide by zero in the map writing
				if (VectorLength(map_texinfo[texinfonum].vecs[0]) < 0.01)
					memcpy(map_texinfo[texinfonum].vecs[0], defaultvec, sizeof(defaultvec));
				if (VectorLength(map_texinfo[texinfonum].vecs[1]) < 0.01)
					memcpy(map_texinfo[texinfonum].vecs[1], defaultvec, sizeof(defaultvec));
				//
				map_texinfo[texinfonum].flags = q1_texinfo[texinfonum].flags;
				map_texinfo[texinfonum].value = 0; //Q1 and HL texinfos don't have a value
				//the mip texture
				miptexlump = (q1_dmiptexlump_t *) q1_dtexdata;
				ofs = miptexlump->dataofs[q1_texinfo[texinfonum].miptex];
				if ( ofs > q1_texdatasize ) {
					ofs = miptexlump->dataofs[0];
				}
				miptex = (q1_miptex_t *)((byte *)miptexlump + ofs);
				//get the mip texture name
				strcpy(map_texinfo[texinfonum].texture, miptex->name);
				//no animations in Quake1 and Half-Life mip textures
				map_texinfo[texinfonum].nexttexinfo = -1;
				//store the texinfo number
				side->texinfo = texinfonum;
				//
				if (texinfonum > map_numtexinfo) map_numtexinfo = texinfonum;
				//this side is textured
				side->flags |= SFL_TEXTURED;
			} //end if
			else
			{
				//no texture for this side
				side->texinfo = TEXINFO_NODE;
				//this side is textured
				side->flags |= SFL_TEXTURED;
			} //end if
		} //end for
		//
		if (!modelnum && prevbrush != brush) qprintf("\r%5d", ++numbrushes);
		//previous brush in the list
		prevbrush = brush;
	} //end for
	if (!modelnum) qprintf("\n");
	//return the new list with brushes
	return brushlist;
} //end of the function Q1_TextureBrushes
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void Q1_FixContentsTextures(bspbrush_t *brushlist)
{
	int i, texinfonum;
	bspbrush_t *brush;

	for (brush = brushlist; brush; brush = brush->next)
	{
		//only fix the textures of water, slime and lava brushes
		if (brush->side != CONTENTS_WATER &&
			brush->side != CONTENTS_SLIME &&
			brush->side != CONTENTS_LAVA) continue;
		//
		for (i = 0; i < brush->numsides; i++)
		{
			texinfonum = brush->sides[i].texinfo;
			if (Q1_TextureContents(map_texinfo[texinfonum].texture) == brush->side) break;
		} //end for
		//if no specific contents texture was found
		if (i >= brush->numsides)
		{
			texinfonum = -1;
			for (i = 0; i < map_numtexinfo; i++)
			{
				if (Q1_TextureContents(map_texinfo[i].texture) == brush->side)
				{
					texinfonum = i;
					break;
				} //end if
			} //end for
		} //end if
		//
		if (texinfonum >= 0)
		{
			//give all the brush sides this contents texture
			for (i = 0; i < brush->numsides; i++)
			{
				brush->sides[i].texinfo = texinfonum;
			} //end for
		} //end if
		else Log_Print("brush contents %d with wrong textures\n", brush->side);
		//
	} //end for
	/*
	for (brush = brushlist; brush; brush = brush->next)
	{
		//give all the brush sides this contents texture
		for (i = 0; i < brush->numsides; i++)
		{
			if (Q1_TextureContents(map_texinfo[texinfonum].texture) != brush->side)
			{
				Error("brush contents %d with wrong contents textures %s\n", brush->side,
							Q1_TextureContents(map_texinfo[texinfonum].texture));
			} //end if
		} //end for
	} //end for*/
} //end of the function Q1_FixContentsTextures
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void Q1_BSPBrushToMapBrush(bspbrush_t *bspbrush, entity_t *mapent)
{
	mapbrush_t *mapbrush;
	side_t *side;
	int i, besttexinfo;

	CheckBSPBrush(bspbrush);

	if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
	Error ("nummapbrushes == MAX_MAPFILE_BRUSHES");

	mapbrush = &mapbrushes[nummapbrushes];
	mapbrush->original_sides = &brushsides[nummapbrushsides];
	mapbrush->entitynum = mapent - entities;
	mapbrush->brushnum = nummapbrushes - mapent->firstbrush;
	mapbrush->leafnum = -1;
	mapbrush->numsides = 0;

	besttexinfo = TEXINFO_NODE;
	for (i = 0; i < bspbrush->numsides; i++)
	{
		if (!bspbrush->sides[i].winding) continue;
		//
		if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
			Error ("MAX_MAPFILE_BRUSHSIDES");
		side = &brushsides[nummapbrushsides];
		//the contents of the bsp brush is stored in the side variable
		side->contents = bspbrush->side;
		side->surf = 0;
		side->planenum = bspbrush->sides[i].planenum;
		side->texinfo = bspbrush->sides[i].texinfo;
		if (side->texinfo != TEXINFO_NODE)
		{
			//this brush side is textured
			side->flags |= SFL_TEXTURED;
			besttexinfo = side->texinfo;
		} //end if
		//
		nummapbrushsides++;
		mapbrush->numsides++;
	} //end for
	//
	if (besttexinfo == TEXINFO_NODE)
	{
		mapbrush->numsides = 0;
		q1_numclipbrushes++;
		return;
	} //end if
	//set the texinfo for all the brush sides without texture
	for (i = 0; i < mapbrush->numsides; i++)
	{
		if (mapbrush->original_sides[i].texinfo == TEXINFO_NODE)
		{
			mapbrush->original_sides[i].texinfo = besttexinfo;
		} //end if
	} //end for
	//contents of the brush
	mapbrush->contents = bspbrush->side;
	//
	if (create_aas)
	{
		//create the AAS brushes from this brush, add brush bevels
		AAS_CreateMapBrushes(mapbrush, mapent, true);
		return;
	} //end if
	//create windings for sides and bounds for brush
	MakeBrushWindings(mapbrush);
	//add brush bevels
	AddBrushBevels(mapbrush);
	//a new brush has been created
	nummapbrushes++;
	mapent->numbrushes++;
} //end of the function Q1_BSPBrushToMapBrush
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void Q1_CreateMapBrushes(entity_t *mapent, int modelnum)
{
	bspbrush_t *brushlist, *brush, *nextbrush;
	int i;

	//create brushes from the model BSP tree
	brushlist = Q1_CreateBrushesFromBSP(modelnum);
	//texture the brushes and split them when necesary
	brushlist = Q1_TextureBrushes(brushlist, modelnum);
	//fix the contents textures of all brushes
	Q1_FixContentsTextures(brushlist);
	//
	if (!nobrushmerge)
	{
		brushlist = Q1_MergeBrushes(brushlist, modelnum);
		//brushlist = Q1_MergeBrushes(brushlist, modelnum);
	} //end if
	//
	if (!modelnum) qprintf("converting brushes to map brushes\n");
	if (!modelnum) qprintf("%5d brushes", i = 0);
	for (brush = brushlist; brush; brush = nextbrush)
	{
		nextbrush = brush->next;
		Q1_BSPBrushToMapBrush(brush, mapent);
		brush->next = NULL;
		FreeBrush(brush);
		if (!modelnum) qprintf("\r%5d", ++i);
	} //end for
	if (!modelnum) qprintf("\n");
} //end of the function Q1_CreateMapBrushes
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void Q1_ResetMapLoading(void)
{
} //end of the function Q1_ResetMapLoading
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void Q1_LoadMapFromBSP(char *filename, int offset, int length)
{
	int i, modelnum;
	char *model, *classname;

	Log_Print("-- Q1_LoadMapFromBSP --\n");
	//the loaded map type
	loadedmaptype = MAPTYPE_QUAKE1;
	//
	qprintf("loading map from %s at %d\n", filename, offset);
	//load the Half-Life BSP file
	Q1_LoadBSPFile(filename, offset, length);
	//
	q1_numclipbrushes = 0;
	//CreatePath(path);
	//Q1_CreateQ2WALFiles(path);
	//parse the entities from the BSP
	Q1_ParseEntities();
	//clear the map mins and maxs
	ClearBounds(map_mins, map_maxs);
	//
	qprintf("creating Quake1 brushes\n");
	if (lessbrushes) qprintf("creating minimum number of brushes\n");
	else qprintf("placing textures correctly\n");
	//
	for (i = 0; i < num_entities; i++)
	{
		entities[i].firstbrush = nummapbrushes;
		entities[i].numbrushes = 0;
		//
		classname = ValueForKey(&entities[i], "classname");
		if (classname && !strcmp(classname, "worldspawn"))
		{
			modelnum = 0;
		} //end if
		else
		{
			//
			model = ValueForKey(&entities[i], "model");
			if (!model || *model != '*') continue;
			model++;
			modelnum = atoi(model);
		} //end else
		//create map brushes for the entity
		Q1_CreateMapBrushes(&entities[i], modelnum);
	} //end for
	//
	qprintf("%5d map brushes\n", nummapbrushes);
	qprintf("%5d clip brushes\n", q1_numclipbrushes);
} //end of the function Q1_LoadMapFromBSP

⌨️ 快捷键说明

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