00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "qbsp.h"
00024 #include "../botlib/aasfile.h"
00025 #include "aas_create.h"
00026
00027
00028
00029
00030
00031
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
00044
00045
00046 if (face1->frontarea == face2->frontarea)
00047 {
00048
00049 if (face1->backarea == face2->backarea)
00050 {
00051
00052 if (face1->planenum == face2->planenum)
00053 {
00054
00055 if (face1->frontarea && face1->backarea)
00056 {
00057 neww = MergeWindings(face1->winding, face2->winding,
00058 mapplanes[face1->planenum].normal);
00059 }
00060 else
00061 {
00062
00063 neww = TryMergeWinding(face1->winding, face2->winding,
00064 mapplanes[face1->planenum].normal);
00065 }
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 }
00075 }
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 }
00081 }
00082 }
00083 return false;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
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
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
00153 if (AAS_TryMergeFaces(face1, face2))
00154 {
00155
00156 restart = true;
00157 num_facemerges++;
00158 qprintf("\r%6d", num_facemerges);
00159 AAS_CheckArea(tmparea);
00160 break;
00161 }
00162 }
00163 if (restart)
00164 {
00165 tmparea = lasttmparea;
00166 break;
00167 }
00168 }
00169 lasttmparea = tmparea;
00170 }
00171 qprintf("\n");
00172 Log_Write("%6d face merges\r\n", num_facemerges);
00173 }
00174
00175
00176
00177
00178
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 }
00208 }
00209 }
00210
00211
00212
00213
00214
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 }
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 }
00241 }
00242 return merge;
00243 }
00244
00245
00246
00247
00248
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
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 }
00278 }
00279 }
00280 qprintf("\n");
00281 Log_Write("%6d plane face merges\r\n", num_facemerges);
00282 }