Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

aas_facemerging.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 #include "qbsp.h"
00024 #include "../botlib/aasfile.h"
00025 #include "aas_create.h"
00026 
00027 //===========================================================================
00028 //
00029 // Parameter:               -
00030 // Returns:                 -
00031 // Changes Globals:     -
00032 //===========================================================================
00033 int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
00034 {
00035     winding_t *neww;
00036 
00037 #ifdef DEBUG
00038     if (!face1->winding) Error("face1 %d without winding", face1->num);
00039     if (!face2->winding) Error("face2 %d without winding", face2->num);
00040 #endif //DEBUG
00041     //
00042     if (face1->faceflags != face2->faceflags) return false;
00043     //NOTE: if the front or back area is zero this doesn't mean there's
00044     //a real area. It means there's solid at that side of the face
00045     //if both faces have the same front area
00046     if (face1->frontarea == face2->frontarea)
00047     {
00048         //if both faces have the same back area
00049         if (face1->backarea == face2->backarea)
00050         {
00051             //if the faces are in the same plane
00052             if (face1->planenum == face2->planenum)
00053             {
00054                 //if they have both a front and a back area (no solid on either side)
00055                 if (face1->frontarea && face1->backarea)
00056                 {
00057                     neww = MergeWindings(face1->winding, face2->winding,
00058                                 mapplanes[face1->planenum].normal);
00059                 } //end if
00060                 else
00061                 {
00062                     //this function is to be found in l_poly.c
00063                     neww = TryMergeWinding(face1->winding, face2->winding,
00064                                     mapplanes[face1->planenum].normal);
00065                 } //end else
00066                 if (neww)
00067                 {
00068                     FreeWinding(face1->winding);
00069                     face1->winding = neww;
00070                     if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
00071                     if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
00072                     AAS_FreeTmpFace(face2);
00073                     return true;
00074                 } //end if
00075             } //end if
00076             else if ((face1->planenum & ~1) == (face2->planenum & ~1))
00077             {
00078                 Log_Write("face %d and %d, same front and back area but flipped planes\r\n",
00079                             face1->num, face2->num);
00080             } //end if
00081         } //end if
00082     } //end if
00083     return false;
00084 } //end of the function AAS_TryMergeFaces
00085 /*
00086 int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
00087 {
00088     winding_t *neww;
00089 
00090 #ifdef DEBUG
00091     if (!face1->winding) Error("face1 %d without winding", face1->num);
00092     if (!face2->winding) Error("face2 %d without winding", face2->num);
00093 #endif //DEBUG
00094     //if the faces are in the same plane
00095     if ((face1->planenum & ~1) != (face2->planenum & ~1)) return false;
00096 //  if (face1->planenum != face2->planenum) return false;
00097     //NOTE: if the front or back area is zero this doesn't mean there's
00098     //a real area. It means there's solid at that side of the face
00099     //if both faces have the same front area
00100     if (face1->frontarea != face2->frontarea ||
00101         face1->backarea != face2->backarea)
00102     {
00103         if (!face1->frontarea || !face1->backarea ||
00104                 !face2->frontarea || !face2->backarea) return false;
00105         else if (face1->frontarea != face2->backarea ||
00106                     face1->backarea != face2->frontarea) return false;
00107 //      return false;
00108     } //end if
00109     //this function is to be found in l_poly.c
00110     neww = TryMergeWinding(face1->winding, face2->winding,
00111                     mapplanes[face1->planenum].normal);
00112     if (!neww) return false;
00113     //
00114     FreeWinding(face1->winding);
00115     face1->winding = neww;
00116     //remove face2
00117     if (face2->frontarea)
00118         AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->frontarea]);
00119     if (face2->backarea)
00120         AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->backarea]);
00121     return true;
00122 } //end of the function AAS_TryMergeFaces*/
00123 //===========================================================================
00124 //
00125 // Parameter:               -
00126 // Returns:                 -
00127 // Changes Globals:     -
00128 //===========================================================================
00129 void AAS_MergeAreaFaces(void)
00130 {
00131     int num_facemerges = 0;
00132     int side1, side2, restart;
00133     tmp_area_t *tmparea, *lasttmparea;
00134     tmp_face_t *face1, *face2;
00135 
00136     Log_Write("AAS_MergeAreaFaces\r\n");
00137     qprintf("%6d face merges", num_facemerges);
00138     //NOTE: first convex area is a dummy
00139     lasttmparea = tmpaasworld.areas;
00140     for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
00141     {
00142         restart = false;
00143         //
00144         if (tmparea->invalid) continue;
00145         //
00146         for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
00147         {
00148             side1 = face1->frontarea != tmparea;
00149             for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
00150             {
00151                 side2 = face2->frontarea != tmparea;
00152                 //if succesfully merged
00153                 if (AAS_TryMergeFaces(face1, face2))
00154                 {
00155                     //start over again after merging two faces
00156                     restart = true;
00157                     num_facemerges++;
00158                     qprintf("\r%6d", num_facemerges);
00159                     AAS_CheckArea(tmparea);
00160                     break;
00161                 } //end if
00162             } //end for
00163             if (restart)
00164             {
00165                 tmparea = lasttmparea;
00166                 break;
00167             } //end if
00168         } //end for
00169         lasttmparea = tmparea;
00170     } //end for
00171     qprintf("\n");
00172     Log_Write("%6d face merges\r\n", num_facemerges);
00173 } //end of the function AAS_MergeAreaFaces
00174 //===========================================================================
00175 //
00176 // Parameter:               -
00177 // Returns:                 -
00178 // Changes Globals:     -
00179 //===========================================================================
00180 void AAS_MergePlaneFaces(tmp_area_t *tmparea, int planenum)
00181 {
00182     tmp_face_t *face1, *face2, *nextface2;
00183     winding_t *neww;
00184     int side1, side2;
00185 
00186     for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
00187     {
00188         side1 = face1->frontarea != tmparea;
00189         if (face1->planenum != planenum) continue;
00190         //
00191         for (face2 = face1->next[side1]; face2; face2 = nextface2)
00192         {
00193             side2 = face2->frontarea != tmparea;
00194             nextface2 = face2->next[side2];
00195             //
00196             if ((face2->planenum & ~1) != (planenum & ~1)) continue;
00197             //
00198             neww = MergeWindings(face1->winding, face2->winding,
00199                                 mapplanes[face1->planenum].normal);
00200             FreeWinding(face1->winding);
00201             face1->winding = neww;
00202             if (face2->frontarea) AAS_RemoveFaceFromArea(face2, face2->frontarea);
00203             if (face2->backarea) AAS_RemoveFaceFromArea(face2, face2->backarea);
00204             AAS_FreeTmpFace(face2);
00205             //
00206             nextface2 = face1->next[side1];
00207         } //end for
00208     } //end for
00209 } //end of the function AAS_MergePlaneFaces
00210 //===========================================================================
00211 //
00212 // Parameter:               -
00213 // Returns:                 -
00214 // Changes Globals:     -
00215 //===========================================================================
00216 int AAS_CanMergePlaneFaces(tmp_area_t *tmparea, int planenum)
00217 {
00218     tmp_area_t *frontarea, *backarea;
00219     tmp_face_t *face1;
00220     int side1, merge, faceflags;
00221 
00222     frontarea = backarea = NULL;
00223     merge = false;
00224     for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
00225     {
00226         side1 = face1->frontarea != tmparea;
00227         if ((face1->planenum & ~1) != (planenum & ~1)) continue;
00228         if (!frontarea && !backarea)
00229         {
00230             frontarea = face1->frontarea;
00231             backarea = face1->backarea;
00232             faceflags = face1->faceflags;
00233         } //end if
00234         else
00235         {
00236             if (frontarea != face1->frontarea) return false;
00237             if (backarea != face1->backarea) return false;
00238             if (faceflags != face1->faceflags) return false;
00239             merge = true;
00240         } //end else
00241     } //end for
00242     return merge;
00243 } //end of the function AAS_CanMergePlaneFaces
00244 //===========================================================================
00245 //
00246 // Parameter:               -
00247 // Returns:                 -
00248 // Changes Globals:     -
00249 //===========================================================================
00250 void AAS_MergeAreaPlaneFaces(void)
00251 {
00252     int num_facemerges = 0;
00253     int side1;
00254     tmp_area_t *tmparea, *nexttmparea;
00255     tmp_face_t *face1;
00256 
00257     Log_Write("AAS_MergePlaneFaces\r\n");
00258     qprintf("%6d plane face merges", num_facemerges);
00259     //NOTE: first convex area is a dummy
00260     for (tmparea = tmpaasworld.areas; tmparea; tmparea = nexttmparea)
00261     {
00262         nexttmparea = tmparea->l_next;
00263         //
00264         if (tmparea->invalid) continue;
00265         //
00266         for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
00267         {
00268             side1 = face1->frontarea != tmparea;
00269             //
00270             if (AAS_CanMergePlaneFaces(tmparea, face1->planenum))
00271             {
00272                 AAS_MergePlaneFaces(tmparea, face1->planenum);
00273                 nexttmparea = tmparea;
00274                 num_facemerges++;
00275                 qprintf("\r%6d", num_facemerges);
00276                 break;
00277             } //end if
00278         } //end for
00279     } //end for
00280     qprintf("\n");
00281     Log_Write("%6d plane face merges\r\n", num_facemerges);
00282 } //end of the function AAS_MergeAreaPlaneFaces

Generated on Thu Aug 25 12:37:14 2005 for Quake III Arena by  doxygen 1.3.9.1