コード例 #1
0
ファイル: solidbsp.c プロジェクト: DeadlyGamer/cs16nd
/*
==================
CopyFacesToNode

Do a final merge attempt, then subdivide the faces
to surface cache size if needed.

These are final faces that will be drawable in the game.
Copies of these faces are further chopped up into the leafs,
but they will reference these originals.
==================
*/
void CopyFacesToNode (node_t *node, surface_t *surf)
{
	face_t	**prevptr, *f, *newf;

	// merge as much as possible
	MergePlaneFaces (surf);

	// subdivide large faces
	prevptr = &surf->faces;
	while (1)
	{
		f = *prevptr;
		if (!f)
			break;
		SubdivideFace (f, prevptr);
		f = *prevptr;
		prevptr = &f->next;
	}

	// copy the faces to the node, and consider them the originals
	node->surfaces = NULL;
	node->faces = NULL;
	for (f=surf->faces ; f ; f=f->next)
	{
		if (f->contents != CONTENTS_SOLID)
		{
			newf = AllocFace ();
			*newf = *f;
			f->original = newf;
			newf->next = node->faces;
			node->faces = newf;
			c_nodefaces++;
		}
	}
}
コード例 #2
0
/*
==================
CopyFacesToOutside
==================
*/
static void CopyFacesToOutside (brush_t *b)
{
	face_t		*f, *newf;

	outside = NULL;

	for (f = b->faces ; f ; f = f->next)
	{
		brushfaces++;
#if 0
		{
			int		i;

			for (i = 0 ; i < f->numpoints ; i++)
				printf ("(%f,%f,%f) ",f->pts[i][0], f->pts[i][1], f->pts[i][2]);
			printf ("\n");
		}
#endif
		newf = AllocFace ();
		*newf = *f;
		newf->next = outside;
		newf->contents[0] = CONTENTS_EMPTY;
		newf->contents[1] = b->contents;
		outside = newf;
	}
}
コード例 #3
0
ファイル: faces.c プロジェクト: jayschwa/quake2world
/*
 * @brief
 */
static face_t *NewFaceFromFace(const face_t *f) {
	face_t *newf;

	newf = AllocFace();
	*newf = *f;
	newf->merged = NULL;
	newf->split[0] = newf->split[1] = NULL;
	newf->w = NULL;
	return newf;
}
コード例 #4
0
/*
==================
NewFaceFromFace

Duplicates the non point information of a face, used by SplitFace and
MergeFace.
==================
*/
face_t *NewFaceFromFace (face_t *in)
{
	face_t	*newf;

	newf = AllocFace ();

	newf->planenum = in->planenum;
	newf->texturenum = in->texturenum;
	newf->planeside = in->planeside;
	newf->original = in->original;
	newf->contents[0] = in->contents[0];
	newf->contents[1] = in->contents[1];
	newf->Light = in->Light;

	return newf;
}
コード例 #5
0
ファイル: faces.cpp プロジェクト: ArkyRomania/ufoai
static face_t* FaceFromPortal (portal_t* p, bool pside)
{
	face_t* f;
	side_t* side = p->side;

	/* portal does not bridge different visible contents */
	if (!side)
		return nullptr;

	/* nodraw/caulk faces */
	if (side->surfaceFlags & SURF_NODRAW)
		return nullptr;

	f = AllocFace();

	f->texinfo = side->texinfo;
	f->planenum = (side->planenum & ~1) | pside;
	f->portal = p;

	if ((p->nodes[pside]->contentFlags & CONTENTS_WINDOW)
	 && VisibleContents(p->nodes[!pside]->contentFlags ^ p->nodes[pside]->contentFlags) == CONTENTS_WINDOW)
		return nullptr;	/* don't show insides of windows */

	/* do back-clipping */
	if (!config.nobackclip && mapplanes[f->planenum].normal[2] < -0.9) {
		/* this face is not visible from birds view - optimize away
		 * but only if it's not light emitting surface */
		const entity_t* e = &entities[side->brush->entitynum];
		if (!Q_streq(ValueForKey(e, "classname"), "func_rotating")) {
			if (!(curTile->texinfo[f->texinfo].surfaceFlags & SURF_LIGHT)) {
				/* e.g. water surfaces are removed if we set the surfaceFlags
				 * to SURF_NODRAW for this side */
				/*side->surfaceFlags |= SURF_NODRAW;*/
				return nullptr;
			}
		}
	}

	if (pside) {
		f->w = ReverseWinding(p->winding);
		f->contentFlags = p->nodes[1]->contentFlags;
	} else {
		f->w = CopyWinding(p->winding);
		f->contentFlags = p->nodes[0]->contentFlags;
	}
	return f;
}
コード例 #6
0
ファイル: detail.cpp プロジェクト: 0xFEEDC0DE64/UltraGame
//-----------------------------------------------------------------------------
// Purpose: Given an original side and chopped winding, make a face_t 
// Input  : *side - side of the original brush
//			*winding - winding for this face (portion of the side)
// Output : face_t
//-----------------------------------------------------------------------------
face_t *MakeBrushFace( side_t *originalSide, winding_t *winding )
{
	face_t *f = AllocFace();
	f->merged = NULL;
	f->split[0] = f->split[1] = NULL;
	f->w = CopyWinding( winding );
	f->originalface = originalSide;
	//
	// save material info
	//
	f->texinfo = originalSide->texinfo;
	f->dispinfo = -1;

	// save plane info
	f->planenum = originalSide->planenum;
	f->contents = originalSide->contents;

	return f;
}
コード例 #7
0
ファイル: csg4.c プロジェクト: dommul/super8
/*
==================
CopyFacesToOutside
==================
*/
static void CopyFacesToOutside( const brush_t *b )
{
	face_t		*f, *newf;

	outside = NULL;
	for( f = b->faces; f; f = f->next ) {
		if( !f->winding )
			continue;

		numcsgbrushfaces++;
		newf = AllocFace ();
		newf->texturenum = f->texturenum;
		newf->planenum = f->planenum;
		newf->planeside = f->planeside;
		newf->original = f->original;
		newf->winding = CopyWinding( f->winding );
		newf->next = outside;
		newf->contents[0] = CONTENTS_EMPTY;
		newf->contents[1] = b->contents;
		outside = newf;
	}
}
コード例 #8
0
ファイル: BRUSH.C プロジェクト: ChunHungLiu/Quake-Tools
void CreateBrushFaces (void)
{
	int				i,j, k;
	vec_t			r;
	face_t			*f;
	winding_t		*w;
	plane_t			plane;
	mface_t			*mf;
	
	brush_mins[0] = brush_mins[1] = brush_mins[2] = 99999;
	brush_maxs[0] = brush_maxs[1] = brush_maxs[2] = -99999;

	brush_faces = NULL;
	
	for (i=0 ; i<numbrushfaces ; i++)
	{
		mf = &faces[i];
		
		w = BaseWindingForPlane (&mf->plane);

		for (j=0 ; j<numbrushfaces && w ; j++)
		{
			if (j == i)
				continue;
		// flip the plane, because we want to keep the back side
			VectorSubtract (vec3_origin,faces[j].plane.normal, plane.normal);
			plane.dist = -faces[j].plane.dist;
			
			w = ClipWinding (w, &plane, false);
		}
		
		if (!w)
			continue;	// overcontrained plane
			
	// this face is a keeper
		f = AllocFace ();
		f->numpoints = w->numpoints;
		if (f->numpoints > MAXEDGES)
			Error ("f->numpoints > MAXEDGES");
	
		for (j=0 ; j<w->numpoints ; j++)
		{
			for (k=0 ; k<3 ; k++)
			{
				r = Q_rint (w->points[j][k]);
				if ( fabs(w->points[j][k] - r) < ZERO_EPSILON)
					f->pts[j][k] = r;
				else
					f->pts[j][k] = w->points[j][k];
					
				if (f->pts[j][k] < brush_mins[k])
					brush_mins[k] = f->pts[j][k];
				if (f->pts[j][k] > brush_maxs[k])
					brush_maxs[k] = f->pts[j][k];				
			}
			
		}
		FreeWinding (w);
		f->texturenum = mf->texinfo;
		f->planenum = FindPlane (&mf->plane, &f->planeside);
		f->next = brush_faces;
		brush_faces = f;
		CheckFace (f);
	}	
}
コード例 #9
0
ファイル: brush.c プロジェクト: nekonomicon/QuakeRemakeDevkit
/*
=================
CreateBrushFaces
=================
*/
void CreateBrushFaces (void)
{
	int				i,j, k;
	vec_t			r;
	face_t			*f, *next;
	winding_t		*w;
	plane_t			clipplane, faceplane;
	mface_t			*mf;
	vec3_t			offset, point;

	offset[0] = offset[1] = offset[2] = 0;
	ClearBounds( brush_mins, brush_maxs );

	brush_faces = NULL;

	if (!strncmp(ValueForKey(CurrentEntity, "classname"), "rotate_", 7))
	{
		entity_t	*FoundEntity;
		char 		*searchstring;
		char		text[20];

		searchstring = ValueForKey (CurrentEntity, "target");
		FoundEntity = FindTargetEntity(searchstring);
		if (FoundEntity)
			GetVectorForKey(FoundEntity, "origin", offset);

		sprintf(text, "%g %g %g", offset[0], offset[1], offset[2]);
		SetKeyValue(CurrentEntity, "origin", text);
	}

	GetVectorForKey(CurrentEntity, "origin", offset);
	//printf("%i brushfaces at offset %f %f %f\n", numbrushfaces, offset[0], offset[1], offset[2]);

	for (i = 0;i < numbrushfaces;i++)
	{
		mf = &faces[i];

		//printf("plane %f %f %f %f\n", mf->plane.normal[0], mf->plane.normal[1], mf->plane.normal[2], mf->plane.dist);
		faceplane = mf->plane;
		w = BaseWindingForPlane (&faceplane);

		//VectorNegate( faceplane.normal, point );
		for (j = 0;j < numbrushfaces && w;j++)
		{
			clipplane = faces[j].plane;
			if( j == i/* || VectorCompare( clipplane.normal, point )*/ )
				continue;

			// flip the plane, because we want to keep the back side
			VectorNegate(clipplane.normal, clipplane.normal);
			clipplane.dist *= -1;

			w = ClipWindingEpsilon (w, &clipplane, ON_EPSILON, true);
		}

		if (!w)
		{
			//printf("----- skipped plane -----\n");
			continue;	// overcontrained plane
		}

		// this face is a keeper
		f = AllocFace ();
		f->winding = w;

		for (j = 0;j < w->numpoints;j++)
		{
			for (k = 0;k < 3;k++)
			{
				point[k] = w->points[j][k] - offset[k];
				r = Q_rint( point[k] );
				if ( fabs( point[k] - r ) < ZERO_EPSILON)
					w->points[j][k] = r;
				else
					w->points[j][k] = point[k];

				// check for incomplete brushes
				if( w->points[j][k] >= BOGUS_RANGE || w->points[j][k] <= -BOGUS_RANGE )
					break;
			}

			// remove this brush
			if (k < 3)
			{
				FreeFace (f);
				for (f = brush_faces; f; f = next)
				{
					next = f->next;
					FreeFace (f);
				}
				brush_faces = NULL;
				//printf("----- skipped brush -----\n");
				return;
			}

			AddPointToBounds( w->points[j], brush_mins, brush_maxs );
		}

		CheckWinding( w );

		faceplane.dist -= DotProduct(faceplane.normal, offset);
		f->texturenum = mf->texinfo;
		f->planenum = FindPlane (&faceplane, &f->planeside);
		f->next = brush_faces;
		brush_faces = f;
	}

	// Rotatable objects have to have a bounding box big enough
	// to account for all its rotations.
	if (DotProduct(offset, offset))
	{
		vec_t delta;

		delta = RadiusFromBounds( brush_mins, brush_maxs );

		for (k = 0;k < 3;k++)
		{
			brush_mins[k] = -delta;
			brush_maxs[k] = delta;
		}
	}

	//printf("%i : %f %f %f : %f %f %f\n", numbrushfaces, brush_mins[0], brush_mins[1], brush_mins[2], brush_maxs[0], brush_maxs[1], brush_maxs[2]);
}
コード例 #10
0
ファイル: brush.c プロジェクト: kellyrm/Q1
void CreateBrushFaces (void)
{
	int	  i, j, k;
	vec3_t    offset, point;
	vec_t	  r, max, min;
	face_t	  *f;
	winding_t *w;
	plane_t	  plane;
	mface_t	  *mf;
	qboolean  IsRotate;

	offset[0] = offset[1] = offset[2] = 0;
	min = brush_mins[0] = brush_mins[1] = brush_mins[2] = 99999;
	max = brush_maxs[0] = brush_maxs[1] = brush_maxs[2] = -99999;

	// Hipnotic rotation
	IsRotate = !strncmp(ValueForKey(CurrEnt, "classname"), "rotate_", 7);

	if (IsRotate)
		FixRotateOrigin(CurrEnt, offset);

	brush_faces = NULL;

	for (i=0 ; i<numbrushfaces ; i++)
	{
		mf = &faces[i];

		w = BaseWindingForPlane (&mf->plane);

		for (j=0 ; j<numbrushfaces && w ; j++)
		{
			if (j == i)
				continue;
		// flip the plane, because we want to keep the back side
			VectorSubtract (vec3_origin,faces[j].plane.normal, plane.normal);
			plane.dist = -faces[j].plane.dist;

			w = ClipWinding (w, &plane, false);
		}

		if (!w)
			continue;	// overcontrained plane

	// this face is a keeper
		f = AllocFace ();
		ResizeFace (f, w->numpoints);
		if (f->numpoints > MAXEDGES)
			Message (MSGERR, "f->numpoints (%d) > MAXEDGES (%d)", f->numpoints, MAXEDGES);

		for (j=0 ; j<w->numpoints ; j++)
		{
			for (k=0 ; k<3 ; k++)
			{
				point[k] = w->points[j][k] - offset[k];
				r = Q_rint(point[k]);
				if (fabs(point[k] - r) < ZERO_EPSILON)
					f->pts[j][k] = r;
				else
					f->pts[j][k] = point[k];

				if (f->pts[j][k] < brush_mins[k])
					brush_mins[k] = f->pts[j][k];
				if (f->pts[j][k] > brush_maxs[k])
					brush_maxs[k] = f->pts[j][k];

				if (IsRotate)
				{
					if (f->pts[j][k] < min)
						min = f->pts[j][k];
					if (f->pts[j][k] > max)
						max = f->pts[j][k];
				}
			}
		}

		if (!IsRotate)
			plane = mf->plane;
		else
		{
			VectorCopy(mf->plane.normal, plane.normal);
			VectorScale(mf->plane.normal, mf->plane.dist, point);
			VectorSubtract(point, offset, point);
			plane.dist = DotProduct(plane.normal, point);
		}

		FreeWinding (w);
		f->texturenum = hullnum ? 0 : mf->texinfo;
		f->planenum = FindPlane (&plane, &f->planeside);
		f->next = brush_faces;
		brush_faces = f;
		CheckFace (f);
	}

	// Rotatable objects must have a bounding box big enough to
	// account for all its rotations
	if (IsRotate)
	{
		vec_t delta;

		delta = fabs(max);
		if (fabs(min) > delta)
			delta = fabs(min);

		for (k=0; k<3; k++)
		{
			brush_mins[k] = -delta;
			brush_maxs[k] = delta;
		}
	}
}