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

be_aas_cluster.c File Reference

#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_log.h"
#include "l_libvar.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_aas_def.h"

Include dependency graph for be_aas_cluster.c:

Include dependency graph

Go to the source code of this file.

Defines

#define AAS_MAX_CLUSTERS   65536
#define AAS_MAX_PORTALINDEXSIZE   65536
#define AAS_MAX_PORTALS   65536
#define MAX_PORTALAREAS   1024

Functions

int AAS_CheckAreaForPossiblePortals (int areanum)
void AAS_ClearCluster (int clusternum)
qboolean AAS_ConnectedAreas (int *areanums, int numareas)
void AAS_ConnectedAreas_r (int *areanums, int numareas, int *connectedareas, int curarea)
void AAS_CountForcedClusterPortals (void)
void AAS_CreatePortals (void)
void AAS_CreateViewPortals (void)
int AAS_FindClusters (void)
void AAS_FindPossiblePortals (void)
int AAS_FloodClusterAreas_r (int areanum, int clusternum)
int AAS_FloodClusterAreasUsingReachabilities (int clusternum)
int AAS_GetAdjacentAreasWithLessPresenceTypes_r (int *areanums, int numareas, int curareanum)
void AAS_InitClustering (void)
void AAS_NumberClusterAreas (int clusternum)
void AAS_NumberClusterPortals (int clusternum)
void AAS_RemoveAllPortals (void)
void AAS_RemoveClusterAreas (void)
void AAS_RemovePortalsClusterReference (int clusternum)
void AAS_SetViewPortalsAsClusterPortals (void)
int AAS_TestPortals (void)
int AAS_UpdatePortal (int areanum, int clusternum)

Variables

botlib_import_t botimport
int nofaceflood = qtrue


Define Documentation

#define AAS_MAX_CLUSTERS   65536
 

Definition at line 50 of file be_aas_cluster.c.

Referenced by AAS_InitClustering().

#define AAS_MAX_PORTALINDEXSIZE   65536
 

Definition at line 49 of file be_aas_cluster.c.

Referenced by AAS_InitClustering().

#define AAS_MAX_PORTALS   65536
 

Definition at line 48 of file be_aas_cluster.c.

Referenced by AAS_InitClustering().

#define MAX_PORTALAREAS   1024
 

Definition at line 52 of file be_aas_cluster.c.


Function Documentation

int AAS_CheckAreaForPossiblePortals int  areanum  ) 
 

Definition at line 793 of file be_aas_cluster.c.

References aas_area_t, AAS_ConnectedAreas(), aas_face_t, AAS_GetAdjacentAreasWithLessPresenceTypes_r(), aasworld, abs(), aas_areasettings_s::areaflags, aas_s::areas, aas_s::areasettings, aas_face_s::backarea, Com_Memset(), aas_areasettings_s::contents, aas_s::edgeindex, aas_face_s::faceflags, aas_s::faceindex, aas_s::faces, aas_face_s::firstedge, aas_area_s::firstface, aas_face_s::frontarea, i, j, k, Log_Write(), numareas, aas_face_s::numedges, aas_area_s::numfaces, and aas_face_s::planenum.

Referenced by AAS_FindPossiblePortals().

00794 {
00795     int i, j, k, fen, ben, frontedgenum, backedgenum, facenum;
00796     int areanums[MAX_PORTALAREAS], numareas, otherareanum;
00797     int numareafrontfaces[MAX_PORTALAREAS], numareabackfaces[MAX_PORTALAREAS];
00798     int frontfacenums[MAX_PORTALAREAS], backfacenums[MAX_PORTALAREAS];
00799     int numfrontfaces, numbackfaces;
00800     int frontareanums[MAX_PORTALAREAS], backareanums[MAX_PORTALAREAS];
00801     int numfrontareas, numbackareas;
00802     int frontplanenum, backplanenum, faceplanenum;
00803     aas_area_t *area;
00804     aas_face_t *frontface, *backface, *face;
00805 
00806     //if it isn't already a portal
00807     if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL) return 0;
00808     //it must be a grounded area
00809     if (!(aasworld.areasettings[areanum].areaflags & AREA_GROUNDED)) return 0;
00810     //
00811     Com_Memset(numareafrontfaces, 0, sizeof(numareafrontfaces));
00812     Com_Memset(numareabackfaces, 0, sizeof(numareabackfaces));
00813     numareas = numfrontfaces = numbackfaces = 0;
00814     numfrontareas = numbackareas = 0;
00815     frontplanenum = backplanenum = -1;
00816     //add any adjacent areas with less presence types
00817     numareas = AAS_GetAdjacentAreasWithLessPresenceTypes_r(areanums, 0, areanum);
00818     //
00819     for (i = 0; i < numareas; i++)
00820     {
00821         area = &aasworld.areas[areanums[i]];
00822         for (j = 0; j < area->numfaces; j++)
00823         {
00824             facenum = abs(aasworld.faceindex[area->firstface + j]);
00825             face = &aasworld.faces[facenum];
00826             //if the face is solid
00827             if (face->faceflags & FACE_SOLID) continue;
00828             //check if the face is shared with one of the other areas
00829             for (k = 0; k < numareas; k++)
00830             {
00831                 if (k == i) continue;
00832                 if (face->frontarea == areanums[k] || face->backarea == areanums[k]) break;
00833             } //end for
00834             //if the face is shared
00835             if (k != numareas) continue;
00836             //the number of the area at the other side of the face
00837             if (face->frontarea == areanums[i]) otherareanum = face->backarea;
00838             else otherareanum = face->frontarea;
00839             //if the other area already is a cluter portal
00840             if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) return 0;
00841             //number of the plane of the area
00842             faceplanenum = face->planenum & ~1;
00843             //
00844             if (frontplanenum < 0 || faceplanenum == frontplanenum)
00845             {
00846                 frontplanenum = faceplanenum;
00847                 frontfacenums[numfrontfaces++] = facenum;
00848                 for (k = 0; k < numfrontareas; k++)
00849                 {
00850                     if (frontareanums[k] == otherareanum) break;
00851                 } //end for
00852                 if (k == numfrontareas) frontareanums[numfrontareas++] = otherareanum;
00853                 numareafrontfaces[i]++;
00854             } //end if
00855             else if (backplanenum < 0 || faceplanenum == backplanenum)
00856             {
00857                 backplanenum = faceplanenum;
00858                 backfacenums[numbackfaces++] = facenum;
00859                 for (k = 0; k < numbackareas; k++)
00860                 {
00861                     if (backareanums[k] == otherareanum) break;
00862                 } //end for
00863                 if (k == numbackareas) backareanums[numbackareas++] = otherareanum;
00864                 numareabackfaces[i]++;
00865             } //end else
00866             else
00867             {
00868                 return 0;
00869             } //end else
00870         } //end for
00871     } //end for
00872     //every area should have at least one front face and one back face
00873     for (i = 0; i < numareas; i++)
00874     {
00875         if (!numareafrontfaces[i] || !numareabackfaces[i]) return 0;
00876     } //end for
00877     //the front areas should all be connected
00878     if (!AAS_ConnectedAreas(frontareanums, numfrontareas)) return 0;
00879     //the back areas should all be connected
00880     if (!AAS_ConnectedAreas(backareanums, numbackareas)) return 0;
00881     //none of the front faces should have a shared edge with a back face
00882     for (i = 0; i < numfrontfaces; i++)
00883     {
00884         frontface = &aasworld.faces[frontfacenums[i]];
00885         for (fen = 0; fen < frontface->numedges; fen++)
00886         {
00887             frontedgenum = abs(aasworld.edgeindex[frontface->firstedge + fen]);
00888             for (j = 0; j < numbackfaces; j++)
00889             {
00890                 backface = &aasworld.faces[backfacenums[j]];
00891                 for (ben = 0; ben < backface->numedges; ben++)
00892                 {
00893                     backedgenum = abs(aasworld.edgeindex[backface->firstedge + ben]);
00894                     if (frontedgenum == backedgenum) break;
00895                 } //end for
00896                 if (ben != backface->numedges) break;
00897             } //end for
00898             if (j != numbackfaces) break;
00899         } //end for
00900         if (fen != frontface->numedges) break;
00901     } //end for
00902     if (i != numfrontfaces) return 0;
00903     //set the cluster portal contents
00904     for (i = 0; i < numareas; i++)
00905     {
00906         aasworld.areasettings[areanums[i]].contents |= AREACONTENTS_CLUSTERPORTAL;
00907         //this area can be used as a route portal
00908         aasworld.areasettings[areanums[i]].contents |= AREACONTENTS_ROUTEPORTAL;
00909         Log_Write("possible portal: %d\r\n", areanums[i]);
00910     } //end for
00911     //
00912     return numareas;
00913 } //end of the function AAS_CheckAreaForPossiblePortals

Here is the call graph for this function:

void AAS_ClearCluster int  clusternum  ) 
 

Definition at line 78 of file be_aas_cluster.c.

References aasworld, aas_s::areasettings, aas_areasettings_s::cluster, i, and aas_s::numareas.

00079 {
00080     int i;
00081 
00082     for (i = 1; i < aasworld.numareas; i++)
00083     {
00084         if (aasworld.areasettings[i].cluster == clusternum)
00085         {
00086             aasworld.areasettings[i].cluster = 0;
00087         } //end if
00088     } //end for
00089 } //end of the function AAS_ClearCluster

qboolean AAS_ConnectedAreas int *  areanums,
int  numareas
 

Definition at line 723 of file be_aas_cluster.c.

References AAS_ConnectedAreas_r(), Com_Memset(), i, numareas, and qboolean.

Referenced by AAS_CheckAreaForPossiblePortals().

00724 {
00725     int connectedareas[MAX_PORTALAREAS], i;
00726 
00727     Com_Memset(connectedareas, 0, sizeof(connectedareas));
00728     if (numareas < 1) return qfalse;
00729     if (numareas == 1) return qtrue;
00730     AAS_ConnectedAreas_r(areanums, numareas, connectedareas, 0);
00731     for (i = 0; i < numareas; i++)
00732     {
00733         if (!connectedareas[i]) return qfalse;
00734     } //end for
00735     return qtrue;
00736 } //end of the function AAS_ConnectedAreas

Here is the call graph for this function:

void AAS_ConnectedAreas_r int *  areanums,
int  numareas,
int *  connectedareas,
int  curarea
 

Definition at line 687 of file be_aas_cluster.c.

References aas_area_t, aas_face_t, aasworld, abs(), aas_s::areas, aas_face_s::backarea, aas_face_s::faceflags, aas_s::faceindex, aas_s::faces, aas_area_s::firstface, aas_face_s::frontarea, i, j, numareas, and aas_area_s::numfaces.

Referenced by AAS_ConnectedAreas().

00688 {
00689     int i, j, otherareanum, facenum;
00690     aas_area_t *area;
00691     aas_face_t *face;
00692 
00693     connectedareas[curarea] = qtrue;
00694     area = &aasworld.areas[areanums[curarea]];
00695     for (i = 0; i < area->numfaces; i++)
00696     {
00697         facenum = abs(aasworld.faceindex[area->firstface + i]);
00698         face = &aasworld.faces[facenum];
00699         //if the face is solid
00700         if (face->faceflags & FACE_SOLID) continue;
00701         //get the area at the other side of the face
00702         if (face->frontarea != areanums[curarea]) otherareanum = face->frontarea;
00703         else otherareanum = face->backarea;
00704         //check if the face is leading to one of the other areas
00705         for (j = 0; j < numareas; j++)
00706         {
00707             if (areanums[j] == otherareanum) break;
00708         } //end for
00709         //if the face isn't leading to one of the other areas
00710         if (j == numareas) continue;
00711         //if the other area is already connected
00712         if (connectedareas[j]) continue;
00713         //recursively proceed with the other area
00714         AAS_ConnectedAreas_r(areanums, numareas, connectedareas, j);
00715     } //end for
00716 } //end of the function AAS_ConnectedAreas_r

Here is the call graph for this function:

void AAS_CountForcedClusterPortals void   ) 
 

Definition at line 1401 of file be_aas_cluster.c.

References aasworld, aas_s::areasettings, botimport, aas_areasettings_s::contents, i, Log_Write(), aas_s::numareas, and PRT_MESSAGE.

Referenced by AAS_InitClustering().

01402 {
01403     int num, i;
01404 
01405     num = 0;
01406     for (i = 1; i < aasworld.numareas; i++)
01407     {
01408         if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
01409         {
01410             Log_Write("area %d is a forced portal area\r\n", i);
01411             num++;
01412         } //end if
01413     } //end for
01414     botimport.Print(PRT_MESSAGE, "%6d forced portal areas\n", num);
01415 } //end of the function AAS_CountForcedClusterPortals

Here is the call graph for this function:

void AAS_CreatePortals void   ) 
 

Definition at line 439 of file be_aas_cluster.c.

References AAS_Error, aas_portal_t, aasworld, aas_portal_s::areanum, aas_s::areasettings, aas_portal_s::backcluster, aas_areasettings_s::contents, aas_portal_s::frontcluster, i, aas_s::numareas, aas_s::numportals, and aas_s::portals.

Referenced by AAS_InitClustering().

00440 {
00441     int i;
00442     aas_portal_t *portal;
00443 
00444     for (i = 1; i < aasworld.numareas; i++)
00445     {
00446         //if the area is a cluster portal
00447         if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
00448         {
00449             if (aasworld.numportals >= AAS_MAX_PORTALS)
00450             {
00451                 AAS_Error("AAS_MAX_PORTALS");
00452                 return;
00453             } //end if
00454             portal = &aasworld.portals[aasworld.numportals];
00455             portal->areanum = i;
00456             portal->frontcluster = 0;
00457             portal->backcluster = 0;
00458             aasworld.numportals++;
00459         } //end if
00460     } //end for
00461 } //end of the function AAS_CreatePortals

void AAS_CreateViewPortals void   ) 
 

Definition at line 1422 of file be_aas_cluster.c.

References aasworld, aas_s::areasettings, aas_areasettings_s::contents, i, and aas_s::numareas.

Referenced by AAS_InitClustering().

01423 {
01424     int i;
01425 
01426     for (i = 1; i < aasworld.numareas; i++)
01427     {
01428         if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
01429         {
01430             aasworld.areasettings[i].contents |= AREACONTENTS_VIEWPORTAL;
01431         } //end if
01432     } //end for
01433 } //end of the function AAS_CreateViewPortals

int AAS_FindClusters void   ) 
 

Definition at line 389 of file be_aas_cluster.c.

References aas_cluster_t, AAS_Error, AAS_FloodClusterAreas_r(), AAS_FloodClusterAreasUsingReachabilities(), AAS_NumberClusterAreas(), AAS_RemoveClusterAreas(), aasworld, aas_s::areasettings, aas_areasettings_s::cluster, aas_s::clusters, aas_areasettings_s::contents, aas_cluster_s::firstportal, i, aas_cluster_s::numareas, aas_s::numareas, aas_s::numclusters, aas_cluster_s::numportals, aas_cluster_s::numreachabilityareas, aas_areasettings_s::numreachableareas, and aas_s::portalindexsize.

Referenced by AAS_InitClustering().

00390 {
00391     int i;
00392     aas_cluster_t *cluster;
00393 
00394     AAS_RemoveClusterAreas();
00395     //
00396     for (i = 1; i < aasworld.numareas; i++)
00397     {
00398         //if the area is already part of a cluster
00399         if (aasworld.areasettings[i].cluster)
00400             continue;
00401         // if not flooding through faces only use areas that have reachabilities
00402         if (nofaceflood)
00403         {
00404             if (!aasworld.areasettings[i].numreachableareas)
00405                 continue;
00406         } //end if
00407         //if the area is a cluster portal
00408         if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
00409             continue;
00410         if (aasworld.numclusters >= AAS_MAX_CLUSTERS)
00411         {
00412             AAS_Error("AAS_MAX_CLUSTERS");
00413             return qfalse;
00414         } //end if
00415         cluster = &aasworld.clusters[aasworld.numclusters];
00416         cluster->numareas = 0;
00417         cluster->numreachabilityareas = 0;
00418         cluster->firstportal = aasworld.portalindexsize;
00419         cluster->numportals = 0;
00420         //flood the areas in this cluster
00421         if (!AAS_FloodClusterAreas_r(i, aasworld.numclusters))
00422             return qfalse;
00423         if (!AAS_FloodClusterAreasUsingReachabilities(aasworld.numclusters))
00424             return qfalse;
00425         //number the cluster areas
00426         //AAS_NumberClusterPortals(aasworld.numclusters);
00427         AAS_NumberClusterAreas(aasworld.numclusters);
00428         //Log_Write("cluster %d has %d areas\r\n", aasworld.numclusters, cluster->numareas);
00429         aasworld.numclusters++;
00430     } //end for
00431     return qtrue;
00432 } //end of the function AAS_FindClusters

Here is the call graph for this function:

void AAS_FindPossiblePortals void   ) 
 

Definition at line 920 of file be_aas_cluster.c.

References AAS_CheckAreaForPossiblePortals(), aasworld, botimport, i, aas_s::numareas, and PRT_MESSAGE.

Referenced by AAS_InitClustering().

00921 {
00922     int i, numpossibleportals;
00923 
00924     numpossibleportals = 0;
00925     for (i = 1; i < aasworld.numareas; i++)
00926     {
00927         numpossibleportals += AAS_CheckAreaForPossiblePortals(i);
00928     } //end for
00929     botimport.Print(PRT_MESSAGE, "\r%6d possible portal areas\n", numpossibleportals);
00930 } //end of the function AAS_FindPossiblePortals

Here is the call graph for this function:

int AAS_FloodClusterAreas_r int  areanum,
int  clusternum
 

Definition at line 177 of file be_aas_cluster.c.

References aas_area_t, AAS_Error, aas_face_t, AAS_UpdatePortal(), aasworld, abs(), aas_reachability_s::areanum, aas_s::areas, aas_s::areasettings, aas_face_s::backarea, aas_areasettings_s::cluster, aas_areasettings_s::clusterareanum, aas_s::clusters, aas_areasettings_s::contents, aas_s::faceindex, aas_s::faces, aas_area_s::firstface, aas_areasettings_s::firstreachablearea, aas_face_s::frontarea, i, aas_cluster_s::numareas, aas_s::numareas, aas_area_s::numfaces, aas_areasettings_s::numreachableareas, and aas_s::reachability.

Referenced by AAS_FindClusters(), and AAS_FloodClusterAreasUsingReachabilities().

00178 {
00179     aas_area_t *area;
00180     aas_face_t *face;
00181     int facenum, i;
00182 
00183     //
00184     if (areanum <= 0 || areanum >= aasworld.numareas)
00185     {
00186         AAS_Error("AAS_FloodClusterAreas_r: areanum out of range");
00187         return qfalse;
00188     } //end if
00189     //if the area is already part of a cluster
00190     if (aasworld.areasettings[areanum].cluster > 0)
00191     {
00192         if (aasworld.areasettings[areanum].cluster == clusternum) return qtrue;
00193         //
00194         //there's a reachability going from one cluster to another only in one direction
00195         //
00196         AAS_Error("cluster %d touched cluster %d at area %d\r\n",
00197                 clusternum, aasworld.areasettings[areanum].cluster, areanum);
00198         return qfalse;
00199     } //end if
00200     //don't add the cluster portal areas to the clusters
00201     if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL)
00202     {
00203         return AAS_UpdatePortal(areanum, clusternum);
00204     } //end if
00205     //set the area cluster number
00206     aasworld.areasettings[areanum].cluster = clusternum;
00207     aasworld.areasettings[areanum].clusterareanum =
00208                 aasworld.clusters[clusternum].numareas;
00209     //the cluster has an extra area
00210     aasworld.clusters[clusternum].numareas++;
00211 
00212     area = &aasworld.areas[areanum];
00213     //use area faces to flood into adjacent areas
00214     if (!nofaceflood)
00215     {
00216         for (i = 0; i < area->numfaces; i++)
00217         {
00218             facenum = abs(aasworld.faceindex[area->firstface + i]);
00219             face = &aasworld.faces[facenum];
00220             if (face->frontarea == areanum)
00221             {
00222                 if (face->backarea) if (!AAS_FloodClusterAreas_r(face->backarea, clusternum)) return qfalse;
00223             } //end if
00224             else
00225             {
00226                 if (face->frontarea) if (!AAS_FloodClusterAreas_r(face->frontarea, clusternum)) return qfalse;
00227             } //end else
00228         } //end for
00229     } //end if
00230     //use the reachabilities to flood into other areas
00231     for (i = 0; i < aasworld.areasettings[areanum].numreachableareas; i++)
00232     {
00233         if (!aasworld.reachability[
00234                     aasworld.areasettings[areanum].firstreachablearea + i].areanum)
00235         {
00236             continue;
00237         } //end if
00238         if (!AAS_FloodClusterAreas_r(aasworld.reachability[
00239                 aasworld.areasettings[areanum].firstreachablearea + i].areanum, clusternum)) return qfalse;
00240     } //end for
00241     return qtrue;
00242 } //end of the function AAS_FloodClusterAreas_r

Here is the call graph for this function:

int AAS_FloodClusterAreasUsingReachabilities int  clusternum  ) 
 

Definition at line 250 of file be_aas_cluster.c.

References AAS_FloodClusterAreas_r(), aasworld, aas_reachability_s::areanum, aas_s::areasettings, aas_areasettings_s::cluster, aas_areasettings_s::contents, aas_areasettings_s::firstreachablearea, i, j, aas_s::numareas, aas_areasettings_s::numreachableareas, and aas_s::reachability.

Referenced by AAS_FindClusters().

00251 {
00252     int i, j, areanum;
00253 
00254     for (i = 1; i < aasworld.numareas; i++)
00255     {
00256         //if this area already has a cluster set
00257         if (aasworld.areasettings[i].cluster)
00258             continue;
00259         //if this area is a cluster portal
00260         if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
00261             continue;
00262         //loop over the reachable areas from this area
00263         for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++)
00264         {
00265             //the reachable area
00266             areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum;
00267             //if this area is a cluster portal
00268             if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL)
00269                 continue;
00270             //if this area has a cluster set
00271             if (aasworld.areasettings[areanum].cluster)
00272             {
00273                 if (!AAS_FloodClusterAreas_r(i, clusternum))
00274                     return qfalse;
00275                 i = 0;
00276                 break;
00277             } //end if
00278         } //end for
00279     } //end for
00280     return qtrue;
00281 } //end of the function AAS_FloodClusterAreasUsingReachabilities

Here is the call graph for this function:

int AAS_GetAdjacentAreasWithLessPresenceTypes_r int *  areanums,
int  numareas,
int  curareanum
 

Definition at line 744 of file be_aas_cluster.c.

References aas_area_t, AAS_Error, aas_face_t, aasworld, abs(), aas_s::areas, aas_s::areasettings, aas_face_s::backarea, aas_face_s::faceflags, aas_s::faceindex, aas_s::faces, aas_area_s::firstface, aas_face_s::frontarea, i, j, numareas, aas_area_s::numfaces, and aas_areasettings_s::presencetype.

Referenced by AAS_CheckAreaForPossiblePortals().

00745 {
00746     int i, j, presencetype, otherpresencetype, otherareanum, facenum;
00747     aas_area_t *area;
00748     aas_face_t *face;
00749 
00750     areanums[numareas++] = curareanum;
00751     area = &aasworld.areas[curareanum];
00752     presencetype = aasworld.areasettings[curareanum].presencetype;
00753     for (i = 0; i < area->numfaces; i++)
00754     {
00755         facenum = abs(aasworld.faceindex[area->firstface + i]);
00756         face = &aasworld.faces[facenum];
00757         //if the face is solid
00758         if (face->faceflags & FACE_SOLID) continue;
00759         //the area at the other side of the face
00760         if (face->frontarea != curareanum) otherareanum = face->frontarea;
00761         else otherareanum = face->backarea;
00762         //
00763         otherpresencetype = aasworld.areasettings[otherareanum].presencetype;
00764         //if the other area has less presence types
00765         if ((presencetype & ~otherpresencetype) &&
00766                 !(otherpresencetype & ~presencetype))
00767         {
00768             //check if the other area isn't already in the list
00769             for (j = 0; j < numareas; j++)
00770             {
00771                 if (otherareanum == areanums[j]) break;
00772             } //end for
00773             //if the other area isn't already in the list
00774             if (j == numareas)
00775             {
00776                 if (numareas >= MAX_PORTALAREAS)
00777                 {
00778                     AAS_Error("MAX_PORTALAREAS");
00779                     return numareas;
00780                 } //end if
00781                 numareas = AAS_GetAdjacentAreasWithLessPresenceTypes_r(areanums, numareas, otherareanum);
00782             } //end if
00783         } //end if
00784     } //end for
00785     return numareas;
00786 } //end of the function AAS_GetAdjacentAreasWithLessPresenceTypes_r

Here is the call graph for this function:

void AAS_InitClustering void   ) 
 

Definition at line 1458 of file be_aas_cluster.c.

References aas_cluster_t, AAS_CountForcedClusterPortals(), AAS_CreatePortals(), AAS_CreateViewPortals(), AAS_FindClusters(), AAS_FindPossiblePortals(), AAS_MAX_CLUSTERS, AAS_MAX_PORTALINDEXSIZE, AAS_MAX_PORTALS, aas_portal_t, aas_portalindex_t, AAS_RemoveClusterAreas(), AAS_SetViewPortalsAsClusterPortals(), AAS_TestPortals(), aasworld, aas_portal_s::areanum, botimport, aas_s::clusters, FreeMemory(), GetClearedMemory(), i, LibVarGetValue(), aas_s::loaded, Log_Write(), n, aas_s::numclusters, aas_s::numportals, aas_cluster_s::numreachabilityareas, aas_s::portalindex, aas_s::portalindexsize, aas_s::portals, PRT_MESSAGE, and aas_s::savefile.

Referenced by AAS_CalcReachAndClusters(), AAS_ContinueInit(), and main().

01459 {
01460     int i, removedPortalAreas;
01461     int n, total, numreachabilityareas;
01462 
01463     if (!aasworld.loaded) return;
01464     //if there are clusters
01465     if (aasworld.numclusters >= 1)
01466     {
01467 #ifndef BSPC
01468         //if clustering isn't forced
01469         if (!((int)LibVarGetValue("forceclustering")) &&
01470             !((int)LibVarGetValue("forcereachability"))) return;
01471 #endif
01472     } //end if
01473     //set all view portals as cluster portals in case we re-calculate the reachabilities and clusters (with -reach)
01474     AAS_SetViewPortalsAsClusterPortals();
01475     //count the number of forced cluster portals
01476     AAS_CountForcedClusterPortals();
01477     //remove all area cluster marks
01478     AAS_RemoveClusterAreas();
01479     //find possible cluster portals
01480     AAS_FindPossiblePortals();
01481     //craete portals to for the bot view
01482     AAS_CreateViewPortals();
01483     //remove all portals that are not closing a cluster
01484     //AAS_RemoveNotClusterClosingPortals();
01485     //initialize portal memory
01486     if (aasworld.portals) FreeMemory(aasworld.portals);
01487     aasworld.portals = (aas_portal_t *) GetClearedMemory(AAS_MAX_PORTALS * sizeof(aas_portal_t));
01488     //initialize portal index memory
01489     if (aasworld.portalindex) FreeMemory(aasworld.portalindex);
01490     aasworld.portalindex = (aas_portalindex_t *) GetClearedMemory(AAS_MAX_PORTALINDEXSIZE * sizeof(aas_portalindex_t));
01491     //initialize cluster memory
01492     if (aasworld.clusters) FreeMemory(aasworld.clusters);
01493     aasworld.clusters = (aas_cluster_t *) GetClearedMemory(AAS_MAX_CLUSTERS * sizeof(aas_cluster_t));
01494     //
01495     removedPortalAreas = 0;
01496     botimport.Print(PRT_MESSAGE, "\r%6d removed portal areas", removedPortalAreas);
01497     while(1)
01498     {
01499         botimport.Print(PRT_MESSAGE, "\r%6d", removedPortalAreas);
01500         //initialize the number of portals and clusters
01501         aasworld.numportals = 1;        //portal 0 is a dummy
01502         aasworld.portalindexsize = 0;
01503         aasworld.numclusters = 1;       //cluster 0 is a dummy
01504         //create the portals from the portal areas
01505         AAS_CreatePortals();
01506         //
01507         removedPortalAreas++;
01508         //find the clusters
01509         if (!AAS_FindClusters())
01510             continue;
01511         //test the portals
01512         if (!AAS_TestPortals())
01513             continue;
01514         //
01515         break;
01516     } //end while
01517     botimport.Print(PRT_MESSAGE, "\n");
01518     //the AAS file should be saved
01519     aasworld.savefile = qtrue;
01520     //write the portal areas to the log file
01521     for (i = 1; i < aasworld.numportals; i++)
01522     {
01523         Log_Write("portal %d: area %d\r\n", i, aasworld.portals[i].areanum);
01524     } //end for
01525     // report cluster info
01526     botimport.Print(PRT_MESSAGE, "%6d portals created\n", aasworld.numportals);
01527     botimport.Print(PRT_MESSAGE, "%6d clusters created\n", aasworld.numclusters);
01528     for (i = 1; i < aasworld.numclusters; i++)
01529     {
01530         botimport.Print(PRT_MESSAGE, "cluster %d has %d reachability areas\n", i,
01531                 aasworld.clusters[i].numreachabilityareas);
01532     } //end for
01533     // report AAS file efficiency
01534     numreachabilityareas = 0;
01535     total = 0;
01536     for (i = 0; i < aasworld.numclusters; i++) {
01537         n = aasworld.clusters[i].numreachabilityareas;
01538         numreachabilityareas += n;
01539         total += n * n;
01540     }
01541     total += numreachabilityareas * aasworld.numportals;
01542     //
01543     botimport.Print(PRT_MESSAGE, "%6i total reachability areas\n", numreachabilityareas);
01544     botimport.Print(PRT_MESSAGE, "%6i AAS memory/CPU usage (the lower the better)\n", total * 3);
01545 } //end of the function AAS_InitClustering

Here is the call graph for this function:

void AAS_NumberClusterAreas int  clusternum  ) 
 

Definition at line 315 of file be_aas_cluster.c.

References AAS_AreaReachability(), aas_cluster_t, aas_portal_t, aasworld, aas_portal_s::areanum, aas_s::areasettings, aas_areasettings_s::cluster, aas_portal_s::clusterareanum, aas_areasettings_s::clusterareanum, aas_s::clusters, aas_cluster_s::firstportal, aas_portal_s::frontcluster, i, aas_s::numareas, aas_cluster_s::numareas, aas_cluster_s::numportals, aas_cluster_s::numreachabilityareas, aas_s::portalindex, and aas_s::portals.

Referenced by AAS_FindClusters().

00316 {
00317     int i, portalnum;
00318     aas_cluster_t *cluster;
00319     aas_portal_t *portal;
00320 
00321     aasworld.clusters[clusternum].numareas = 0;
00322     aasworld.clusters[clusternum].numreachabilityareas = 0;
00323     //number all areas in this cluster WITH reachabilities
00324     for (i = 1; i < aasworld.numareas; i++)
00325     {
00326         //
00327         if (aasworld.areasettings[i].cluster != clusternum) continue;
00328         //
00329         if (!AAS_AreaReachability(i)) continue;
00330         //
00331         aasworld.areasettings[i].clusterareanum = aasworld.clusters[clusternum].numareas;
00332         //the cluster has an extra area
00333         aasworld.clusters[clusternum].numareas++;
00334         aasworld.clusters[clusternum].numreachabilityareas++;
00335     } //end for
00336     //number all portals in this cluster WITH reachabilities
00337     cluster = &aasworld.clusters[clusternum];
00338     for (i = 0; i < cluster->numportals; i++)
00339     {
00340         portalnum = aasworld.portalindex[cluster->firstportal + i];
00341         portal = &aasworld.portals[portalnum];
00342         if (!AAS_AreaReachability(portal->areanum)) continue;
00343         if (portal->frontcluster == clusternum)
00344         {
00345             portal->clusterareanum[0] = cluster->numareas++;
00346             aasworld.clusters[clusternum].numreachabilityareas++;
00347         } //end if
00348         else
00349         {
00350             portal->clusterareanum[1] = cluster->numareas++;
00351             aasworld.clusters[clusternum].numreachabilityareas++;
00352         } //end else
00353     } //end for
00354     //number all areas in this cluster WITHOUT reachabilities
00355     for (i = 1; i < aasworld.numareas; i++)
00356     {
00357         //
00358         if (aasworld.areasettings[i].cluster != clusternum) continue;
00359         //
00360         if (AAS_AreaReachability(i)) continue;
00361         //
00362         aasworld.areasettings[i].clusterareanum = aasworld.clusters[clusternum].numareas;
00363         //the cluster has an extra area
00364         aasworld.clusters[clusternum].numareas++;
00365     } //end for
00366     //number all portals in this cluster WITHOUT reachabilities
00367     cluster = &aasworld.clusters[clusternum];
00368     for (i = 0; i < cluster->numportals; i++)
00369     {
00370         portalnum = aasworld.portalindex[cluster->firstportal + i];
00371         portal = &aasworld.portals[portalnum];
00372         if (AAS_AreaReachability(portal->areanum)) continue;
00373         if (portal->frontcluster == clusternum)
00374         {
00375             portal->clusterareanum[0] = cluster->numareas++;
00376         } //end if
00377         else
00378         {
00379             portal->clusterareanum[1] = cluster->numareas++;
00380         } //end else
00381     } //end for
00382 } //end of the function AAS_NumberClusterAreas

Here is the call graph for this function:

void AAS_NumberClusterPortals int  clusternum  ) 
 

Definition at line 288 of file be_aas_cluster.c.

References aas_cluster_t, aas_portal_t, aasworld, aas_portal_s::clusterareanum, aas_s::clusters, aas_cluster_s::firstportal, aas_portal_s::frontcluster, i, aas_cluster_s::numareas, aas_cluster_s::numportals, aas_s::portalindex, and aas_s::portals.

00289 {
00290     int i, portalnum;
00291     aas_cluster_t *cluster;
00292     aas_portal_t *portal;
00293 
00294     cluster = &aasworld.clusters[clusternum];
00295     for (i = 0; i < cluster->numportals; i++)
00296     {
00297         portalnum = aasworld.portalindex[cluster->firstportal + i];
00298         portal = &aasworld.portals[portalnum];
00299         if (portal->frontcluster == clusternum)
00300         {
00301             portal->clusterareanum[0] = cluster->numareas++;
00302         } //end if
00303         else
00304         {
00305             portal->clusterareanum[1] = cluster->numareas++;
00306         } //end else
00307     } //end for
00308 } //end of the function AAS_NumberClusterPortals

void AAS_RemoveAllPortals void   ) 
 

Definition at line 937 of file be_aas_cluster.c.

References aasworld, aas_s::areasettings, aas_areasettings_s::contents, i, and aas_s::numareas.

00938 {
00939     int i;
00940 
00941