#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
#include "aas_store.h"
Include dependency graph for aas_areamerging.c:

Go to the source code of this file.
Defines | |
| #define | CONVEX_EPSILON 0.3 |
Functions | |
| int | AAS_GroundArea (tmp_area_t *tmparea) |
| void | AAS_MergeAreas (void) |
| tmp_node_t * | AAS_RefreshMergedTree_r (tmp_node_t *tmpnode) |
| int | AAS_TryMergeFaceAreas (tmp_face_t *seperatingface) |
| int | NonConvex (tmp_face_t *face1, tmp_face_t *face2, int side1, int side2) |
|
|
Definition at line 28 of file aas_areamerging.c. |
|
|
Definition at line 312 of file aas_areamerging.c. References tmp_face_s::faceflags, tmp_face_s::frontarea, tmp_face_s::next, tmp_area_t, tmp_face_t, and tmp_area_s::tmpfaces. Referenced by AAS_MergeAreas(). 00313 {
00314 tmp_face_t *face;
00315 int side;
00316
00317 for (face = tmparea->tmpfaces; face; face = face->next[side])
00318 {
00319 side = (face->frontarea != tmparea);
00320 if (face->faceflags & FACE_GROUND) return true;
00321 } //end for
00322 return false;
00323 } //end of the function AAS_GroundArea
|
|
|
Definition at line 325 of file aas_areamerging.c. References AAS_GroundArea(), AAS_RefreshMergedTree_r(), AAS_TryMergeFaceAreas(), tmp_aas_s::areas, tmp_face_s::backarea, tmp_face_s::frontarea, tmp_area_s::invalid, tmp_area_s::l_next, Log_Write(), tmp_face_s::next, tmp_aas_s::nodes, qprintf(), tmp_area_t, tmp_face_t, tmpaasworld, and tmp_area_s::tmpfaces. Referenced by AAS_Create(). 00326 {
00327 int side, nummerges, merges, groundfirst;
00328 tmp_area_t *tmparea, *othertmparea;
00329 tmp_face_t *face;
00330
00331 nummerges = 0;
00332 Log_Write("AAS_MergeAreas\r\n");
00333 qprintf("%6d areas merged", 1);
00334 //
00335 groundfirst = true;
00336 //for (i = 0; i < 4 || merges; i++)
00337 while(1)
00338 {
00339 //if (i < 2) groundfirst = true;
00340 //else groundfirst = false;
00341 //
00342 merges = 0;
00343 //first merge grounded areas only
00344 for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
00345 {
00346 //if the area is invalid
00347 if (tmparea->invalid)
00348 {
00349 continue;
00350 } //end if
00351 //
00352 if (groundfirst)
00353 {
00354 if (!AAS_GroundArea(tmparea)) continue;
00355 } //end if
00356 //
00357 for (face = tmparea->tmpfaces; face; face = face->next[side])
00358 {
00359 side = (face->frontarea != tmparea);
00360 //if the face has both a front and back area
00361 if (face->frontarea && face->backarea)
00362 {
00363 //
00364 if (face->frontarea == tmparea) othertmparea = face->backarea;
00365 else othertmparea = face->frontarea;
00366 //
00367 if (groundfirst)
00368 {
00369 if (!AAS_GroundArea(othertmparea)) continue;
00370 } //end if
00371 if (AAS_TryMergeFaceAreas(face))
00372 {
00373 qprintf("\r%6d", ++nummerges);
00374 merges++;
00375 break;
00376 } //end if
00377 } //end if
00378 } //end for
00379 } //end for
00380 if (!merges)
00381 {
00382 if (groundfirst) groundfirst = false;
00383 else break;
00384 } //end if
00385 } //end for
00386 qprintf("\n");
00387 Log_Write("%6d areas merged\r\n", nummerges);
00388 //refresh the merged tree
00389 AAS_RefreshMergedTree_r(tmpaasworld.nodes);
00390 } //end of the function AAS_MergeAreas
|
Here is the call graph for this function:

|
|
Definition at line 36 of file aas_areamerging.c. References tmp_node_s::children, tmp_area_s::mergedarea, tmp_area_t, tmp_node_t, and tmp_node_s::tmparea. Referenced by AAS_MergeAreas(). 00037 {
00038 tmp_area_t *tmparea;
00039
00040 //if this is a solid leaf
00041 if (!tmpnode) return NULL;
00042 //if this is an area leaf
00043 if (tmpnode->tmparea)
00044 {
00045 tmparea = tmpnode->tmparea;
00046 while(tmparea->mergedarea) tmparea = tmparea->mergedarea;
00047 tmpnode->tmparea = tmparea;
00048 return tmpnode;
00049 } //end if
00050 //do the children recursively
00051 tmpnode->children[0] = AAS_RefreshMergedTree_r(tmpnode->children[0]);
00052 tmpnode->children[1] = AAS_RefreshMergedTree_r(tmpnode->children[1]);
00053 return tmpnode;
00054 } //end of the function AAS_RefreshMergedTree_r
|
|
|
Definition at line 95 of file aas_areamerging.c. References AAS_AddFaceSideToArea(), AAS_AllocTmpArea(), AAS_CheckArea(), AAS_FlipAreaFaces(), AAS_FreeTmpFace(), AAS_GapFace(), AAS_RemoveFaceFromArea(), tmp_face_s::backarea, tmp_area_s::contents, Error(), tmp_face_s::faceflags, tmp_face_s::frontarea, tmp_area_s::invalid, tmp_area_s::mergedarea, tmp_area_s::modelnum, tmp_face_s::next, NonConvex(), tmp_area_s::presencetype, tmp_area_t, tmp_face_t, and tmp_area_s::tmpfaces. Referenced by AAS_MergeAreas(). 00096 {
00097 int side1, side2, area1faceflags, area2faceflags;
00098 tmp_area_t *tmparea1, *tmparea2, *newarea;
00099 tmp_face_t *face1, *face2, *nextface1, *nextface2;
00100
00101 tmparea1 = seperatingface->frontarea;
00102 tmparea2 = seperatingface->backarea;
00103
00104 //areas must have the same presence type
00105 if (tmparea1->presencetype != tmparea2->presencetype) return false;
00106 //areas must have the same area contents
00107 if (tmparea1->contents != tmparea2->contents) return false;
00108 //areas must have the same bsp model inside (or both none)
00109 if (tmparea1->modelnum != tmparea2->modelnum) return false;
00110
00111 area1faceflags = 0;
00112 area2faceflags = 0;
00113 for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1])
00114 {
00115 side1 = (face1->frontarea != tmparea1);
00116 //debug: check if the area belongs to the area
00117 if (face1->frontarea != tmparea1 &&
00118 face1->backarea != tmparea1) Error("face does not belong to area1");
00119 //just continue if the face is seperating the two areas
00120 //NOTE: a result of this is that ground and gap areas can
00121 // be merged if the seperating face is the gap
00122 if ((face1->frontarea == tmparea1 &&
00123 face1->backarea == tmparea2) ||
00124 (face1->frontarea == tmparea2 &&
00125 face1->backarea == tmparea1)) continue;
00126 //get area1 face flags
00127 area1faceflags |= face1->faceflags;
00128 if (AAS_GapFace(face1, side1)) area1faceflags |= FACE_GAP;
00129 //
00130 for (face2 = tmparea2->tmpfaces; face2; face2 = face2->next[side2])
00131 {
00132 side2 = (face2->frontarea != tmparea2);
00133 //debug: check if the area belongs to the area
00134 if (face2->frontarea != tmparea2 &&
00135 face2->backarea != tmparea2) Error("face does not belong to area2");
00136 //just continue if the face is seperating the two areas
00137 //NOTE: a result of this is that ground and gap areas can
00138 // be merged if the seperating face is the gap
00139 if ((face2->frontarea == tmparea1 &&
00140 face2->backarea == tmparea2) ||
00141 (face2->frontarea == tmparea2 &&
00142 face2->backarea == tmparea1)) continue;
00143 //get area2 face flags
00144 area2faceflags |= face2->faceflags;
00145 if (AAS_GapFace(face2, side2)) area2faceflags |= FACE_GAP;
00146 //if the two faces would create a non-convex area
00147 if (NonConvex(face1, face2, side1, side2)) return false;
00148 } //end for
00149 } //end for
00150 //if one area has gap faces (that aren't seperating the two areas)
00151 //and the other has ground faces (that aren't seperating the two areas),
00152 //the areas can't be merged
00153 if (((area1faceflags & FACE_GROUND) && (area2faceflags & FACE_GAP)) ||
00154 ((area2faceflags & FACE_GROUND) && (area1faceflags & FACE_GAP)))
00155 {
00156 // Log_Print(" can't merge: ground/gap\n");
00157 return false;
00158 } //end if
00159
00160 // Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum, numfaces);
00161 // return false;
00162 //
00163 //AAS_CheckArea(tmparea1);
00164 //AAS_CheckArea(tmparea2);
00165 //create the new area
00166 newarea = AAS_AllocTmpArea();
00167 newarea->presencetype = tmparea1->presencetype;
00168 newarea->contents = tmparea1->contents;
00169 newarea->modelnum = tmparea1->modelnum;
00170 newarea->tmpfaces = NULL;
00171
00172 //add all the faces (except the seperating ones) from the first area
00173 //to the new area
00174 for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
00175 {
00176 side1 = (face1->frontarea != tmparea1);
00177 nextface1 = face1->next[side1];
00178 //don't add seperating faces
00179 if ((face1->frontarea == tmparea1 &&
00180 face1->backarea == tmparea2) ||
00181 (face1->frontarea == tmparea2 &&
00182 face1->backarea == tmparea1))
00183 {
00184 continue;
00185 } //end if
00186 //
00187 AAS_RemoveFaceFromArea(face1, tmparea1);
00188 AAS_AddFaceSideToArea(face1, side1, newarea);
00189 } //end for
00190 //add all the faces (except the seperating ones) from the second area
00191 //to the new area
00192 for (face2 = tmparea2->tmpfaces; face2; face2 = nextface2)
00193 {
00194 side2 = (face2->frontarea != tmparea2);
00195 nextface2 = face2->next[side2];
00196 //don't add seperating faces
00197 if ((face2->frontarea == tmparea1 &&
00198 face2->backarea == tmparea2) ||
00199 (face2->frontarea == tmparea2 &&
00200 face2->backarea == tmparea1))
00201 {
00202 continue;
00203 } //end if
00204 //
00205 AAS_RemoveFaceFromArea(face2, tmparea2);
00206 AAS_AddFaceSideToArea(face2, side2, newarea);
00207 } //end for
00208 //free all shared faces
00209 for (face1 = tmparea1->tmpfaces; face1; face1 = nextface1)
00210 {
00211 side1 = (face1->frontarea != tmparea1);
00212 nextface1 = face1->next[side1];
00213 //
00214 AAS_RemoveFaceFromArea(face1, face1->frontarea);
00215 AAS_RemoveFaceFromArea(face1, face1->backarea);
00216 AAS_FreeTmpFace(face1);
00217 } //end for
00218 //
00219 tmparea1->mergedarea = newarea;
00220 tmparea1->invalid = true;
00221 tmparea2->mergedarea = newarea;
00222 tmparea2->invalid = true;
00223 //
00224 AAS_CheckArea(newarea);
00225 AAS_FlipAreaFaces(newarea);
00226 // Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum);
00227 return true;
00228 } //end of the function AAS_TryMergeFaceAreas
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 63 of file aas_areamerging.c. References plane_t::dist, DotProduct, i, mapplanes, plane_t::normal, winding_t::numpoints, winding_t::p, tmp_face_s::planenum, tmp_face_t, and tmp_face_s::winding. Referenced by AAS_TryMergeFaceAreas(). 00064 {
00065 int i;
00066 winding_t *w1, *w2;
00067 plane_t *plane1, *plane2;
00068
00069 w1 = face1->winding;
00070 w2 = face2->winding;
00071
00072 plane1 = &mapplanes[face1->planenum ^ side1];
00073 plane2 = &mapplanes[face2->planenum ^ side2];
00074
00075 //check if one of the points of face1 is at the back of the plane of face2
00076 for (i = 0; i < w1->numpoints; i++)
00077 {
00078 if (DotProduct(plane2->normal, w1->p[i]) - plane2->dist < -CONVEX_EPSILON) return true;
00079 } //end for
00080 //check if one of the points of face2 is at the back of the plane of face1
00081 for (i = 0; i < w2->numpoints; i++)
00082 {
00083 if (DotProduct(plane1->normal, w2->p[i]) - plane1->dist < -CONVEX_EPSILON) return true;
00084 } //end for
00085
00086 return false;
00087 } //end of the function NonConvex
|
1.3.9.1