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

aas_areamerging.c File Reference

#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
#include "aas_store.h"

Include dependency graph for aas_areamerging.c:

Include dependency graph

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_tAAS_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)


Define Documentation

#define CONVEX_EPSILON   0.3
 

Definition at line 28 of file aas_areamerging.c.


Function Documentation

int AAS_GroundArea tmp_area_t tmparea  ) 
 

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

void AAS_MergeAreas void   ) 
 

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:

tmp_node_t* AAS_RefreshMergedTree_r tmp_node_t tmpnode  ) 
 

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

int AAS_TryMergeFaceAreas tmp_face_t seperatingface  ) 
 

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:

int NonConvex tmp_face_t face1,
tmp_face_t face2,
int  side1,
int  side2
 

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


Generated on Thu Aug 25 12:44:41 2005 for Quake III Arena by  doxygen 1.3.9.1