Example #1
0
/**
 * @brief If two polygons share a common edge and the edges that meet at the
 * common points are both inside the other polygons, merge them
 *
 * @return nullptr if the faces couldn't be merged, or the new face.
 * @note The originals will NOT be freed.
 */
static face_t* TryMerge (face_t* f1, face_t* f2, const vec3_t planenormal)
{
	face_t* newf;
	winding_t* nw;

	if (!f1->w || !f2->w)
		return nullptr;
	if (f1->texinfo != f2->texinfo)
		return nullptr;
	if (f1->planenum != f2->planenum)	/* on front and back sides */
		return nullptr;
	if (f1->contentFlags != f2->contentFlags)
		return nullptr;

	nw = TryMergeWinding(f1->w, f2->w, planenormal);
	if (!nw)
		return nullptr;

	c_merge++;
	newf = NewFaceFromFace(f1);
	newf->w = nw;

	f1->merged = newf;
	f2->merged = newf;

	return newf;
}
Example #2
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_TryMergeFaces( tmp_face_t *face1, tmp_face_t *face2 ) {
	winding_t *neww;

#ifdef DEBUG
	if ( !face1->winding ) {
		Error( "face1 %d without winding", face1->num );
	}
	if ( !face2->winding ) {
		Error( "face2 %d without winding", face2->num );
	}
#endif //DEBUG
	   //
	if ( face1->faceflags != face2->faceflags ) {
		return false;
	}
	//NOTE: if the front or back area is zero this doesn't mean there's
	//a real area. It means there's solid at that side of the face
	//if both faces have the same front area
	if ( face1->frontarea == face2->frontarea ) {
		//if both faces have the same back area
		if ( face1->backarea == face2->backarea ) {
			//if the faces are in the same plane
			if ( face1->planenum == face2->planenum ) {
				//if they have both a front and a back area (no solid on either side)
				if ( face1->frontarea && face1->backarea ) {
					neww = MergeWindings( face1->winding, face2->winding,
										  mapplanes[face1->planenum].normal );
				} //end if
				else
				{
					//this function is to be found in l_poly.c
					neww = TryMergeWinding( face1->winding, face2->winding,
											mapplanes[face1->planenum].normal );
				} //end else
				if ( neww ) {
					FreeWinding( face1->winding );
					face1->winding = neww;
					if ( face2->frontarea ) {
						AAS_RemoveFaceFromArea( face2, face2->frontarea );
					}
					if ( face2->backarea ) {
						AAS_RemoveFaceFromArea( face2, face2->backarea );
					}
					AAS_FreeTmpFace( face2 );
					return true;
				} //end if
			} //end if
			else if ( ( face1->planenum & ~1 ) == ( face2->planenum & ~1 ) ) {
				Log_Write( "face %d and %d, same front and back area but flipped planes\r\n",
						   face1->num, face2->num );
			} //end if
		} //end if
	} //end if
	return false;
} //end of the function AAS_TryMergeFaces
Example #3
0
/*
   ============
   MergeLeafPortals
   ============
 */
void MergeLeafPortals( void ){
	int i, j, k, nummerges, hintsmerged;
	leaf_t *leaf;
	vportal_t *p1, *p2;
	fixedWinding_t *w;

	nummerges = 0;
	hintsmerged = 0;
	for ( i = 0; i < portalclusters; i++ )
	{
		leaf = &leafs[i];
		if ( leaf->merged >= 0 ) {
			continue;
		}
		for ( j = 0; j < leaf->numportals; j++ )
		{
			p1 = leaf->portals[j];
			if ( p1->removed ) {
				continue;
			}
			for ( k = j + 1; k < leaf->numportals; k++ )
			{
				p2 = leaf->portals[k];
				if ( p2->removed ) {
					continue;
				}
				if ( p1->leaf == p2->leaf ) {
					w = TryMergeWinding( p1->winding, p2->winding, p1->plane.normal );
					if ( w ) {
						free( p1->winding );    //% FreeWinding(p1->winding);
						p1->winding = w;
						if ( p1->hint && p2->hint ) {
							hintsmerged++;
						}
						p1->hint |= p2->hint;
						SetPortalSphere( p1 );
						p2->removed = qtrue;
						nummerges++;
						i--;
						break;
					}
				}
			}
			if ( k < leaf->numportals ) {
				break;
			}
		}
	}
	Sys_Printf( "%6d portals merged\n", nummerges );
	Sys_Printf( "%6d hint portals merged\n", hintsmerged );
}