Пример #1
0
void ParseBrushFace (entity_t *ent, mbrush_t **brushpointer, brushtype_t brushtype)
{
	int			i, j, hltexdef, bpface, brushplane;
//	int			facecontents, faceflags, facevalue, q2brushface, q3brushface;
	vec_t		planepts[3][3], t1[3], t2[3], d, rotate, scale[2], vecs[2][4], ang, sinv, cosv, bp[2][3];
	mface_t		*f, *f2;
	plane_t	plane;
	texinfo_t	tx;
	mbrush_t	*b;

	if (brushtype == BRUSHTYPE_PATCHDEF2 || brushtype == BRUSHTYPE_PATCHDEF3)
		return;
	// read the three point plane definition
	if (strcmp (token, "(") )
		Error ("parsing brush on line %d\n", scriptline);
	GetToken (false);
	planepts[0][0] = atof(token);
	GetToken (false);
	planepts[0][1] = atof(token);
	GetToken (false);
	planepts[0][2] = atof(token);
	GetToken (false);
	if (!strcmp(token, ")"))
	{
		brushplane = false;
		GetToken (false);
		if (strcmp(token, "("))
			Error("parsing brush on line %d\n", scriptline);
		GetToken (false);
		planepts[1][0] = atof(token);
		GetToken (false);
		planepts[1][1] = atof(token);
		GetToken (false);
		planepts[1][2] = atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);

		GetToken (false);
		if (strcmp(token, "("))
			Error("parsing brush on line %d\n", scriptline);
		GetToken (false);
		planepts[2][0] = atof(token);
		GetToken (false);
		planepts[2][1] = atof(token);
		GetToken (false);
		planepts[2][2] = atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);

		// convert points to a plane
		VectorSubtract(planepts[0], planepts[1], t1);
		VectorSubtract(planepts[2], planepts[1], t2);
		CrossProduct(t1, t2, plane.normal);
		VectorNormalize(plane.normal);
		plane.dist = DotProduct(planepts[1], plane.normal);
	}
	else
	{
		// oh, it's actually a 4 value plane
		brushplane = true;
		plane.normal[0] = planepts[0][0];
		plane.normal[1] = planepts[0][1];
		plane.normal[2] = planepts[0][2];
		plane.dist = -atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);
	}

	// read the texturedef
	memset (&tx, 0, sizeof(tx));
	GetToken (false);
	bpface = false;
	hltexdef = false;
	if (!strcmp(token, "("))
	{
		// brush primitives, utterly insane
		bpface = true;
		// (
		GetToken(false);
		// (
		GetToken(false);
		bp[0][0] = atof(token);
		GetToken(false);
		bp[0][1] = atof(token);
		GetToken(false);
		bp[0][2] = atof(token);
		GetToken(false);
		// )
		GetToken(false);
		// (
		GetToken(false);
		bp[1][0] = atof(token);
		GetToken(false);
		bp[1][1] = atof(token);
		GetToken(false);
		bp[1][2] = atof(token);
		GetToken(false);
		// )
		GetToken (false);
		GetToken (false);
		tx.miptex = FindMiptex (token);
		rotate = 0;
		scale[0] = 1;
		scale[1] = 1;
	}
	else
	{
		// if the texture name contains a / then this is a q2/q3 brushface
		// strip off the path, wads don't use a path on texture names
		tx.miptex = FindMiptex (token);
		GetToken (false);
		if (!strcmp(token, "["))
		{
			hltexdef = true;
			// S vector
			GetToken(false);
			vecs[0][0] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][1] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][2] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][3] = (vec_t)atof(token);
			// ]
			GetToken(false);
			// [
			GetToken(false);
			// T vector
			GetToken(false);
			vecs[1][0] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][1] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][2] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][3] = (vec_t)atof(token);
			// ]
			GetToken(false);

			// rotation (unused - implicit in tex coords)
			GetToken(false);
			rotate = 0;
		}
		else
		{
			vecs[0][3] = (vec_t)atof(token); // LordHavoc: float coords
			GetToken (false);
			vecs[1][3] = (vec_t)atof(token); // LordHavoc: float coords
			GetToken (false);
			rotate = atof(token); // LordHavoc: float coords
		}

		GetToken (false);
		scale[0] = (vec_t)atof(token); // LordHavoc: was already float coords
		GetToken (false);
		scale[1] = (vec_t)atof(token); // LordHavoc: was already float coords

		bp[0][0] = 1;
		bp[0][1] = 0;
		bp[0][2] = 0;
		bp[1][0] = 0;
		bp[1][1] = 1;
		bp[1][2] = 0;
	}
	// q3 .map properties, currently unused but parsed
//	facecontents = 0;
//	faceflags = 0;
//	facevalue = 0;
//	q2brushface = false;
//	q3brushface = false;
	if (GetToken (false))
	{
//		q2brushface = true;
//		facecontents = atoi(token);
		if (GetToken (false))
		{
//			faceflags = atoi(token);
			if (GetToken (false))
			{
//				q2brushface = false;
//				q3brushface = true;
//				facevalue = atoi(token);
			}
		}
	}
	// skip trailing info (the 3 q3 .map parameters for example)
	while (GetToken (false));

	if (DotProduct(plane.normal, plane.normal) < 0.1)
	{
		printf ("WARNING: line %i: brush plane with no normal\n", scriptline);
		return;
	}

	scale[0] = 1.0 / scale[0];
	scale[1] = 1.0 / scale[1];

	if (bpface)
	{
		// calculate proper texture vectors from GTKRadiant/Doom3 brushprimitives matrix
		float a, ac, as, bc, bs;
		a = -atan2(plane.normal[2], sqrt(plane.normal[0]*plane.normal[0]+plane.normal[1]*plane.normal[1]));
		ac = cos(a);
		as = sin(a);
		a = atan2(plane.normal[1], plane.normal[0]);
		bc = cos(a);
		bs = sin(a);
		vecs[0][0] = -bs;
		vecs[0][1] = bc;
		vecs[0][2] = 0;
		vecs[1][0] = -as*bc;
		vecs[1][1] = -as*bs;
		vecs[1][2] = -ac;
		tx.vecs[0][0] = bp[0][0] * vecs[0][0] + bp[0][1] * vecs[1][0];
		tx.vecs[0][1] = bp[0][0] * vecs[0][1] + bp[0][1] * vecs[1][1];
		tx.vecs[0][2] = bp[0][0] * vecs[0][2] + bp[0][1] * vecs[1][2];
		tx.vecs[0][3] = bp[0][0] * vecs[0][3] + bp[0][1] * vecs[1][3] + bp[0][2];
		tx.vecs[1][0] = bp[1][0] * vecs[0][0] + bp[1][1] * vecs[1][0];
		tx.vecs[1][1] = bp[1][0] * vecs[0][1] + bp[1][1] * vecs[1][1];
		tx.vecs[1][2] = bp[1][0] * vecs[0][2] + bp[1][1] * vecs[1][2];
		tx.vecs[1][3] = bp[1][0] * vecs[0][3] + bp[1][1] * vecs[1][3] + bp[1][2];
	}
	else if (hltexdef)
	{
		// HL texture vectors are almost ready to go
		for (i = 0; i < 2; i++)
		{
			for (j = 0; j < 3; j++)
				tx.vecs[i][j] = vecs[i][j] * scale[i];
			tx.vecs[i][3] = vecs[i][3] /*+ DotProduct(origin, tx.vecs[i])*/;
// Sajt: ripped the commented out bit from the HL compiler code, not really sure what it is exactly doing
// 'origin': origin set on bmodel by origin brush or origin key
		}
	}
	else
	{
		// fake proper texture vectors from QuakeEd style

		// texture rotation around the plane normal
			 if (rotate ==  0) {sinv = 0;cosv = 1;}
		else if (rotate == 90) {sinv = 1;cosv = 0;}
		else if (rotate == 180) {sinv = 0;cosv = -1;}
		else if (rotate == 270) {sinv = -1;cosv = 0;}
		else {ang = rotate * (Q_PI / 180);sinv = sin(ang);cosv = cos(ang);}

		if (fabs(plane.normal[2]) < fabs(plane.normal[0]))
		{
			if (fabs(plane.normal[0]) < fabs(plane.normal[1]))
			{
				// Y primary
				VectorSet4(tx.vecs[0],  cosv*scale[0],  0,  sinv*scale[0], vecs[0][3]);
				VectorSet4(tx.vecs[1],  sinv*scale[1],  0, -cosv*scale[1], vecs[1][3]);
			}
			else
			{
				// X primary
				VectorSet4(tx.vecs[0],  0,  cosv*scale[0],  sinv*scale[0], vecs[0][3]);
				VectorSet4(tx.vecs[1],  0,  sinv*scale[1], -cosv*scale[1], vecs[1][3]);
			}
		}
		else if (fabs(plane.normal[2]) < fabs(plane.normal[1]))
		{
			// Y primary
			VectorSet4(tx.vecs[0],  cosv*scale[0],  0,  sinv*scale[0], vecs[0][3]);
			VectorSet4(tx.vecs[1],  sinv*scale[1],  0, -cosv*scale[1], vecs[1][3]);
		}
		else
		{
			// Z primary
			VectorSet4(tx.vecs[0],  cosv*scale[0],  sinv*scale[0], 0, vecs[0][3]);
			VectorSet4(tx.vecs[1],  sinv*scale[1], -cosv*scale[1], 0, vecs[1][3]);
		}
		//printf("plane + rotate scale = texture vectors:\n(%f %f %f %f) + [%f %f %f] =\n[%f %f %f %f] [%f %f %f %f]\n", plane.normal[0], plane.normal[1], plane.normal[2], plane.dist, rotate, scale[0], scale[1], tx.vecs[0][0], tx.vecs[0][1], tx.vecs[0][2], tx.vecs[0][3], tx.vecs[1][0], tx.vecs[1][1], tx.vecs[1][2], tx.vecs[1][3]);
	}

	for (i = 0;i < 2;i++)
	{
		for (j = 0;j < 4;j++)
		{
			if (tx.vecs[i][j] > -BOGUS_RANGE && tx.vecs[i][j] < BOGUS_RANGE)
				continue;
			printf( "WARNING: line %i: corrupt texture mapping vectors, using defaults\n", scriptline);
			cosv = 1;
			sinv = 0;
			scale[0] = 1;
			scale[1] = 1;
			vecs[0][3] = 0;
			vecs[1][3] = 0;
			if (fabs(plane.normal[2]) < fabs(plane.normal[0]))
			{
				if (fabs(plane.normal[0]) < fabs(plane.normal[1]))
				{
					// Y primary
					VectorSet4(tx.vecs[0],  cosv*scale[0],  0,  sinv*scale[0], vecs[0][3]);
					VectorSet4(tx.vecs[1],  sinv*scale[1],  0, -cosv*scale[1], vecs[1][3]);
				}
				else
				{
					// X primary
					VectorSet4(tx.vecs[0],  0,  cosv*scale[0],  sinv*scale[0], vecs[0][3]);
					VectorSet4(tx.vecs[1],  0,  sinv*scale[1], -cosv*scale[1], vecs[1][3]);
				}
			}
			else if (fabs(plane.normal[2]) < fabs(plane.normal[1]))
			{
				// Y primary
				VectorSet4(tx.vecs[0],  cosv*scale[0],  0,  sinv*scale[0], vecs[0][3]);
				VectorSet4(tx.vecs[1],  sinv*scale[1],  0, -cosv*scale[1], vecs[1][3]);
			}
			else
			{
				// Z primary
				VectorSet4(tx.vecs[0],  cosv*scale[0],  sinv*scale[0], 0, vecs[0][3]);
				VectorSet4(tx.vecs[1],  sinv*scale[1], -cosv*scale[1], 0, vecs[1][3]);
			}
			break;
		}
	}
	
	/*
	// LordHavoc: fix for CheckFace: point off plane errors in some maps (most notably QOOLE ones),
	// and hopefully preventing most 'portal clipped away' warnings
	VectorNormalize (plane.normal);
	for (j = 0;j < 3;j++)
		plane.normal[j] = (Q_rint((vec_t) plane.normal[j] * (vec_t) 8.0)) * (vec_t) (1.0 / 8.0);
	VectorNormalize (plane.normal);
	plane.dist = DotProduct (t3, plane.normal);
	d = (Q_rint(plane.dist * 8.0)) * (1.0 / 8.0);
	//if (fabs(d - plane.dist) >= (0.4 / 8.0))
	//	printf("WARNING: line %i: correcting minor math errors in brushface\n", scriptline);
	plane.dist = d;
	*/

	/*
	VectorNormalize (plane.normal);
	plane.dist = DotProduct (t3, plane.normal);

	VectorCopy(plane.normal, v);
	//for (j = 0;j < 3;j++)
	//	v[j] = (Q_rint((vec_t) v[j] * (vec_t) 32.0)) * (vec_t) (1.0 / 32.0);
	VectorNormalize (v);
	d = (Q_rint(DotProduct (t3, v) * 8.0)) * (1.0 / 8.0);

	// if deviation is too high, warn  (frequently happens on QOOLE maps)
	if (fabs(DotProduct(v, plane.normal) - 1.0) > (0.5 / 32.0)
	 || fabs(d - plane.dist) >= (0.25 / 8.0))
		printf("WARNING: line %i: minor misalignment of brushface\n"
			   "normal     %f %f %f (l: %f d: %f)\n"
			   "rounded to %f %f %f (l: %f d: %f r: %f)\n",
			   scriptline,
			   (vec_t) plane.normal[0], (vec_t) plane.normal[1], (vec_t) plane.normal[2], (vec_t) sqrt(DotProduct(plane.normal, plane.normal)), (vec_t) DotProduct (t3, plane.normal),
			   (vec_t) v[0], (vec_t) v[1], (vec_t) v[2], (vec_t) sqrt(DotProduct(v, v)), (vec_t) DotProduct(t3, v), (vec_t) d);
	//VectorCopy(v, plane.normal);
	//plane.dist = d;
	*/

	b = *brushpointer;
	if (b)
	{
		if (brushplane)
		{
			for (f2 = b->faces ; f2 ;f2=f2->next)
				if (VectorCompare(plane.normal, f2->plane.normal) && fabs(plane.dist - f2->plane.dist) < ON_EPSILON)
					break;
			if (f2)
			{
				printf ("WARNING: line %i: brush with duplicate plane\n", scriptline);
				return;
			}
		}
		else
		{
			// if the three points are all on a previous plane, it is a
			// duplicate plane
			for (f2 = b->faces ; f2 ; f2=f2->next)
			{
				for (i = 0;i < 3;i++)
				{
					d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
					if (d < -ON_EPSILON || d > ON_EPSILON)
						break;
				}
				if (i==3)
					break;
			}
			if (f2)
			{
				printf ("WARNING: line %i: brush with duplicate plane\n", scriptline);
				return;
			}
		}
	}
	else
	{
		b = &mapbrushes[nummapbrushes];
		nummapbrushes++;
		b->next = ent->brushes;
		ent->brushes = b;
		b->scriptline = scriptline;
		*brushpointer = b;
	}

	f = qmalloc(sizeof(mface_t));
	f->next = b->faces;
	b->faces = f;
	f->scriptline = scriptline;
	f->plane = plane;
	f->texinfo = FindTexinfo (&tx);
	nummapbrushfaces++;
}
Пример #2
0
void ParseBrushFace (entity_t *ent, mbrush_t **brushpointer, brushtype_t brushtype)
{
	int			i, j, sv, tv, hltexdef, facecontents, faceflags, facevalue, q2brushface, q3brushface, bpface;
	vec_t		planepts[3][3], t1[3], t2[3], d, rotate, scale[2], vecs[2][4], ang, sinv, cosv, ns, nt, bp[2][3];
	mface_t		*f, *f2;
	plane_t	plane;
	texinfo_t	tx;
	mbrush_t	*b;

	if (brushtype == BRUSHTYPE_PATCHDEF2 || brushtype == BRUSHTYPE_PATCHDEF3)
		return;
	// read the three point plane definition
	if (strcmp (token, "(") )
		Error ("parsing brush on line %d\n", scriptline);
	GetToken (false);
	planepts[0][0] = atof(token);
	GetToken (false);
	planepts[0][1] = atof(token);
	GetToken (false);
	planepts[0][2] = atof(token);
	GetToken (false);
	if (!strcmp(token, ")"))
	{
		GetToken (false);
		if (strcmp(token, "("))
			Error("parsing brush on line %d\n", scriptline);
		GetToken (false);
		planepts[1][0] = atof(token);
		GetToken (false);
		planepts[1][1] = atof(token);
		GetToken (false);
		planepts[1][2] = atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);

		GetToken (false);
		if (strcmp(token, "("))
			Error("parsing brush on line %d\n", scriptline);
		GetToken (false);
		planepts[2][0] = atof(token);
		GetToken (false);
		planepts[2][1] = atof(token);
		GetToken (false);
		planepts[2][2] = atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);

		// convert points to a plane
		VectorSubtract(planepts[0], planepts[1], t1);
		VectorSubtract(planepts[2], planepts[1], t2);
		CrossProduct(t1, t2, plane.normal);
		VectorNormalize(plane.normal);
		plane.dist = DotProduct(planepts[1], plane.normal);
	}
	else
	{
		// oh, it's actually a 4 value plane
		plane.normal[0] = planepts[0][0];
		plane.normal[1] = planepts[0][1];
		plane.normal[2] = planepts[0][2];
		plane.dist = -atof(token);
		GetToken (false);
		if (strcmp(token, ")"))
			Error("parsing brush on line %d\n", scriptline);
	}

	// read the texturedef
	memset (&tx, 0, sizeof(tx));
	GetToken (false);
	bpface = false;
	hltexdef = false;
	if (!strcmp(token, "("))
	{
		// brush primitives, utterly insane
		bpface = true;
		// (
		GetToken(false);
		// (
		GetToken(false);
		bp[0][0] = atof(token);
		GetToken(false);
		bp[0][1] = atof(token);
		GetToken(false);
		bp[0][2] = atof(token);
		GetToken(false);
		// )
		GetToken(false);
		// (
		GetToken(false);
		bp[1][0] = atof(token);
		GetToken(false);
		bp[1][1] = atof(token);
		GetToken(false);
		bp[1][2] = atof(token);
		GetToken(false);
		// )
		GetToken (false);
		GetToken (false);
		tx.miptex = FindMiptex (token);
		rotate = 0;
		scale[0] = 1;
		scale[1] = 1;
	}
	else
	{
		// if the texture name contains a / then this is a q2/q3 brushface
		// strip off the path, wads don't use a path on texture names
		tx.miptex = FindMiptex (token);
		GetToken (false);
		if (!strcmp(token, "["))
		{
			hltexdef = true;
			// S vector
			GetToken(false);
			vecs[0][0] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][1] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][2] = (vec_t)atof(token);
			GetToken(false);
			vecs[0][3] = (vec_t)atof(token);
			// ]
			GetToken(false);
			// [
			GetToken(false);
			// T vector
			GetToken(false);
			vecs[1][0] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][1] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][2] = (vec_t)atof(token);
			GetToken(false);
			vecs[1][3] = (vec_t)atof(token);
			// ]
			GetToken(false);

			// rotation (unused - implicit in tex coords)
			GetToken(false);
			rotate = 0;
		}
		else
		{
			vecs[0][3] = (vec_t)atof(token); // LordHavoc: float coords
			GetToken (false);
			vecs[1][3] = (vec_t)atof(token); // LordHavoc: float coords
			GetToken (false);
			rotate = atof(token); // LordHavoc: float coords
		}

		GetToken (false);
		scale[0] = (vec_t)atof(token); // LordHavoc: was already float coords
		GetToken (false);
		scale[1] = (vec_t)atof(token); // LordHavoc: was already float coords
	}
	// q3 .map properties, currently unused but parsed
	facecontents = 0;
	faceflags = 0;
	facevalue = 0;
	q2brushface = false;
	q3brushface = false;
	if (GetToken (false))
	{
		q2brushface = true;
		facecontents = atoi(token);
		if (GetToken (false))
		{
			faceflags = atoi(token);
			if (GetToken (false))
			{
				q2brushface = false;
				q3brushface = true;
				facevalue = atoi(token);
			}
		}
	}
	// skip trailing info (the 3 q3 .map parameters for example)
	while (GetToken (false));

	if (DotProduct(plane.normal, plane.normal) < 0.1)
	{
		printf ("WARNING: brush plane with no normal on line %d\n", scriptline);
		return;
	}

	if (bpface)
	{
		// fake proper texture vectors from QuakeEd style
		TextureAxisFromPlane(&plane, vecs[0], vecs[1], true);
		// FIXME: deal with the bp stuff here
		printf("warning: brush primitive texturing not yet supported (line %d)\n", scriptline);
		// generic texturing
		tx.vecs[0][0] = vecs[0][0];
		tx.vecs[0][1] = vecs[0][1];
		tx.vecs[0][2] = vecs[0][2];
		tx.vecs[0][3] = vecs[0][3];
		tx.vecs[1][0] = vecs[1][0];
		tx.vecs[1][1] = vecs[1][1];
		tx.vecs[1][2] = vecs[1][2];
		tx.vecs[1][3] = vecs[1][3];
	}
	else
	{
		if (hltexdef)
		{
			for (i = 0; i < 2; i++)
			{
				d = 1.0 / (scale[i] ? scale[i] : 1.0);
				for (j = 0; j < 3; j++)
					tx.vecs[i][j] = vecs[i][j] * d;
				tx.vecs[i][3] = vecs[i][3] /*+ DotProduct(origin, tx.vecs[i])*/;
// Sajt: ripped the commented out bit from the HL compiler code, not really sure what it is exactly doing
// 'origin': origin set on bmodel by origin brush or origin key
			}
		}
		else
		{
			// fake proper texture vectors from QuakeEd style
			TextureAxisFromPlane(&plane, vecs[0], vecs[1], q3brushface);

			// rotate axis
				 if (rotate ==  0) {sinv = 0;cosv = 1;}
			else if (rotate == 90) {sinv = 1;cosv = 0;}
			else if (rotate == 180) {sinv = 0;cosv = -1;}
			else if (rotate == 270) {sinv = -1;cosv = 0;}
			else {ang = rotate * (Q_PI / 180);sinv = sin(ang);cosv = cos(ang);}

			// LordHavoc: I don't quite understand this
			for (sv = 0;sv < 2 && !vecs[0][sv];sv++);
			for (tv = 0;tv < 2 && !vecs[1][tv];tv++);

			for (i = 0;i < 2;i++)
			{
				// rotate
				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
				nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
				vecs[i][sv] = ns;
				vecs[i][tv] = nt;
				// scale and store into texinfo
				d = 1.0 / (scale[i] ? scale[i] : 1.0);
				for (j = 0;j < 3;j++)
					tx.vecs[i][j] = vecs[i][j] * d;
				tx.vecs[i][3] = vecs[i][3];
			}
		}
	}

	/*
	// LordHavoc: fix for CheckFace: point off plane errors in some maps (most notably QOOLE ones),
	// and hopefully preventing most 'portal clipped away' warnings
	VectorNormalize (plane.normal);
	for (j = 0;j < 3;j++)
		plane.normal[j] = (Q_rint((vec_t) plane.normal[j] * (vec_t) 8.0)) * (vec_t) (1.0 / 8.0);
	VectorNormalize (plane.normal);
	plane.dist = DotProduct (t3, plane.normal);
	d = (Q_rint(plane.dist * 8.0)) * (1.0 / 8.0);
	//if (fabs(d - plane.dist) >= (0.4 / 8.0))
	//	printf("WARNING: correcting minor math errors in brushface on line %d\n", scriptline);
	plane.dist = d;
	*/

	/*
	VectorNormalize (plane.normal);
	plane.dist = DotProduct (t3, plane.normal);

	VectorCopy(plane.normal, v);
	//for (j = 0;j < 3;j++)
	//	v[j] = (Q_rint((vec_t) v[j] * (vec_t) 32.0)) * (vec_t) (1.0 / 32.0);
	VectorNormalize (v);
	d = (Q_rint(DotProduct (t3, v) * 8.0)) * (1.0 / 8.0);

	// if deviation is too high, warn  (frequently happens on QOOLE maps)
	if (fabs(DotProduct(v, plane.normal) - 1.0) > (0.5 / 32.0)
	 || fabs(d - plane.dist) >= (0.25 / 8.0))
		printf("WARNING: minor misalignment of brushface on line %d\n"
			   "normal     %f %f %f (l: %f d: %f)\n"
			   "rounded to %f %f %f (l: %f d: %f r: %f)\n",
			   scriptline,
			   (vec_t) plane.normal[0], (vec_t) plane.normal[1], (vec_t) plane.normal[2], (vec_t) sqrt(DotProduct(plane.normal, plane.normal)), (vec_t) DotProduct (t3, plane.normal),
			   (vec_t) v[0], (vec_t) v[1], (vec_t) v[2], (vec_t) sqrt(DotProduct(v, v)), (vec_t) DotProduct(t3, v), (vec_t) d);
	//VectorCopy(v, plane.normal);
	//plane.dist = d;
	*/

	b = *brushpointer;
	if (b)
	{
		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i = 0;i < 3;i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
					break;
			}
			if (i==3)
				break;
		}
		if (f2)
		{
			printf ("WARNING: brush with duplicate plane (first point is at %g %g %g, .map file line number %d)\n", planepts[0][0], planepts[0][1], planepts[0][2], scriptline);
			return;
		}
	}
	else
	{
		b = &mapbrushes[nummapbrushes];
		nummapbrushes++;
		b->next = ent->brushes;
		ent->brushes = b;
		*brushpointer = b;
	}

	f = qmalloc(sizeof(mface_t));
	f->next = b->faces;
	b->faces = f;
	f->plane = plane;
	f->texinfo = FindTexinfo (&tx);
	nummapbrushfaces++;
}
Пример #3
0
/*
=================
ParseBrush
=================
*/
void ParseBrush (void)
{
	mbrush_t	*b;
	mface_t		*f, *f2;
	vec3_t		planepts[3];
	vec3_t		t1, t2, t3;
	int			i,j;
	texinfo_t	tx;
	vec_t		d;
	float		shift[2], rotate, scale[2];

	b = &mapbrushes[nummapbrushes];
	nummapbrushes++;
	b->next = mapent->brushes;
	mapent->brushes = b;

	do
	{
		if (!GetToken (true))
			break;
		if (!strcmp (token, "}") )
			break;

		// read the three point plane definition
		for (i=0 ; i<3 ; i++)
		{
			if (i != 0)
				GetToken (true);
			if (strcmp (token, "(") )
				Error ("parsing brush");

			for (j=0 ; j<3 ; j++)
			{
				GetToken (false);
				planepts[i][j] = atof(token); // LordHavoc: float coords
			}

			GetToken (false);
			if (strcmp (token, ")") )
				Error ("parsing brush");
		}

		fflush(stdout);
		// read the texturedef
		memset (&tx, 0, sizeof(tx));
		GetToken (false);
		tx.miptex = FindMiptex (token);
		GetToken (false);
		shift[0] = atof(token); // LordHavoc: float coords
		GetToken (false);
		shift[1] = atof(token); // LordHavoc: float coords
		GetToken (false);
		rotate = atof(token);	 // LordHavoc: float coords
		GetToken (false);
		scale[0] = atof(token); // LordHavoc: was already float coords
		GetToken (false);
		scale[1] = atof(token); // LordHavoc: was already float coords

		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i=0 ; i<3 ; i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
				break;
			}
			if (i==3)
				break;
		}
		if (f2)		
		{
			printf ("WARNING: brush with duplicate plane\n");
			continue;
		}

		f = malloc(sizeof(mface_t));
		f->next = b->faces;
		b->faces = f;

		// convert to a vector / dist plane
		for (j=0 ; j<3 ; j++)
		{
			t1[j] = planepts[0][j] - planepts[1][j];
			t2[j] = planepts[2][j] - planepts[1][j];
			t3[j] = planepts[1][j];
		}

		CrossProduct(t1,t2, f->plane.normal);
		if (VectorCompare (f->plane.normal, vec3_origin))
		{
			printf ("WARNING: brush plane with no normal\n");
			b->faces = f->next;
			free (f);
			break;
		}
		VectorNormalize (f->plane.normal);
		f->plane.dist = DotProduct (t3, f->plane.normal);

		//
		// fake proper texture vectors from QuakeEd style
		//
		{
			vec3_t	vecs[2];
			int		sv, tv;
			float	ang, sinv, cosv;
			float	ns, nt;

			TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

			// rotate axis
			if (rotate == 0)
			{ sinv = 0 ; cosv = 1; }
			else if (rotate == 90)
			{ sinv = 1 ; cosv = 0; }
			else if (rotate == 180)
			{ sinv = 0 ; cosv = -1; }
			else if (rotate == 270)
			{ sinv = -1 ; cosv = 0; }
			else
			{	
				ang = rotate / 180 * Q_PI;
				sinv = sin(ang);
				cosv = cos(ang);
			}

			if (vecs[0][0])
				sv = 0;
			else if (vecs[0][1])
				sv = 1;
			else
				sv = 2;
					
			if (vecs[1][0])
				tv = 0;
			else if (vecs[1][1])
				tv = 1;
			else
				tv = 2;
						
			for (i=0 ; i<2 ; i++)
			{
				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
				nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
				vecs[i][sv] = ns;
				vecs[i][tv] = nt;
			}

			for (i=0 ; i<2 ; i++)
			for (j=0 ; j<3 ; j++)
			tx.vecs[i][j] = vecs[i][j] / scale[i];

			tx.vecs[0][3] = shift[0];
			tx.vecs[1][3] = shift[1];
		}

		// unique the texinfo
		f->texinfo = FindTexinfo (&tx);		
	} while (1);
}
Пример #4
0
Файл: map.c Проект: kellyrm/Q1
/*
=================
ParseBrush
=================
*/
void ParseBrush (void)
{
	mbrush_t  *b;
	mface_t	  *f, *f2;
	vec3_t	  planepts[3];
	vec3_t	  t1, t2, t3, VAxis[2];
	int	  i, j, Faces;
	texinfo_t tx;
	vec_t	  d;
	vec_t	  shift[2], rotate, scale[2];
	qboolean  ok, Valve220;

        ExtendArray(mapbrushes, nummapbrushes);
	b = &mapbrushes[nummapbrushes];
	b->Line = scriptline;

	ok = GetToken (true);

	while (ok)
	{
		txcommand = 0;
		if (!strcmp (token, "}") )
		{
			if (!options.onlyents)
			{
				if (InvalidBrush(b, &Faces))
				{
					// Too few faces in brush or not closed; drop it
					DropBrush (b);
					nummapfaces -= Faces;
					// Note: texinfo array is not corrected here
					return;
				}
			}

			if (options.SortFace)
				SortFaces(b);

			break;
		}

	// read the three point plane definition
		for (i=0 ; i<3 ; i++)
		{
			if (i != 0)
				GetToken (true);
			if (strcmp (token, "(") )
				Message (MSGERR, "Invalid brush plane format on line %d", scriptline);

			for (j=0 ; j<3 ; j++)
			{
				GetToken (false);
				planepts[i][j] = atof(token);	// AR: atof
			}

			GetToken (false);
			if (strcmp (token, ")") )
				Message (MSGERR, "Invalid brush plane format on line %d", scriptline);

		}

	// read the texturedef
		memset (&tx, 0, sizeof(tx));
		GetToken (false);

		if (options.Q2Map)
			Q2ToQ1Tex (token);

		// Check texture name length
		if (strlen(token) > sizeof(char16) - 1)
			Message (MSGERR, "Texture name \"%s\" too long on line %d", token, scriptline);

		if (options.SolidMap && num_entities == 1 && token[0] == '*' ||
		    options.noents && num_entities > 1)
		{
			// No liquid worldbrushes or only worldbrushes allowed; drop brush
			DropBrush (b);

			while (GetToken(true) && strcmp(token, "}"))
				;

			return;
		}

		Valve220 = false;

		tx.miptex = FindMiptex (token);
		GetToken (false);
		
		if (!strcmp (token, "["))
		{
			// Valve 220 map import
			Valve220 = true;
			GetValveTex (VAxis[0]);
		}

		shift[0] = atoi(token);
		GetToken (false);
		
		if (Valve220)
		{
			// Skip ]
			GetToken (false);
			GetValveTex (VAxis[1]);
		}

		shift[1] = atoi(token);
		GetToken (false);

		if (Valve220)
			GetToken (false); // Skip ]

		rotate = atoi(token);
		GetToken (false);
		scale[0] = atof(token);
		GetToken (false);
		scale[1] = atof(token);

		if (options.Q2Map)
		{
			// Skip extra Q2 style face info
			GetToken (false);
			GetToken (false);
			GetToken (false);
		}

		ok = GetToken (true); // Note : scriptline normally gets advanced here

		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i=0 ; i<3 ; i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
					break;
			}
			if (i==3)
				break;
		}
		if (f2)
		{
			Message (MSGWARN, "Brush with duplicate plane on line %d", scriptline - 1);
			continue;
		}

		f = AllocOther(sizeof(mface_t));

	// convert to a vector / dist plane
		for (j=0 ; j<3 ; j++)
		{
			t1[j] = planepts[0][j] - planepts[1][j];
			t2[j] = planepts[2][j] - planepts[1][j];
			t3[j] = planepts[1][j];
		}

		CrossProduct(t1,t2, f->plane.normal);
		if (VectorCompare (f->plane.normal, vec3_origin))
		{
			Message (MSGWARN, "Brush plane with no normal on line %d", scriptline - 1);
			FreeOther (f);
			continue;
		}
		VectorNormalize (f->plane.normal);
		f->plane.dist = DotProduct (t3, f->plane.normal);

		f->next = b->faces;
		b->faces = f;

		if (txcommand=='1' || txcommand=='2')
		{		// from QuArK, the texture vectors are given directly from the three points
			vec3_t	TexPt[2];
			int		k;
			vec_t	dot22, dot23, dot33, mdet, aa, bb, dd;

			k = txcommand-'0';
			for (j=0; j<3; j++)
				TexPt[1][j] = (planepts[k][j] - planepts[0][j]) * ScaleCorrection;
			k = 3-k;
			for (j=0; j<3; j++)
				TexPt[0][j] = (planepts[k][j] - planepts[0][j]) * ScaleCorrection;

			dot22 = DotProduct (TexPt[0], TexPt[0]);
			dot23 = DotProduct (TexPt[0], TexPt[1]);
			dot33 = DotProduct (TexPt[1], TexPt[1]);
			mdet = dot22*dot33-dot23*dot23;
			if (mdet<1E-6 && mdet>-1E-6)
			{
				aa = bb = dd = 0;
				Message (MSGWARN, "Degenerate QuArK-style brush texture on line %d", scriptline - 1);
			}
			else
			{
				mdet = 1.0/mdet;
      			aa = dot33*mdet;
      			bb = -dot23*mdet;
				//cc = -dot23*mdet;     // cc = bb
				dd = dot22*mdet;
			}

			for (j=0; j<3; j++)
			{
				tx.vecs[0][j] = aa * TexPt[0][j] + bb * TexPt[1][j];
				tx.vecs[1][j] = -(/*cc*/ bb * TexPt[0][j] + dd * TexPt[1][j]);
			}

			tx.vecs[0][3] = -DotProduct(tx.vecs[0], planepts[0]);
			tx.vecs[1][3] = -DotProduct(tx.vecs[1], planepts[0]);
		}
		else if (Valve220)
		{
			// Valve 220 texturedef
			vec3_t vec;
			vec_t  tscale;

			// Prevent division by zero
			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

			// FIXME: If origin brushes are in use, this is where to fix their tex alignment!!!
			for (i = 0; i < 2; ++i)
			{
				tscale = 1 / scale[i];
				VectorScale(VAxis[i], tscale, vec);
				
				for (j = 0; j < 3; ++j)
					tx.vecs[i][j] = (float)vec[j];
				
				tx.vecs[i][3] = (float)shift[i] + DotProduct(vec3_origin, vec);
			}
		}
		else
	//
	// fake proper texture vectors from QuakeEd style
	//
		{
			vec3_t	vecs[2];
			int		sv, tv;
			vec_t	ang, sinv, cosv;
			vec_t	ns, nt;

			TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

		// rotate axis
			if (rotate == 0)
				{ sinv = 0 ; cosv = 1; }
			else if (rotate == 90)
				{ sinv = 1 ; cosv = 0; }
			else if (rotate == 180)
				{ sinv = 0 ; cosv = -1; }
			else if (rotate == 270)
				{ sinv = -1 ; cosv = 0; }
			else
			{
				ang = rotate / 180 * Q_PI;
				sinv = sin(ang);
				cosv = cos(ang);
			}

			if (vecs[0][0])
				sv = 0;
			else if (vecs[0][1])
				sv = 1;
			else
				sv = 2;

			if (vecs[1][0])
				tv = 0;
			else if (vecs[1][1])
				tv = 1;
			else
				tv = 2;

			for (i=0 ; i<2 ; i++)
			{
				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
				nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
				vecs[i][sv] = ns;
				vecs[i][tv] = nt;
			}

			for (i=0 ; i<2 ; i++)
				for (j=0 ; j<3 ; j++)
					tx.vecs[i][j] = vecs[i][j] / scale[i];

			tx.vecs[0][3] = shift[0];
			tx.vecs[1][3] = shift[1];
		}

	// unique the texinfo
		f->texinfo = FindTexinfo (&tx);
		nummapfaces++;
	};

	nummapbrushes++;
	b->next = mapent->brushes;
	mapent->brushes = b;
}
Пример #5
0
/*
=================
ParseBrush
=================
*/
void ParseBrush (void)
{
	int			i, j, sv, tv, hltexdef;
	vec_t		planepts[3][3], t1[3], t2[3], d, rotate, scale[2], vecs[2][4], ang, sinv, cosv, ns, nt;
	mbrush_t	*b;
	mface_t		*f, *f2;
	plane_t	plane;
	texinfo_t	tx;

	b = &mapbrushes[nummapbrushes];
	nummapbrushes++;
	b->next = mapent->brushes;
	mapent->brushes = b;

	do
	{
		if (!GetToken (true))
			break;
		if (!strcmp (token, "}") )
			break;

		// read the three point plane definition
		for (i = 0;i < 3;i++)
		{
			if (i != 0)
				GetToken (true);
			if (strcmp (token, "(") )
				Error ("parsing brush on line %d\n", scriptline);

			for (j = 0;j < 3;j++)
			{
				GetToken (false);
				planepts[i][j] = atof(token); // LordHavoc: float coords
			}

			GetToken (false);
			if (strcmp (token, ")") )
				Error ("parsing brush on line %d\n", scriptline);
		}

		//fflush(stdout);

		// convert points to a plane
		VectorSubtract(planepts[0], planepts[1], t1);
		VectorSubtract(planepts[2], planepts[1], t2);
		CrossProduct(t1, t2, plane.normal);
		VectorNormalize(plane.normal);
		plane.dist = DotProduct(planepts[1], plane.normal);

		// read the texturedef
		memset (&tx, 0, sizeof(tx));
		GetToken (false);
		tx.miptex = FindMiptex (token);
		GetToken (false);
		if ((hltexdef = !strcmp(token, "[")))
		{
			// S vector
			GetToken(false);
			vecs[0][0] = atof(token);
			GetToken(false);
			vecs[0][1] = atof(token);
			GetToken(false);
			vecs[0][2] = atof(token);
			GetToken(false);
			vecs[0][3] = atof(token);
			// ]
			GetToken(false);
			// [
			GetToken(false);
			// T vector
			GetToken(false);
			vecs[1][0] = atof(token);
			GetToken(false);
			vecs[1][1] = atof(token);
			GetToken(false);
			vecs[1][2] = atof(token);
			GetToken(false);
			vecs[1][3] = atof(token);
			// ]
			GetToken(false);
		}
		else
		{
			vecs[0][3] = atof(token); // LordHavoc: float coords
			GetToken (false);
			vecs[1][3] = atof(token); // LordHavoc: float coords
		}
		GetToken (false);
		rotate = atof(token);	 // LordHavoc: float coords
		GetToken (false);
		scale[0] = atof(token); // LordHavoc: was already float coords
		GetToken (false);
		scale[1] = atof(token); // LordHavoc: was already float coords

		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i = 0;i < 3;i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
					break;
			}
			if (i==3)
				break;
		}
		if (f2)
		{
			printf ("WARNING: brush with duplicate plane (first point is at %g %g %g, .map file line number %d)\n", planepts[0][0], planepts[0][1], planepts[0][2], scriptline);
			continue;
		}

		if (DotProduct(plane.normal, plane.normal) < 0.1)
		{
			printf ("WARNING: brush plane with no normal on line %d\n", scriptline);
			continue;
		}

		/*
		// LordHavoc: fix for CheckFace: point off plane errors in some maps (most notably QOOLE ones),
		// and hopefully preventing most 'portal clipped away' warnings
		VectorNormalize (plane.normal);
		for (j = 0;j < 3;j++)
			plane.normal[j] = (Q_rint((vec_t) plane.normal[j] * (vec_t) 8.0)) * (vec_t) (1.0 / 8.0);
		VectorNormalize (plane.normal);
		plane.dist = DotProduct (t3, plane.normal);
		d = (Q_rint(plane.dist * 8.0)) * (1.0 / 8.0);
		//if (fabs(d - plane.dist) >= (0.4 / 8.0))
		//	printf("WARNING: correcting minor math errors in brushface on line %d\n", scriptline);
		plane.dist = d;
		*/

		/*
		VectorNormalize (plane.normal);
		plane.dist = DotProduct (t3, plane.normal);

		VectorCopy(plane.normal, v);
		//for (j = 0;j < 3;j++)
		//	v[j] = (Q_rint((vec_t) v[j] * (vec_t) 32.0)) * (vec_t) (1.0 / 32.0);
		VectorNormalize (v);
		d = (Q_rint(DotProduct (t3, v) * 8.0)) * (1.0 / 8.0);

		// if deviation is too high, warn  (frequently happens on QOOLE maps)
		if (fabs(DotProduct(v, plane.normal) - 1.0) > (0.5 / 32.0)
		 || fabs(d - plane.dist) >= (0.25 / 8.0))
			printf("WARNING: minor misalignment of brushface on line %d\n"
			       "normal     %f %f %f (l: %f d: %f)\n"
			       "rounded to %f %f %f (l: %f d: %f r: %f)\n",
			       scriptline,
			       (vec_t) plane.normal[0], (vec_t) plane.normal[1], (vec_t) plane.normal[2], (vec_t) sqrt(DotProduct(plane.normal, plane.normal)), (vec_t) DotProduct (t3, plane.normal),
			       (vec_t) v[0], (vec_t) v[1], (vec_t) v[2], (vec_t) sqrt(DotProduct(v, v)), (vec_t) DotProduct(t3, v), (vec_t) d);
		//VectorCopy(v, plane.normal);
		//plane.dist = d;
		*/

		if (!hltexdef)
		{
			// fake proper texture vectors from QuakeEd style
			TextureAxisFromPlane(&plane, vecs[0], vecs[1]);
		}

		// rotate axis
		     if (rotate ==  0) {sinv = 0;cosv = 1;}
		else if (rotate == 90) {sinv = 1;cosv = 0;}
		else if (rotate == 180) {sinv = 0;cosv = -1;}
		else if (rotate == 270) {sinv = -1;cosv = 0;}
		else {ang = rotate * (Q_PI / 180);sinv = sin(ang);cosv = cos(ang);}

		// LordHavoc: I don't quite understand this
		for (sv = 0;sv < 2 && !vecs[0][sv];sv++);
		for (tv = 0;tv < 2 && !vecs[1][tv];tv++);

		for (i = 0;i < 2;i++)
		{
			// rotate
			ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
			nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
			vecs[i][sv] = ns;
			vecs[i][tv] = nt;
			// scale and store into texinfo
			d = 1.0 / (scale[i] ? scale[i] : 1.0);
			for (j = 0;j < 3;j++)
				tx.vecs[i][j] = vecs[i][j] * d;
			tx.vecs[i][3] = vecs[i][3];
		}

		f = malloc(sizeof(mface_t));
		f->next = b->faces;
		b->faces = f;
		f->plane = plane;
		f->texinfo = FindTexinfo (&tx);
		nummapbrushfaces++;
	}
	while (1);
}
Пример #6
0
static void
ParseBrush(void)
{
    vec3_t planepts[3];
    vec3_t t1, t2, t3;
    int i, j;
    texinfo_t tx;
    vec_t d;
    int shift[2], rotate;
    vec_t scale[2];
    int iFace;
    int tx_type;

    map.rgBrushes[map.iBrushes].iFaceEnd = map.iFaces + 1;

    while (ParseToken(PARSE_NORMAL)) {
	if (!strcmp(token, "}"))
	    break;

	// read the three point plane definition
	for (i = 0; i < 3; i++) {
	    if (i != 0)
		ParseToken(PARSE_NORMAL);
	    if (strcmp(token, "("))
		Message(msgError, errInvalidMapPlane, linenum);

	    for (j = 0; j < 3; j++) {
		ParseToken(PARSE_SAMELINE);
		planepts[i][j] = atof(token);
	    }

	    ParseToken(PARSE_SAMELINE);
	    if (strcmp(token, ")"))
		Message(msgError, errInvalidMapPlane, linenum);
	}

	// read the texturedef
	memset(&tx, 0, sizeof(tx));
	ParseToken(PARSE_SAMELINE);
	tx.miptex = FindMiptex(token);
	ParseToken(PARSE_SAMELINE);
	shift[0] = atoi(token);
	ParseToken(PARSE_SAMELINE);
	shift[1] = atoi(token);
	ParseToken(PARSE_SAMELINE);
	rotate = atoi(token);
	ParseToken(PARSE_SAMELINE);
	scale[0] = atof(token);
	ParseToken(PARSE_SAMELINE);
	scale[1] = atof(token);

	// if the three points are all on a previous plane, it is a
	// duplicate plane
	for (iFace = map.rgBrushes[map.iBrushes].iFaceEnd - 1;
	     iFace > map.iFaces; iFace--) {
	    for (i = 0; i < 3; i++) {
		d = DotProduct(planepts[i], map.rgFaces[iFace].plane.normal) -
		    map.rgFaces[iFace].plane.dist;
		if (d < -ON_EPSILON || d > ON_EPSILON)
		    break;
	    }
	    if (i == 3)
		break;
	}
	if (iFace > map.iFaces) {
	    Message(msgWarning, warnBrushDuplicatePlane, linenum);
	    continue;
	}

	if (map.iFaces < 0)
	    Message(msgError, errLowFaceCount);

	// convert to a vector / dist plane
	for (j = 0; j < 3; j++) {
	    t1[j] = planepts[0][j] - planepts[1][j];
	    t2[j] = planepts[2][j] - planepts[1][j];
	    t3[j] = planepts[1][j];
	}

	CrossProduct(t1, t2, map.rgFaces[map.iFaces].plane.normal);
	if (VectorCompare(map.rgFaces[map.iFaces].plane.normal, vec3_origin)) {
	    Message(msgWarning, warnNoPlaneNormal, linenum);
	    break;
	}
	VectorNormalize(map.rgFaces[map.iFaces].plane.normal);
	map.rgFaces[map.iFaces].plane.dist =
	    DotProduct(t3, map.rgFaces[map.iFaces].plane.normal);

	tx_type = ParseExtendedTX();
	switch (tx_type) {
	case TX_QUARK_TYPE1:
	case TX_QUARK_TYPE2:
	    SetTexinfo_QuArK(planepts, tx_type, &tx);
	    break;
	default:
	    SetTexinfo_QuakeEd(shift, rotate, scale, &tx);
	    break;
	}

	// unique the texinfo
	map.rgFaces[map.iFaces].texinfo = FindTexinfo(&tx);
	map.iFaces--;
	Message(msgPercent, map.cFaces - map.iFaces - 1, map.cFaces);
    }

    map.rgBrushes[map.iBrushes].iFaceStart = map.iFaces + 1;
    map.iBrushes--;
}
Пример #7
0
void ParseBrush (void)

{

	mbrush_t		*b;

	mface_t		*f, *f2;

	vec3_t		planepts[3];

	vec3_t			t1, t2, t3;

	int			i,j;

	texinfo_t	tx;

	double		d;

	float		shift[2], rotate, scale[2];

	char		name[64];



	b = &mapbrushes[nummapbrushes];

		

	do

	{

		if (!GetToken (true))

			break;

		if (!strcmp (token, "}") )

			break;

		

	// read the three point plane definition

		for (i=0 ; i<3 ; i++)

		{

			if (i != 0)

				GetToken (true);

			if (strcmp (token, "(") )

				logerror ("parsing brush"); // jkrige - was Error()

			

			for (j=0 ; j<3 ; j++)

			{

				GetToken (false);

				// jkrige - floating point texture support
				//planepts[i][j] = atoi(token);
				planepts[i][j] = atof(token);
				// jkrige - floating point texture support

			}

			

			GetToken (false);

			if (strcmp (token, ")") )

				logerror ("parsing brush"); // jkrige - was Error()

				

		}



	// read the texturedef

		memset (&tx, 0, sizeof(tx));

		GetToken (false);



		strcpy (name, token);	// JDC 8/8/97: for origin texture



		tx.miptex = FindMiptex (token);
		
		GetToken (false);
		
		shift[0] = atoi(token);
		
		GetToken (false);
		
		shift[1] = atoi(token);
		
		GetToken (false);
		
		rotate = atoi(token);	
		
		GetToken (false);

		scale[0] = atof(token);

		GetToken (false);

		scale[1] = atof(token);

		GetToken (false);

		b->Light = atol(token);



		// if the three points are all on a previous plane, it is a

		// duplicate plane

		for (f2 = b->faces ; f2 ; f2=f2->next)

		{

			for (i=0 ; i<3 ; i++)

			{

				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;

				if (d < -ON_EPSILON || d > ON_EPSILON)

					break;

			}

			if (i==3)

				break;

		}

		if (f2)		

		{

			logprint ("WARNING: brush with duplicate plane\n");

			continue;

		}



		f = malloc(sizeof(mface_t));

		f->next = b->faces;

		b->faces = f;

		

	// convert to a vector / dist plane

		for (j=0 ; j<3 ; j++)

		{

			t1[j] = planepts[0][j] - planepts[1][j];

			t2[j] = planepts[2][j] - planepts[1][j];

			t3[j] = planepts[1][j];

		}

		

		CrossProduct(t1,t2, f->plane.normal);

		if (VectorCompare (f->plane.normal, vec3_origin))

		{

			logprint ("WARNING: brush plane with no normal\n");

			b->faces = f->next;

			free (f);

			break;

		}

		VectorNormalize (f->plane.normal);

		f->plane.dist = DotProduct (t3, f->plane.normal);



	//

	// fake proper texture vectors from QuakeEd style

	//

		{

			vec3_t	vecs[2];

			int		sv, tv;

			float	ang, sinv, cosv;

			float	ns, nt;

			

			TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

		

			if (!scale[0])

				scale[0] = 1;

			if (!scale[1])

				scale[1] = 1;

		

		

		// rotate axis

			if (rotate == 0)

				{ sinv = 0 ; cosv = 1; }

			else if (rotate == 90)

				{ sinv = 1 ; cosv = 0; }

			else if (rotate == 180)

				{ sinv = 0 ; cosv = -1; }

			else if (rotate == 270)

				{ sinv = -1 ; cosv = 0; }

			else

			{	

				ang = rotate / 180 * Q_PI;

				sinv = sin(ang);

				cosv = cos(ang);

			}

		

			if (vecs[0][0])

				sv = 0;

			else if (vecs[0][1])

				sv = 1;

			else

				sv = 2;

						

			if (vecs[1][0])

				tv = 0;

			else if (vecs[1][1])

				tv = 1;

			else

				tv = 2;

							

			for (i=0 ; i<2 ; i++)

			{

				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];

				nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];

				vecs[i][sv] = ns;

				vecs[i][tv] = nt;

			}

		

			for (i=0 ; i<2 ; i++)

				for (j=0 ; j<3 ; j++)

					tx.vecs[i][j] = vecs[i][j] / scale[i];

		

			tx.vecs[0][3] = shift[0];

			tx.vecs[1][3] = shift[1];

		}

	

	// unique the texinfo

		f->texinfo = FindTexinfo (&tx);		

	} while (1);



	// JDC 8/8/97

	// origin brushes are removed, but they set

	// the rotation origin for the rest of the brushes

	// in the entity

	//

	if (Q_strncasecmp (name, "origin",6))

	{	// keep it

		nummapbrushes++;

		b->next = mapent->brushes;

		mapent->brushes = b;

	}

	else

	{	// don't save the brush, just use as entity origin

		char	string[32];

		vec3_t	origin;



		if (num_entities == 1)

			logerror ("Origin brushes not allowed in world"); // jkrige - was Error()



		BrushOrigin (b, origin);



		sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);

		SetKeyValue (mapent, "origin", string);



		VectorCopy (origin, mapent->origin);



		memset (b, 0, sizeof(*b));

	}

}
Пример #8
0
static void
ParseBrush(parser_t *parser, mapbrush_t *brush)
{
    vec3_t planepts[3];
    vec3_t t1, t2, t3;
    int i, j;
    texinfo_t tx;
    vec_t d;
    int shift[2], rotate;
    vec_t scale[2];
    int tx_type;
    plane_t *plane;
    mapface_t *face, *checkface;

    brush->faces = face = map.faces + map.numfaces;
    while (ParseToken(parser, PARSE_NORMAL)) {
	if (!strcmp(parser->token, "}"))
	    break;

	// read the three point plane definition
	for (i = 0; i < 3; i++) {
	    if (i != 0)
		ParseToken(parser, PARSE_NORMAL);
	    if (strcmp(parser->token, "("))
		Error(errInvalidMapPlane, parser->linenum);

	    for (j = 0; j < 3; j++) {
		ParseToken(parser, PARSE_SAMELINE);
		planepts[i][j] = atof(parser->token);
	    }

	    ParseToken(parser, PARSE_SAMELINE);
	    if (strcmp(parser->token, ")"))
		Error(errInvalidMapPlane, parser->linenum);
	}

	// read the texturedef
	memset(&tx, 0, sizeof(tx));
	ParseToken(parser, PARSE_SAMELINE);
	tx.miptex = FindMiptex(parser->token);
	ParseToken(parser, PARSE_SAMELINE);
	shift[0] = atoi(parser->token);
	ParseToken(parser, PARSE_SAMELINE);
	shift[1] = atoi(parser->token);
	ParseToken(parser, PARSE_SAMELINE);
	rotate = atoi(parser->token);
	ParseToken(parser, PARSE_SAMELINE);
	scale[0] = atof(parser->token);
	ParseToken(parser, PARSE_SAMELINE);
	scale[1] = atof(parser->token);

	// if the three points are all on a previous plane, it is a
	// duplicate plane
	for (checkface = brush->faces; checkface < face; checkface++) {
	    plane = &checkface->plane;
	    for (i = 0; i < 3; i++) {
		d = DotProduct(planepts[i], plane->normal) - plane->dist;
		if (d < -ON_EPSILON || d > ON_EPSILON)
		    break;
	    }
	    if (i == 3)
		break;
	}
	if (checkface < face) {
	    Message(msgWarning, warnBrushDuplicatePlane, parser->linenum);
	    continue;
	}

	if (map.numfaces == map.maxfaces)
	    Error(errLowFaceCount);

	// convert to a vector / dist plane
	for (j = 0; j < 3; j++) {
	    t1[j] = planepts[0][j] - planepts[1][j];
	    t2[j] = planepts[2][j] - planepts[1][j];
	    t3[j] = planepts[1][j];
	}

	plane = &face->plane;
	CrossProduct(t1, t2, plane->normal);
	if (VectorCompare(plane->normal, vec3_origin)) {
	    Message(msgWarning, warnNoPlaneNormal, parser->linenum);
	    continue;
	}
	VectorNormalize(plane->normal);
	plane->dist = DotProduct(t3, plane->normal);

	tx_type = ParseExtendedTX(parser);
	switch (tx_type) {
	case TX_QUARK_TYPE1:
	case TX_QUARK_TYPE2:
	    SetTexinfo_QuArK(parser, &planepts[0], tx_type, &tx);
	    break;
	default:
	    SetTexinfo_QuakeEd(plane, shift, rotate, scale, &tx);
	    break;
	}
	face->texinfo = FindTexinfo(&tx);

	face++;
	map.numfaces++;
	Message(msgPercent, map.numfaces, map.maxfaces);
    }

    brush->numfaces = face - brush->faces;
    if (!brush->numfaces)
	brush->faces = NULL;
}