예제 #1
0
bool Primitive_Parse( brush_t *pBrush ){
	char *token = Token();

	GetToken( true );
	if ( !strcmp( token, "patchDef2" ) ) {
		pBrush->patchBrush = true;
		pBrush->pPatch = Patch_Alloc();
		pBrush->pPatch->pSymbiot = pBrush;
		Patch_Parse( pBrush->pPatch );
		GetToken( true ); //}

		// A patchdef should never be loaded from a quake2 map file
		// so we just return false and the brush+patch gets freed
		// and the user gets told.
		if ( g_MapVersion != MAPVERSION_Q3 ) {
			// FIXME: Hydra - I wanted to write out a line number here, but I can't because there's no API to access the core's "scriptline" variable.
			Syn_Printf( "ERROR: patchDef2's are not supported in Quake%d format .map files!\n",g_MapVersion );
			abortcode = MAP_WRONGVERSION;
			return false;
		}
	}
	else if ( !strcmp( token, "brushDef" ) ) {
		pBrush->bBrushDef = true;
		GetToken( true ); // {
		while ( 1 )
		{
			face_t    *f = pBrush->brush_faces;
			pBrush->brush_faces = Face_Alloc();
			Face_Parse( pBrush->brush_faces, true );
			pBrush->brush_faces->next = f;
			// check for end of brush
			GetToken( true );
			if ( strcmp( token,"}" ) == 0 ) {
				break;
			}
			UnGetToken();
		}
		GetToken( true ); // }
	}
	else
	{
		UnGetToken();
		while ( 1 )
		{
			face_t    *f = pBrush->brush_faces;
			pBrush->brush_faces = Face_Alloc();
			Face_Parse( pBrush->brush_faces );
			pBrush->brush_faces->next = f;

			// check for end of brush
			GetToken( true );
			if ( strcmp( token,"}" ) == 0 ) {
				break;
			}
			UnGetToken();
		}
	}
	return true;
}
예제 #2
0
face_t* MakePlaneList(face_t* top, face_t* bottom)
{
	face_t*		fList;
	face_t*		curFace;
	face_t*		newTop;
	face_t*		newBot;
	int			i;
	int			j;
	int			k;
	vec3_t		t1, t2, t3;
	
	fList = NULL;
	newTop = Face_Alloc();
	CopyFace(top, newTop);
	newBot = Face_Alloc();
	CopyFace(bottom, newBot);
	WrapFaces(newTop, newBot);
	for (i = 0; i<newTop->face_winding->numpoints; i++)
	{
		if (i == (newTop->face_winding->numpoints - 1))
		{
			j = 0;
		}
		else
		{
			j = i + 1;
		}
		
		curFace = Face_Alloc();
		VectorCopy(newTop->face_winding->points[j],curFace->planepts[0]);
		VectorCopy(newTop->face_winding->points[i],curFace->planepts[1]);
		VectorCopy(newBot->face_winding->points[i],curFace->planepts[2]);
	
		for (k=0 ; k<3 ; k++)
		{
			t1[k] = curFace->planepts[0][k] - curFace->planepts[1][k];
			t2[k] = curFace->planepts[2][k] - curFace->planepts[1][k];
			t3[k] = curFace->planepts[1][k];
		}
		
		CrossProduct(t1,t2, curFace->plane.normal);
		if (VectorCompare (curFace->plane.normal, vec3_origin))
		{
			printf ("WARNING: brush plane with no normal\n");
		
		}
		VectorNormalize (curFace->plane.normal);
		curFace->plane.dist = DotProduct (t3, curFace->plane.normal);
	
		curFace->next = fList;
		fList = curFace;
  	}	// for loop
	return fList;
}
예제 #3
0
void WINAPI QERApp_AddFaceData(LPVOID pv, _QERFaceData *pData)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	brush_t* pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv);
  if (pBrush != NULL)
  {
		face_t *f = Face_Alloc();
		f->texdef = g_qeglobals.d_texturewin.texdef;
		f->texdef.flags = pData->m_nFlags;
    f->texdef.contents = pData->m_nContents;
    f->texdef.value = pData->m_nValue;
    f->texdef.rotate = pData->m_fRotate;
    f->texdef.shift[0] = pData->m_fShift[0];
    f->texdef.shift[1] = pData->m_fShift[1];
    f->texdef.scale[0] = pData->m_fScale[0];
    f->texdef.scale[1] = pData->m_fScale[1];
    //strcpy(f->texdef.name, pData->m_TextureName);
    f->texdef.SetName(pData->m_TextureName);
		f->next = pBrush->brush_faces;
		pBrush->brush_faces = f;
		VectorCopy (pData->m_v1, f->planepts[0]);
		VectorCopy (pData->m_v2, f->planepts[1]);
		VectorCopy (pData->m_v3, f->planepts[2]);
		Sys_MarkMapModified();		// PGM
  }
}
brush_t *BrushFromMapBrush(idMapBrush *mapbrush, idVec3 origin) {
	brush_t *b = NULL;
	if (mapbrush) {
		b = Brush_Alloc();
		int count = mapbrush->GetNumSides();
		for (int i = 0; i < count; i++) {
			idMapBrushSide *side = mapbrush->GetSide(i);
			face_t *f = Face_Alloc();
			f->next = NULL;
			if (!b->brush_faces) {
				b->brush_faces = f;
			}
			else {
				face_t	*scan;
				for (scan = b->brush_faces; scan->next; scan = scan->next) {
					;
				}
				scan->next = f;
			}
			f->plane = side->GetPlane();
			f->originalPlane = f->plane;
			f->dirty = false;

// ---> sikk - Old Brush Format
/*			idWinding w;
			w.BaseForPlane(f->plane);

			for (int j = 0; j < 3; j++) {
				f->planepts[j].x = w[j].x + origin.x;
				f->planepts[j].y = w[j].y + origin.y;
				f->planepts[j].z = w[j].z + origin.z;
			}*/
			
			side->GetPlanePoints( f->planepts[0], f->planepts[1], f->planepts[2] );
			for ( int j = 0; j < 3; j++ ) {
				f->planepts[j] += origin;
			}
// <--- sikk - Old Brush Format



			idVec3 mat[2];
			side->GetTextureMatrix(mat[0], mat[1]);
			f->brushprimit_texdef.coords[0][0] = mat[0][0];
			f->brushprimit_texdef.coords[0][1] = mat[0][1];
			f->brushprimit_texdef.coords[0][2] = mat[0][2];
			f->brushprimit_texdef.coords[1][0] = mat[1][0];
			f->brushprimit_texdef.coords[1][1] = mat[1][1];
			f->brushprimit_texdef.coords[1][2] = mat[1][2];

			f->texdef.SetName(side->GetMaterial());
		}
	}
	return b;
}
예제 #5
0
face_t	*Face_Clone (face_t *f)
{
	face_t	*n;

	n = Face_Alloc();
	n->texdef = f->texdef;
	memcpy (n->planepts, f->planepts, sizeof(n->planepts));

	// all other fields are derived, and will be set by Brush_Build
	return n;
}
예제 #6
0
void Brush_XMLParse( brush_t *pBrush, xmlNodePtr primitive ){
	face_t    *f;

	for ( xmlNodePtr current = primitive->children; current != NULL; current = current->next )
	{
		if ( current->type != XML_ELEMENT_NODE ) {
			continue;
		}
		f = pBrush->brush_faces;
		pBrush->brush_faces = Face_Alloc();
		Face_XMLParse( pBrush->brush_faces, current );
		pBrush->brush_faces->next = f;
	}
}
예제 #7
0
void CPlugInManager::AddFaceToBrushHandle(void * vp, vec3_t v1, vec3_t v2, vec3_t v3)
{
  brush_t *bp = FindBrushHandle(vp);
  if (bp != NULL)
  {
		face_t *f = Face_Alloc();
		f->texdef = g_qeglobals.d_texturewin.texdef;
		f->texdef.flags &= ~SURF_KEEP;
		f->texdef.contents &= ~CONTENTS_KEEP;
		f->next = bp->brush_faces;
		bp->brush_faces = f;
		VectorCopy (v1, f->planepts[0]);
		VectorCopy (v2, f->planepts[1]);
		VectorCopy (v3, f->planepts[2]);
  }
}
예제 #8
0
/*	Makes the current brushhave the given number of 2d sides
*/
void Brush_MakeSided(int sides)
{
	int			i;
	vec3_t		mins, maxs;
	brush_t		*b;
	texdef_t	*texdef;
	face_t		*f;
	vec3_t		mid;
	float		width,sv,cv;

	if(sides < 3)
	{
		Sys_Status ("Bad sides number", 0);
		return;
	}
	else if(!QE_SingleBrush())
	{
		Sys_Status ("Must have a single brush selected", 0 );
		return;
	}

	b = selected_brushes.next;
	Math_VectorCopy(b->mins,mins);
	Math_VectorCopy(b->maxs,maxs);
	texdef = &g_qeglobals.d_texturewin.texdef;

	Brush_Free (b);

	// find center of brush
	width = 8;
	for (i=0 ; i<2 ; i++)
	{
		mid[i] = (maxs[i] + mins[i])*0.5;
		if (maxs[i] - mins[i] > width)
			width = maxs[i] - mins[i];
	}
	width /= 2;

	b = qmalloc (sizeof(brush_t));

	// create top face
	f = Face_Alloc();
	f->texdef = *texdef;
	f->next = b->brush_faces;
	b->brush_faces = f;

	f->planepts[2][0] = mins[0];f->planepts[2][1] = mins[1];f->planepts[2][2] = maxs[2];
	f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = maxs[2];
	f->planepts[0][0] = maxs[0];f->planepts[0][1] = maxs[1];f->planepts[0][2] = maxs[2];

	// create bottom face
	f = Face_Alloc();
	f->texdef	= *texdef;
	f->next		= b->brush_faces;

	b->brush_faces = f;

	f->planepts[0][0] = mins[0];f->planepts[0][1] = mins[1];f->planepts[0][2] = mins[2];
	f->planepts[1][0] = maxs[0];f->planepts[1][1] = mins[1];f->planepts[1][2] = mins[2];
	f->planepts[2][0] = maxs[0];f->planepts[2][1] = maxs[1];f->planepts[2][2] = mins[2];

	for (i=0 ; i<sides ; i++)
	{
		f = Face_Alloc();
		f->texdef = *texdef;
		f->next = b->brush_faces;
		b->brush_faces = f;

		sv = sin (i*3.14159265*2/sides);
		cv = cos (i*3.14159265*2/sides);

		f->planepts[0][0] = floor(mid[0]+width*cv+0.5);
		f->planepts[0][1] = floor(mid[1]+width*sv+0.5);
		f->planepts[0][2] = mins[2];

		f->planepts[1][0] = f->planepts[0][0];
		f->planepts[1][1] = f->planepts[0][1];
		f->planepts[1][2] = maxs[2];

		f->planepts[2][0] = floor(f->planepts[0][0] - width*sv + 0.5);
		f->planepts[2][1] = floor(f->planepts[0][1] + width*cv + 0.5);
		f->planepts[2][2] = maxs[2];

	}

	Brush_AddToList (b, &selected_brushes);

	Entity_LinkBrush (world_entity, b);

	Brush_Build( b );

	Sys_UpdateWindows (W_ALL);
}
예제 #9
0
/*	Create non-textured blocks for entities
	The brush is NOT linked to any list
*/
brush_t	*Brush_Create (vec3_t mins, vec3_t maxs, texdef_t *texdef)
{
	int		i, j;
	vec3_t	pts[4][2];
	face_t	*f;
	brush_t	*b;

	for (i=0 ; i<3 ; i++)
		if (maxs[i] < mins[i])
			Error ("Brush_InitSolid: backwards");

	b = (brush_t*)qmalloc(sizeof(brush_t));

	pts[0][0][0] = mins[0];
	pts[0][0][1] = mins[1];

	pts[1][0][0] = mins[0];
	pts[1][0][1] = maxs[1];

	pts[2][0][0] = maxs[0];
	pts[2][0][1] = maxs[1];

	pts[3][0][0] = maxs[0];
	pts[3][0][1] = mins[1];

	for (i=0 ; i<4 ; i++)
	{
		pts[i][0][2] = mins[2];
		pts[i][1][0] = pts[i][0][0];
		pts[i][1][1] = pts[i][0][1];
		pts[i][1][2] = maxs[2];
	}

	for (i=0 ; i<4 ; i++)
	{
		f = Face_Alloc();
		f->texdef = *texdef;
		f->next = b->brush_faces;
		b->brush_faces = f;
		j = (i+1)%4;

		Math_VectorCopy(pts[j][1],f->planepts[0]);
		Math_VectorCopy(pts[i][1],f->planepts[1]);
		Math_VectorCopy(pts[i][0],f->planepts[2]);
	}

	f = Face_Alloc();
	f->texdef	= *texdef;
	f->next		= b->brush_faces;

	b->brush_faces = f;

	Math_VectorCopy(pts[0][1],f->planepts[0]);
	Math_VectorCopy(pts[1][1],f->planepts[1]);
	Math_VectorCopy(pts[2][1],f->planepts[2]);

	f = Face_Alloc();
	f->texdef	= *texdef;
	f->next		= b->brush_faces;

	b->brush_faces = f;

	Math_VectorCopy(pts[2][0],f->planepts[0]);
	Math_VectorCopy(pts[1][0],f->planepts[1]);
	Math_VectorCopy(pts[0][0],f->planepts[2]);

	return b;
}
예제 #10
0
/*	The brush is NOT linked to any list
*/
brush_t *Brush_Parse(void)
{
	brush_t		*b;
	face_t		*f;
	int			i,j;

	g_qeglobals.d_parsed_brushes++;
	b = (brush_t*)qmalloc(sizeof(brush_t));

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

		f = Face_Alloc();

		// add the brush to the end of the chain, so
		// loading and saving a map doesn't reverse the order

		f->next = NULL;
		if (!b->brush_faces)
			b->brush_faces = f;
		else
		{
			face_t *scan;

			for (scan=b->brush_faces ; scan->next ; scan=scan->next)
				;
			scan->next = f;
		}

		// 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);
				f->planepts[i][j] = atoi(token);
			}

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

	// read the texturedef
		GetToken(false);
		strcpy(f->texdef.name,token);
		GetToken(false);
		f->texdef.shift[0] = atoi(token);
		GetToken(false);
		f->texdef.shift[1] = atoi(token);
		GetToken(false);
		f->texdef.rotate = atoi(token);
		GetToken(false);
		f->texdef.scale[0] = atof(token);
		GetToken(false);
		f->texdef.scale[1] = atof(token);

		// the flags and value field aren't necessarily present
		f->d_texture		= Texture_ForName( f->texdef.name );
		f->texdef.flags		= f->d_texture->flags;
		f->texdef.value		= f->d_texture->value;
		f->texdef.contents	= f->d_texture->contents;

		if (TokenAvailable ())
		{
			GetToken(false);
			f->texdef.contents = atoi(token);
			GetToken(false);
			f->texdef.flags = atoi(token);
			GetToken(false);
			f->texdef.value = atoi(token);
		}
	} while (1);

	return b;
}
예제 #11
0
/*
=============
Brush_MergeList

 Tries to merge all brushes in the list into one new brush.
 The input brush list stays intact.
 Returns NULL if no merged brush can be created.
 To create a new brush the brushes in the list may not overlap and
 the outer faces of the brushes together should make a new convex brush.

 if onlyshape is true then the merge is allowed based on the shape only
 otherwise the texture references of faces in the same plane have to
 be the same as well.
=============
*/
brush_t *Brush_MergeList(brush_t *brushlist, int onlyshape)
{
	brush_t *brush1, *brush2, *brush3, *newbrush;
	face_t *face1, *face2, *face3, *newface, *f;

	if (!brushlist) return NULL;
	for (brush1 = brushlist; brush1; brush1 = brush1->next)
	{
		// check if the new brush would be convex... flipped planes make a brush concave
		for (face1 = brush1->brush_faces; face1; face1 = face1->next)
		{
			// don't check face1 if it touches another brush
			for (brush2 = brushlist; brush2; brush2 = brush2->next)
			{
				if (brush2 == brush1) continue;
				for (face2 = brush2->brush_faces; face2; face2 = face2->next)
				{
					if (Plane_Equal(&face1->plane, &face2->plane, true))
					{
						break;
					}
				}
				if (face2) break;
			}
			// if face1 touches another brush
			if (brush2) continue;
			//
			for (brush2 = brush1->next; brush2; brush2 = brush2->next)
			{
				// don't check the faces of brush 2 touching another brush
				for (face2 = brush2->brush_faces; face2; face2 = face2->next)
				{
					for (brush3 = brushlist; brush3; brush3 = brush3->next)
					{
						if (brush3 == brush2) continue;
						for (face3 = brush3->brush_faces; face3; face3 = face3->next)
						{
							if (Plane_Equal(&face2->plane, &face3->plane, true)) break;
						}
						if (face3) break;
					}
					// if face2 touches another brush
					if (brush3) continue;
					//
					if (Plane_Equal(&face1->plane, &face2->plane, false))
					{
						//if the texture references should be the same but are not
						if (!onlyshape && stricmp(face1->texdef.name, face2->texdef.name) != 0) return NULL;
						continue;
					}
					//
					if (Winding_PlanesConcave(face1->face_winding, face2->face_winding,
											face1->plane.normal, face2->plane.normal,
											face1->plane.dist, face2->plane.dist))
					{
						return NULL;
					}
				}
			}
		}
	}
	//
	newbrush = Brush_Alloc();
	//
	for (brush1 = brushlist; brush1; brush1 = brush1->next)
	{
		for (face1 = brush1->brush_faces; face1; face1 = face1->next)
		{
			// don't add face1 to the new brush if it touches another brush
			for (brush2 = brushlist; brush2; brush2 = brush2->next)
			{
				if (brush2 == brush1) continue;
				for (face2 = brush2->brush_faces; face2; face2 = face2->next)
				{
					if (Plane_Equal(&face1->plane, &face2->plane, true))
					{
						break;
					}
				}
				if (face2) break;
			}
			if (brush2) continue;
			// don't add faces with the same plane twice
			for (f = newbrush->brush_faces; f; f = f->next)
			{
				if (Plane_Equal(&face1->plane, &f->plane, false))
					break;
				if (Plane_Equal(&face1->plane, &f->plane, true))
					break;
			}
			if (f)
				continue;
			//
			newface = Face_Alloc();
			newface->texdef = face1->texdef;
			VectorCopy(face1->planepts[0], newface->planepts[0]);
			VectorCopy(face1->planepts[1], newface->planepts[1]);
			VectorCopy(face1->planepts[2], newface->planepts[2]);
			newface->plane = face1->plane;
			newface->next = newbrush->brush_faces;
			newbrush->brush_faces = newface;
		}
	}
	// link the new brush to an entity
	Entity_LinkBrush (brushlist->owner, newbrush);
	// build windings for the faces
	Brush_BuildWindings( newbrush);
	return newbrush;
}
예제 #12
0
/*
=============
Brush_Merge

 Returns a new brush that is created by merging brush1 and brush2.
 May return NULL if brush1 and brush2 do not create a convex brush when merged.
 The input brushes brush1 and brush2 stay intact.

 if onlyshape is true then the merge is allowed based on the shape only
 otherwise the texture references of faces in the same plane have to
 be the same as well.
=============
*/
brush_t *Brush_Merge(brush_t *brush1, brush_t *brush2, int onlyshape)
{
	int i, shared;
	brush_t *newbrush;
	face_t *face1, *face2, *newface, *f;

	// check for bounding box overlapp
	for (i = 0; i < 3; i++)
	{
		if (brush1->mins[i] > brush2->maxs[i] + ON_EPSILON
				|| brush1->maxs[i] < brush2->mins[i] - ON_EPSILON)
		{
			// never merge if the brushes overlap
			return NULL;
		}
	}
	//
	shared = 0;
	// check if the new brush would be convex... flipped planes make a brush non-convex
	for (face1 = brush1->brush_faces; face1; face1 = face1->next)
	{
		// don't check the faces of brush 1 and 2 touching each other
		for (face2 = brush2->brush_faces; face2; face2 = face2->next)
		{
			if (Plane_Equal(&face1->plane, &face2->plane, true))
			{
				shared++;
				// there may only be ONE shared side
				if (shared > 1)
					return NULL;
				break;
			}
		}
		// if this face plane is shared
		if (face2) continue;
		//
		for (face2 = brush2->brush_faces; face2; face2 = face2->next)
		{
			// don't check the faces of brush 1 and 2 touching each other
			for (f = brush1->brush_faces; f; f = f->next)
			{
				if (Plane_Equal(&face2->plane, &f->plane, true)) break;
			}
			if (f)
				continue;
			//
			if (Plane_Equal(&face1->plane, &face2->plane, false))
			{
				//if the texture references should be the same but are not
				if (!onlyshape && stricmp(face1->texdef.name, face2->texdef.name) != 0) return NULL;
				continue;
			}
			//
			if (Winding_PlanesConcave(face1->face_winding, face2->face_winding,
									face1->plane.normal, face2->plane.normal,
									face1->plane.dist, face2->plane.dist))
			{
				return NULL;
			} //end if
		} //end for
	} //end for
	//
	newbrush = Brush_Alloc();
	//
	for (face1 = brush1->brush_faces; face1; face1 = face1->next)
	{
		// don't add the faces of brush 1 and 2 touching each other
		for (face2 = brush2->brush_faces; face2; face2 = face2->next)
		{
			if (Plane_Equal(&face1->plane, &face2->plane, true))
				break;
		}
		if (face2)
			continue;
		// don't add faces with the same plane twice
		for (f = newbrush->brush_faces; f; f = f->next)
		{
			if (Plane_Equal(&face1->plane, &f->plane, false))
				break;
			if (Plane_Equal(&face1->plane, &f->plane, true))
				break;
		}
		if (f)
			continue;
		//
		newface = Face_Alloc();
		newface->texdef = face1->texdef;
		VectorCopy(face1->planepts[0], newface->planepts[0]);
		VectorCopy(face1->planepts[1], newface->planepts[1]);
		VectorCopy(face1->planepts[2], newface->planepts[2]);
		newface->plane = face1->plane;
		newface->next = newbrush->brush_faces;
		newbrush->brush_faces = newface;
	}
	//
	for (face2 = brush2->brush_faces; face2; face2 = face2->next)
	{
		// don't add the faces of brush 1 and 2 touching each other
		for (face1 = brush1->brush_faces; face1; face1 = face1->next)
		{
			if (Plane_Equal(&face2->plane, &face1->plane, true))
				break;
		}
		if (face1)
			continue;
		// don't add faces with the same plane twice
		for (f = newbrush->brush_faces; f; f = f->next)
		{
			if (Plane_Equal(&face2->plane, &f->plane, false))
				break;
			if (Plane_Equal(&face2->plane, &f->plane, true))
				break;
		}
		if (f)
			continue;
		//
		newface = Face_Alloc();
		newface->texdef = face2->texdef;
		VectorCopy(face2->planepts[0], newface->planepts[0]);
		VectorCopy(face2->planepts[1], newface->planepts[1]);
		VectorCopy(face2->planepts[2], newface->planepts[2]);
		newface->plane = face2->plane;
		newface->next = newbrush->brush_faces;
		newbrush->brush_faces = newface;
	}
	// link the new brush to an entity
	Entity_LinkBrush (brush1->owner, newbrush);
	// build windings for the faces
	Brush_BuildWindings(newbrush);
	return newbrush;
}
예제 #13
0
//
// =======================================================================================================================
//    parse a brush in brush primitive format
// =======================================================================================================================
//
void BrushPrimit_Parse(brush_t *b, bool newFormat, const idVec3 origin) {
	face_t	*f;
	int		i, j;
	GetToken(true);
	if (strcmp(token, "{")) {
		Warning("parsing brush primitive");
		return;
	}

	do {
		if (!GetToken(true)) {
			break;
		}

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

		// reading of b->epairs if any
		if (strcmp(token, "(")) {
			ParseEpair(&b->epairs);
		}
		else {	// it's a face
			f = Face_Alloc();
			f->next = NULL;
			if (!b->brush_faces) {
				b->brush_faces = f;
			}
			else {
				face_t	*scan;
				for (scan = b->brush_faces; scan->next; scan = scan->next)
					;
				scan->next = f;
			}

			if (newFormat) {
				// read the three point plane definition
				idPlane plane;
				for (j = 0; j < 4; j++) {
					GetToken(false);
					plane[j] = atof(token);
				}

				f->plane = plane;
				f->originalPlane = plane;
				f->dirty = false;

				//idWinding	*w = Brush_MakeFaceWinding(b, f, true);
				idWinding w;
				w.BaseForPlane( plane );

				for (j = 0; j < 3; j++) {
					f->planepts[j].x = w[j].x + origin.x;
					f->planepts[j].y = w[j].y + origin.y;
					f->planepts[j].z = w[j].z + origin.z;
				}

				GetToken(false);
			}
			else {
				for (i = 0; i < 3; i++) {
					if (i != 0) {
						GetToken(true);
					}

					if (strcmp(token, "(")) {
						Warning("parsing brush");
						return;
					}

					for (j = 0; j < 3; j++) {
						GetToken(false);
						f->planepts[i][j] = atof(token);
					}

					GetToken(false);
					if (strcmp(token, ")")) {
						Warning("parsing brush");
						return;
					}
				}
			}

			// texture coordinates
			GetToken(false);
			if (strcmp(token, "(")) {
				Warning("parsing brush primitive");
				return;
			}

			GetToken(false);
			if (strcmp(token, "(")) {
				Warning("parsing brush primitive");
				return;
			}

			for (j = 0; j < 3; j++) {
				GetToken(false);
				f->brushprimit_texdef.coords[0][j] = atof(token);
			}

			GetToken(false);
			if (strcmp(token, ")")) {
				Warning("parsing brush primitive");
				return;
			}

			GetToken(false);
			if (strcmp(token, "(")) {
				Warning("parsing brush primitive");
				return;
			}

			for (j = 0; j < 3; j++) {
				GetToken(false);
				f->brushprimit_texdef.coords[1][j] = atof(token);
			}

			GetToken(false);
			if (strcmp(token, ")")) {
				Warning("parsing brush primitive");
				return;
			}

			GetToken(false);
			if (strcmp(token, ")")) {
				Warning("parsing brush primitive");
				return;
			}

			// read the texturedef
			GetToken(false);

			// strcpy(f->texdef.name, token);
			if (g_qeglobals.mapVersion < 2.0) {
				f->texdef.SetName(va("textures/%s", token));
			}
			else {
				f->texdef.SetName(token);
			}

			if (TokenAvailable()) {
				GetToken(false);
				GetToken(false);
				GetToken(false);
				f->texdef.value = atoi(token);
			}
		}
	} while (1);
}
예제 #14
0
void WrapFaces( face_t* top, face_t* bottom)
{
	face_t*	tempFace;
	int		i;	
	float	maxX;
	float	maxY;
	int pointFlag;

	tempFace = Face_Alloc();
	//wrap the top face points the other way
	CopyFace(top, tempFace);
	for ( i = 0; i<top->face_winding->numpoints; i++)
	{
		VectorCopy(top->face_winding->points[top->face_winding->numpoints-1-i],tempFace->face_winding->points[i]);
	}
	CopyFace(tempFace,top);
	// top and bottom are now wrapped with normals pointing upward
	// now grab the point in top with most positive x (and y if there are more than one)
	maxX = top->face_winding->points[0][0];
	maxY = top->face_winding->points[0][1];
	pointFlag = 0;

	for ( i = 1; i<top->face_winding->numpoints; i++)
	{
		if ( maxX > top->face_winding->points[i][0] )
		{
			continue;
		}
		else
		{
			if ( maxX == top->face_winding->points[i][0] )
			{
				if (top->face_winding->points[i][1] > maxY)
				{
					maxY = top->face_winding->points[i][1];
					pointFlag = i;
				}
			}
			else
			{
				maxX = top->face_winding->points[i][0];
				maxY = top->face_winding->points[i][1];
				pointFlag = i;
			}
		}
	}
//  now, starting at the point[pointflag] in top, write the sequence starting at [0] in tempFace
	for ( i = 0; i<top->face_winding->numpoints; i++)
	{
		if (pointFlag == top->face_winding->numpoints)
		{
			pointFlag = 0;
		}
		VectorCopy(top->face_winding->points[pointFlag], tempFace->face_winding->points[i]);
		pointFlag++;
	}
	CopyFace(tempFace,top);
//repeat with bottom
	CopyFace(bottom, tempFace);
	maxX = bottom->face_winding->points[0][0];
	maxY = bottom->face_winding->points[0][1];
	pointFlag = 0;

	for ( i = 1; i<bottom->face_winding->numpoints; i++)
	{
		if ( maxX > bottom->face_winding->points[i][0] )
		{
			continue;
		}
		else
		{
			if ( maxX == bottom->face_winding->points[i][0] )
			{
				if (bottom->face_winding->points[i][1] > maxY)
				{
					maxY = bottom->face_winding->points[i][1];
					pointFlag = i;
				}
			}
			else
			{
				maxX = bottom->face_winding->points[i][0];
				maxY = bottom->face_winding->points[i][1];
				pointFlag = i;
			}
		}
	}
//  now, starting at the point[pointflag] in bottom, write the sequence starting at [0] in tempFace
	for ( i = 0; i<bottom->face_winding->numpoints; i++)
	{
		if (pointFlag == bottom->face_winding->numpoints)
		{
			pointFlag = 0;
		}
		VectorCopy(bottom->face_winding->points[pointFlag], tempFace->face_winding->points[i]);
		pointFlag++;
	}
	CopyFace(tempFace,bottom);
	Face_Free(tempFace);
	return;
}
예제 #15
0
void DoTower(void)
{
	brush_t*	brush1 = NULL;
	brush_t*	brush2 = NULL;
	brush_t*	newBrush = NULL;
	brush_t*	tempBrush = NULL;
	face_t*		topFace = NULL;
	face_t*		bottomFace = NULL;
	face_t*		curFace;
	face_t*		faceList;
	int			zFlag = 0;
	int			i = 0; // loop counter

	if (g_qeglobals.d_select_count != 2)
	{
		Sys_Printf ("Error: you must have exactly 2 brushes selected\n");
		Sys_Beep ();
		return;
	}
	brush1 = selected_brushes.next;
	brush2 = selected_brushes.next->next;
//	establish brush1 as the upper brush
	if (brush2->maxs[2] > brush1->mins[2])
	{
		tempBrush = brush1;
		brush1 = brush2;
		brush2 = tempBrush;
	}
//	test to insure brushes do not "overlap" in the Z direction
	if (brush2->maxs[2] > brush1->mins[2])
	{
		Sys_Printf ("Brushes are not separated in the Z direction!");
		Sys_Beep();
		return;
	}
//  find the bottom Z plane (topFace) in 1 and top Z plane in 2 (bottomFace)
	topFace = brush1->brush_faces;
	while (topFace != NULL)
	{
		zFlag = 0;
		for (i = 0; i<3; i++)
		{
			if (abs(topFace->planepts[i][2] - brush1->mins[2]) < TOWER_EPSILON)
			{
				zFlag++;
			}
		}
		if (zFlag == 3)
		{
			break;
		}
		else
		{
			topFace = topFace->next;
		}
	}
	if (topFace == NULL)
	{
		Sys_Printf("Couldn't find flat bottom-face in top brush", 0);
		Sys_Beep();
		return;
	}
	bottomFace = brush2->brush_faces;
	while (bottomFace != NULL)
	{
		zFlag = 0;
		for (i = 0; i<3; i++)
		{
			if (abs(bottomFace->planepts[i][2] - brush2->maxs[2]) < TOWER_EPSILON)
			{
				zFlag++;
			}
		}
		if (zFlag == 3)
		{
			break;
		}
		else
		{
			bottomFace = bottomFace->next;
		}
	}
	if (bottomFace == NULL)
	{
		Sys_Printf ("Couldn't find flat top-face in bottom brush", 0);
		Sys_Beep();
		return;
	}
//	count vertices on top and bottom planes to make sure they are equal
	if (topFace->face_winding->numpoints != bottomFace->face_winding->numpoints)
	{

		Sys_Printf ("Top and Bottom faces don't have same #'s of vertices!", 0);
		Sys_Beep();
		return;
	}
//  put top and bottom faces on brush
//  reverse winding for top and bottom
	faceList = Face_Alloc();
	for ( i = 0; i<3; i++)
	{
		VectorCopy(topFace->planepts[2-i],faceList->planepts[i]);
	}
	curFace = Face_Alloc();
	for ( i = 0; i < 3; i++)
	{
		VectorCopy(bottomFace->planepts[2-i],curFace->planepts[i]);
	}
	curFace->next = faceList;
	faceList = curFace;
	
	curFace = MakePlaneList(topFace, bottomFace);
	if (curFace == NULL)
	{
		Sys_Printf ("Couldn't make planes for tower!", 0);
		Sys_Beep();
		return;
	}
	else
	{
		faceList->next->next = curFace;
	}

	newBrush = (brush_t*)qmalloc(sizeof(brush_t));
	newBrush->brush_faces = faceList;
	Select_Deselect();
	Brush_AddToList (newBrush, &selected_brushes);

	Entity_LinkBrush (world_entity, newBrush);

	Brush_Build(newBrush);
//	UNDO_FinishBrushAdd("&Undo Tower");
	Sys_UpdateWindows(W_ALL);
	return;

}