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

📄 map.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 3 页
字号:
		{
			k = (j+1)%w->numpoints;
			VectorSubtract (w->p[j], w->p[k], vec);
			if (VectorNormalize (vec) < 0.5)
				continue;
			SnapVector (vec);
			for (k=0 ; k<3 ; k++)
				if ( vec[k] == -1 || vec[k] == 1)
					break;	// axial
			if (k != 3)
				continue;	// only test non-axial edges

			// try the six possible slanted axials from this edge
			for (axis=0 ; axis <3 ; axis++)
			{
				for (dir=-1 ; dir <= 1 ; dir+=2)
				{
					// construct a plane
					VectorClear (vec2);
					vec2[axis] = dir;
					CrossProduct (vec, vec2, normal);
					if (VectorNormalize (normal) < 0.5)
						continue;
					dist = DotProduct (w->p[j], normal);

					// if all the points on all the sides are
					// behind this plane, it is a proper edge bevel
					for (k=0 ; k<b->numsides ; k++)
					{
						// if this plane has allready been used, skip it
						if (PlaneEqual (&mapplanes[b->original_sides[k].planenum]
							, normal, dist) )
							break;

						w2 = b->original_sides[k].winding;
						if (!w2)
							continue;
						for (l=0 ; l<w2->numpoints ; l++)
						{
							d = DotProduct (w2->p[l], normal) - dist;
							if (d > 0.1)
								break;	// point in front
						}
						if (l != w2->numpoints)
							break;
					}

					if (k != b->numsides)
						continue;	// wasn't part of the outer hull
					// add this plane
					if (nummapbrushsides == MAX_MAP_BRUSHSIDES)
						Error ("MAX_MAP_BRUSHSIDES");
					nummapbrushsides++;
					s2 = &b->original_sides[b->numsides];
					s2->planenum = FindFloatPlane (normal, dist);
					s2->texinfo = b->original_sides[0].texinfo;
#ifdef SIN
					s2->lightinfo = b->original_sides[0].lightinfo;
#endif
					s2->contents = b->original_sides[0].contents;
					s2->flags |= SFL_BEVEL;
					c_edgebevels++;
					b->numsides++;
				}
			}
		}
	}
} //end of the function AddBrushBevels
//===========================================================================
// creates windigs for sides and mins / maxs for the brush
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean MakeBrushWindings(mapbrush_t *ob)
{
	int			i, j;
	winding_t	*w;
	side_t		*side;
	plane_t		*plane;

	ClearBounds (ob->mins, ob->maxs);

	for (i = 0; i < ob->numsides; i++)
	{
		plane = &mapplanes[ob->original_sides[i].planenum];
		w = BaseWindingForPlane(plane->normal, plane->dist);
		for (j = 0; j <ob->numsides && w; j++)
		{
			if (i == j) continue;
			if (ob->original_sides[j].flags & SFL_BEVEL) continue;
			plane = &mapplanes[ob->original_sides[j].planenum^1];
			ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
		}

		side = &ob->original_sides[i];
		side->winding = w;
		if (w)
		{
			side->flags |= SFL_VISIBLE;
			for (j = 0; j < w->numpoints; j++)
				AddPointToBounds (w->p[j], ob->mins, ob->maxs);
		}
	}

	for (i = 0; i < 3; i++)
	{
		//IDBUG: all the indexes into the mins and maxs were zero (not using i)
		if (ob->mins[i] < -MAX_MAP_BOUNDS || ob->maxs[i] > MAX_MAP_BOUNDS)
		{
			Log_Print("entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum);
			ob->numsides = 0; //remove the brush
			break;
		} //end if
		if (ob->mins[i] > MAX_MAP_BOUNDS || ob->maxs[i] < -MAX_MAP_BOUNDS)
		{
			Log_Print("entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum);
			ob->numsides = 0; //remove the brush
			break;
		} //end if
	} //end for
	return true;
} //end of the function MakeBrushWindings
//===========================================================================
// FIXME: currently doesn't mark all bevels
// NOTE: when one brush bevel is found the remaining sides of the brush
//       are bevels as well (when the brush isn't expanded for AAS :))
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void MarkBrushBevels(mapbrush_t *brush)
{
	int i;
	int we;
	side_t *s;

	//check all the sides of the brush
	for (i = 0; i < brush->numsides; i++)
	{
		s = brush->original_sides + i;
		//if the side has no winding
		if (!s->winding)
		{
			Log_Write("MarkBrushBevels: brush %d no winding", brush->brushnum);
			s->flags |= SFL_BEVEL;
		} //end if
		//if the winding is tiny
		else if (WindingIsTiny(s->winding))
		{
			s->flags |= SFL_BEVEL;
			Log_Write("MarkBrushBevels: brush %d tiny winding", brush->brushnum);
		} //end else if
		//if the winding has errors
		else
		{
			we = WindingError(s->winding);
			if (we == WE_NOTENOUGHPOINTS
					|| we == WE_SMALLAREA
					|| we == WE_POINTBOGUSRANGE
//					|| we == WE_NONCONVEX
					)
			{
				Log_Write("MarkBrushBevels: brush %d %s", brush->brushnum, WindingErrorString());
				s->flags |= SFL_BEVEL;
			} //end else if
		} //end else
		if (s->flags & SFL_BEVEL)
		{
			s->flags &= ~SFL_VISIBLE;
			//if the side has a valid plane
			if (s->planenum > 0 && s->planenum < nummapplanes)
			{
				//if it is an axial plane
				if (mapplanes[s->planenum].type < 3) c_boxbevels++;
				else c_edgebevels++;
			} //end if
		} //end if
	} //end for
} //end of the function MarkBrushBevels
//===========================================================================
// returns true if the map brush already exists
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int BrushExists(mapbrush_t *brush)
{
	int i, s1, s2;
	side_t *side1, *side2;
	mapbrush_t *brush1, *brush2;

	for (i = 0; i < nummapbrushes; i++)
	{
		brush1 = brush;
		brush2 = &mapbrushes[i];
		//compare the brushes
		if (brush1->entitynum != brush2->entitynum) continue;
		//if (brush1->contents != brush2->contents) continue;
		if (brush1->numsides != brush2->numsides) continue;
		for (s1 = 0; s1 < brush1->numsides; s1++)
		{
			side1 = brush1->original_sides + s1;
			//
			for (s2 = 0; s2 < brush2->numsides; s2++)
			{
				side2 = brush2->original_sides + s2;
				//
				if ((side1->planenum & ~1) == (side2->planenum & ~1)
//						&& side1->texinfo == side2->texinfo
//						&& side1->contents == side2->contents
//						&& side1->surf == side2->surf
					) break;
			} //end if
			if (s2 >= brush2->numsides) break;
		} //end for
		if (s1 >= brush1->numsides) return true;
	} //end for
	return false;
} //end of the function BrushExists
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean WriteMapBrush(FILE *fp, mapbrush_t *brush, vec3_t origin)
{
	int sn, rotate, shift[2], sv, tv, planenum, p1, i, j;
	float scale[2], originshift[2], ang1, ang2, newdist;
	vec3_t vecs[2], axis[2];
	map_texinfo_t *ti;
	winding_t *w;
	side_t *s;
	plane_t *plane;

	if (noliquids)
	{
		if (brush->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA))
		{
			return true;
		} //end if
	} //end if
	//if the brush has no contents
	if (!brush->contents) return true;
	//print the leading {
	if (fprintf(fp, " { //brush %d\n", brush->brushnum) < 0) return false;
	//write brush sides
	for (sn = 0; sn < brush->numsides; sn++)
	{
		s = brush->original_sides + sn;
		//don't write out bevels
		if (!(s->flags & SFL_BEVEL))
		{
			//if the entity has an origin set
			if (origin[0] || origin[1] || origin[2])
			{
				newdist = mapplanes[s->planenum].dist +
					DotProduct(mapplanes[s->planenum].normal, origin);
				planenum = FindFloatPlane(mapplanes[s->planenum].normal, newdist);
			} //end if
			else
			{
				planenum = s->planenum;
			} //end else
			//always take the first plane, then flip the points if necesary
			plane = &mapplanes[planenum & ~1];
			w = BaseWindingForPlane(plane->normal, plane->dist);
			//
			for (i = 0; i < 3; i++)
			{
				for (j = 0; j < 3; j++)
				{
					if (fabs(w->p[i][j]) < 0.2) w->p[i][j] = 0;
					else if (fabs((int)w->p[i][j] - w->p[i][j]) < 0.3) w->p[i][j] = (int) w->p[i][j];
					//w->p[i][j] = (int) (w->p[i][j] + 0.2);
				} //end for
			} //end for
			//three non-colinear points to define the plane
			if (planenum & 1) p1 = 1;
			else p1 = 0;
			if (fprintf(fp,"  ( %5i %5i %5i ) ", (int)w->p[p1][0], (int)w->p[p1][1], (int)w->p[p1][2]) < 0) return false;
			if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[!p1][0], (int)w->p[!p1][1], (int)w->p[!p1][2]) < 0) return false;
			if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]) < 0) return false;
			//free the winding
			FreeWinding(w);
			//
			if (s->texinfo == TEXINFO_NODE)
			{
				if (brush->contents & CONTENTS_PLAYERCLIP)
				{
					//player clip
					if (loadedmaptype == MAPTYPE_SIN)
					{
						if (fprintf(fp, "generic/misc/clip 0 0 0 1 1") < 0) return false;
					} //end if
					else if (loadedmaptype == MAPTYPE_QUAKE2)
					{	//FIXME: don't always use e1u1
						if (fprintf(fp, "e1u1/clip 0 0 0 1 1") < 0) return false;
					} //end else
					else if (loadedmaptype == MAPTYPE_QUAKE3)
					{
						if (fprintf(fp, "e1u1/clip 0 0 0 1 1") < 0) return false;
					} //end else if
					else
					{
						if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
					} //end else
				} //end if
				else if (brush->contents == CONTENTS_MONSTERCLIP)
				{
					//monster clip
					if (loadedmaptype == MAPTYPE_SIN)
					{
						if (fprintf(fp, "generic/misc/monster 0 0 0 1 1") < 0) return false;
					} //end if
					else if (loadedmaptype == MAPTYPE_QUAKE2)
					{
						if (fprintf(fp, "e1u1/clip_mon 0 0 0 1 1") < 0) return false;
					} //end else
					else
					{
						if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
					} //end else
				} //end else
				else
				{
					if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
					Log_Write("brush->contents = %d\n", brush->contents);
				} //end else
			} //end if
			else if (loadedmaptype == MAPTYPE_SIN && s->texinfo == 0)
			{
				if (brush->contents & CONTENTS_DUMMYFENCE)
				{
					if (fprintf(fp, "generic/misc/fence 0 0 0 1 1") < 0) return false;
				} //end if
				else if (brush->contents & CONTENTS_MIST)
				{
					if (fprintf(fp, "generic/misc/volumetric_base 0 0 0 1 1") < 0) return false;
				} //end if
				else //unknown so far
				{
					if (fprintf(fp, "generic/misc/red 0 0 0 1 1") < 0) return false;
				} //end else
			} //end if
			else if (loadedmaptype == MAPTYPE_QUAKE3)
			{
				//always use the same texture
				if (fprintf(fp, "e2u3/floor1_2 0 0 0 1 1 1 0 0") < 0) return false;
			} //end else if
			else
			{
				//*
				ti = &map_texinfo[s->texinfo];
				//the scaling of the texture
				scale[0] = 1 / VectorNormalize2(ti->vecs[0], vecs[0]);
				scale[1] = 1 / VectorNormalize2(ti->vecs[1], vecs[1]);
				//
				TextureAxisFromPlane(plane, axis[0], axis[1]);
				//calculate texture shift done by entity origin
				originshift[0] = DotProduct(origin, axis[0]);
				originshift[1] = DotProduct(origin, axis[1]);
				//the texture shift without origin shift
				shift[0] = ti->vecs[0][3] - originshift[0];
				shift[1] = ti->vecs[1][3] - originshift[1];
				//
				if (axis[0][0]) sv = 0;
				else if (axis[0][1]) sv = 1;
				else sv = 2;
				if (axis[1][0]) tv = 0;
				else if (axis[1][1]) tv = 1;
				else tv = 2;
				//calculate rotation of texture
				if (vecs[0][tv] == 0) ang1 = vecs[0][sv] > 0 ? 90.0 : -90.0;
				else ang1 = atan2(vecs[0][sv], vecs[0][tv]) * 180 / Q_PI;
				if (ang1 < 0) ang1 += 360;
				if (ang1 >= 360) ang1 -= 360;
				if (axis[0][tv] == 0) ang2 = axis[0][sv] > 0 ? 90.0 : -90.0;
				else ang2 = atan2(axis[0][sv], axis[0][tv]) * 180 / Q_PI;
				if (ang2 < 0) ang2 += 360;
				if (ang2 >= 360) ang2 -= 360;
				rotate = ang2 - ang1;
				if (rotate < 0) rotate += 360;
				if (rotate >= 360) rotate -= 360;
				//write the texture info
				if (fprintf(fp, "%s %d %d %d", ti->texture, shift[0], shift[1], rotate) < 0) return false;
				if (fabs(scale[0] - ((int) scale[0])) < 0.001)
				{
					if (fprintf(fp, " %d", (int) scale[0]) < 0) return false;
				} //end if
				else
				{
					if (fprintf(fp, " %4f", scale[0]) < 0) return false;
				} //end if
				if (fabs(scale[1] - ((int) scale[1])) < 0.001)
				{
					if (fprintf(fp, " %d", (int) scale[1]) < 0) return false;
				} //end if
				else
				{
					if (fprintf(fp, " %4f", scale[1]) < 0) return false;
				} //end else
				//write the extra brush side info
				if (loadedmaptype == MAPTYPE_QUAKE2)
				{
					if (fprintf(fp, " %ld %ld %ld", s->contents, ti->flags, ti->value) < 0) return false;
				} //end if
				//*/
			} //end else
			if (fprintf(fp, "\n") < 0) return false;
		} //end if
	} //end if
	if (fprintf(fp, " }\n") < 0) return false;
	c_writtenbrushes++;
	return true;
} //end of the function WriteMapBrush
//===========================================================================
//
// Parameter:				-

⌨️ 快捷键说明

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