/** * @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; }
//=========================================================================== // // 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
/* ============ 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 ); }