示例#1
0
/**
 * @brief Chop up faces that are larger than we want in the surface cache
 */
static void SubdivideFace (node_t* node, face_t* f)
{
	if (f->merged)
		return;

	/* special (non-surface cached) faces don't need subdivision */
	const dBspTexinfo_t* tex = &curTile->texinfo[f->texinfo];
	if (tex->surfaceFlags & SURF_WARP)
		return;

	for (int axis = 0; axis < 2; axis++) {
		while (1) {
			const winding_t* w = f->w;
			winding_t* frontw, *backw;
			float mins = 999999;
			float maxs = -999999;
			vec3_t temp;
			vec_t v;

			VectorCopy(tex->vecs[axis], temp);
			for (int i = 0; i < w->numpoints; i++) {
				v = DotProduct(w->p[i], temp);
				if (v < mins)
					mins = v;
				if (v > maxs)
					maxs = v;
			}

			/* no bsp subdivide for this winding? */
			if (maxs - mins <= config.subdivideSize)
				break;

			/* split it */
			c_subdivide++;

			v = VectorNormalize(temp);

			vec_t dist = (mins + config.subdivideSize - 16) / v;

			ClipWindingEpsilon(w, temp, dist, ON_EPSILON, &frontw, &backw);
			if (!frontw || !backw)
				Sys_Error("SubdivideFace: didn't split the polygon (texture: '%s')",
					tex->texture);

			f->split[0] = NewFaceFromFace(f);
			f->split[0]->w = frontw;
			f->split[0]->next = node->faces;
			node->faces = f->split[0];

			f->split[1] = NewFaceFromFace(f);
			f->split[1]->w = backw;
			f->split[1]->next = node->faces;
			node->faces = f->split[1];

			SubdivideFace(node, f->split[0]);
			SubdivideFace(node, f->split[1]);
			return;
		}
	}
}
示例#2
0
/*
==================
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++;
		}
	}
}
示例#3
0
static void SubdivideNodeFaces (node_t* node)
{
	face_t* f;

	for (f = node->faces; f; f = f->next)
		SubdivideFace(node, f);
}
// actually, this has no users.
void SubdivideFaces (surface_t *surfhead)
{
	surface_t	*surf;
	face_t		*f , **prevptr;

	qprintf ("--- SubdivideFaces ---\n");

	subdivides = 0;

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

	qprintf ("%i faces added by subdivision\n", subdivides);
}
示例#5
0
/*
==================
LinkNodeFaces

Returns a duplicated list of all faces on surface
==================
*/
static face_t *
LinkNodeFaces(surface_t *surface)
{
    face_t *f, *newf, **prevptr;
    face_t *list = NULL;

    // subdivide large faces
    prevptr = &surface->faces;
    f = *prevptr;
    while (f) {
	SubdivideFace(f, prevptr);
	prevptr = &(*prevptr)->next;
	f = *prevptr;
    }

    // copy
    for (f = surface->faces; f; f = f->next) {
	nodefaces++;
	newf = AllocMem(FACE, 1, true);
	*newf = *f;
	f->original = newf;
	newf->next = list;
	list = newf;
    }

    return list;
}
示例#6
0
void LS_Surface::Subdivide()
{
	subdivisionLevel++;
	// Linear subdivision of edges
	LS_EdgeList::iterator edge_itr = edges.begin();
	int numEdges = edges.size();
	int numVertices = vertices.size();
	//TimeHandle t = TimeBegin();
	for( int i = 0; i < numEdges; i++, edge_itr++ )
	{
		// Only subdivide old edges (ones not attached to a new vertex)
		if ( (*edge_itr)->vertices[0]->creationLevel != subdivisionLevel
					&& (*edge_itr)->vertices[1]->creationLevel != subdivisionLevel )
			SubdivideEdge( *edge_itr );
	}
	//printf("Subdivide Edge Time = %lf\n", TimeSlice(t));
	// Create the new faces / Connect the new vertices
	LS_FaceList::iterator face_itr = faces.begin();
	int orinumfaces = faces.size();
	//t = TimeBegin();
	for( int i = 0; i < orinumfaces; i++, face_itr++ )
	{
		// Connect the new vertices into faces
		SubdivideFace( *face_itr );
	}
	//printf("Subdivide Face Time = %lf\n", TimeSlice(t));
	// Reposition new vertices
	LS_VertexList::iterator vertex_itr = vertices.begin();
	//t = TimeBegin();
	for( int i = 0; i < vertices.size(); i++, vertex_itr++ )
	{
		RepositionVertex( *vertex_itr );
	}
	//printf("Reposition Time = %lf\n", TimeSlice(t));
	vertex_itr = vertices.begin();
	//t = TimeBegin();
	for( int i = 0; i < vertices.size(); i++, vertex_itr++ )
		(*vertex_itr)->pos = (*vertex_itr)->newPos;
	//printf("Other Time = %lf\n", TimeSlice(t));
	//UpdateNormals();
}