📄 aas_create.c
字号:
//recurse down to leafs
if (node->planenum != PLANENUM_LEAF)
{
//the first tmp node is a dummy
tmpnode = AAS_AllocTmpNode();
tmpnode->planenum = node->planenum;
tmpnode->children[0] = AAS_CreateAreas_r(node->children[0]);
tmpnode->children[1] = AAS_CreateAreas_r(node->children[1]);
return tmpnode;
} //end if
//areas won't be created for solid leafs
if (node->contents & CONTENTS_SOLID)
{
//just return zero for a solid leaf (in tmp AAS NULL is a solid leaf)
return NULL;
} //end if
return AAS_CreateArea(node);
} //end of the function AAS_CreateAreas_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_CreateAreas(node_t *node)
{
Log_Write("AAS_CreateAreas\r\n");
qprintf("%6d areas created", 0);
tmpaasworld.nodes = AAS_CreateAreas_r(node);
qprintf("\n");
Log_Write("%6d areas created\r\n", tmpaasworld.numareas);
} //end of the function AAS_CreateAreas
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_PrintNumGroundFaces(void)
{
tmp_face_t *tmpface;
int numgroundfaces = 0;
for (tmpface = tmpaasworld.faces; tmpface; tmpface = tmpface->l_next)
{
if (tmpface->faceflags & FACE_GROUND)
{
numgroundfaces++;
} //end if
} //end for
qprintf("%6d ground faces\n", numgroundfaces);
} //end of the function AAS_PrintNumGroundFaces
//===========================================================================
// checks the number of shared faces between the given two areas
// since areas are convex they should only have ONE shared face
// however due to crappy face merging there are sometimes several
// shared faces
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_CheckAreaSharedFaces(tmp_area_t *tmparea1, tmp_area_t *tmparea2)
{
int numsharedfaces, side;
tmp_face_t *face1, *sharedface;
if (tmparea1->invalid || tmparea2->invalid) return;
sharedface = NULL;
numsharedfaces = 0;
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
{
side = face1->frontarea != tmparea1;
if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
{
sharedface = face1;
numsharedfaces++;
} //end if
} //end if
if (!sharedface) return;
//the areas should only have one shared face
if (numsharedfaces > 1)
{
Log_Write("---- tmp area %d and %d have %d shared faces\r\n",
tmparea1->areanum, tmparea2->areanum, numsharedfaces);
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
{
side = face1->frontarea != tmparea1;
if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
{
Log_Write("face %d, planenum = %d, face->frontarea = %d face->backarea = %d\r\n",
face1->num, face1->planenum, face1->frontarea->areanum, face1->backarea->areanum);
} //end if
} //end if
} //end if
} //end of the function AAS_CheckAreaSharedFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_CheckSharedFaces(void)
{
tmp_area_t *tmparea1, *tmparea2;
for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next)
{
for (tmparea2 = tmpaasworld.areas; tmparea2; tmparea2 = tmparea2->l_next)
{
if (tmparea1 == tmparea2) continue;
AAS_CheckAreaSharedFaces(tmparea1, tmparea2);
} //end for
} //end for
} //end of the function AAS_CheckSharedFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_FlipFace(tmp_face_t *face)
{
tmp_area_t *frontarea, *backarea;
winding_t *w;
frontarea = face->frontarea;
backarea = face->backarea;
//must have an area at both sides before flipping is allowed
if (!frontarea || !backarea) return;
//flip the face winding
w = face->winding;
face->winding = ReverseWinding(w);
FreeWinding(w);
//flip the face plane
face->planenum ^= 1;
//flip the face areas
AAS_RemoveFaceFromArea(face, frontarea);
AAS_RemoveFaceFromArea(face, backarea);
AAS_AddFaceSideToArea(face, 1, frontarea);
AAS_AddFaceSideToArea(face, 0, backarea);
} //end of the function AAS_FlipFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
/*
void AAS_FlipAreaSharedFaces(tmp_area_t *tmparea1, tmp_area_t *tmparea2)
{
int numsharedfaces, side, area1facing, area2facing;
tmp_face_t *face1, *sharedface;
if (tmparea1->invalid || tmparea2->invalid) return;
sharedface = NULL;
numsharedfaces = 0;
area1facing = 0; //number of shared faces facing towards area 1
area2facing = 0; //number of shared faces facing towards area 2
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
{
side = face1->frontarea != tmparea1;
if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
{
sharedface = face1;
numsharedfaces++;
if (face1->frontarea == tmparea1) area1facing++;
else area2facing++;
} //end if
} //end if
if (!sharedface) return;
//if there's only one shared face
if (numsharedfaces <= 1) return;
//if all the shared faces are facing to the same area
if (numsharedfaces == area1facing || numsharedfaces == area2facing) return;
//
do
{
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side])
{
side = face1->frontarea != tmparea1;
if (face1->backarea == tmparea2 || face1->frontarea == tmparea2)
{
if (face1->frontarea != tmparea1)
{
AAS_FlipFace(face1);
break;
} //end if
} //end if
} //end for
} while(face1);
} //end of the function AAS_FlipAreaSharedFaces
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_FlipSharedFaces(void)
{
int i;
tmp_area_t *tmparea1, *tmparea2;
i = 0;
qprintf("%6d areas checked for shared face flipping", i);
for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next)
{
if (tmparea1->invalid) continue;
for (tmparea2 = tmpaasworld.areas; tmparea2; tmparea2 = tmparea2->l_next)
{
if (tmparea2->invalid) continue;
if (tmparea1 == tmparea2) continue;
AAS_FlipAreaSharedFaces(tmparea1, tmparea2);
} //end for
qprintf("\r%6d", ++i);
} //end for
Log_Print("\r%6d areas checked for shared face flipping\n", i);
} //end of the function AAS_FlipSharedFaces
*/
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_FlipSharedFaces(void)
{
int i, side1, side2;
tmp_area_t *tmparea1;
tmp_face_t *face1, *face2;
i = 0;
qprintf("%6d areas checked for shared face flipping", i);
for (tmparea1 = tmpaasworld.areas; tmparea1; tmparea1 = tmparea1->l_next)
{
if (tmparea1->invalid) continue;
for (face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1])
{
side1 = face1->frontarea != tmparea1;
if (!face1->frontarea || !face1->backarea) continue;
//
for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
{
side2 = face2->frontarea != tmparea1;
if (!face2->frontarea || !face2->backarea) continue;
//
if (face1->frontarea == face2->backarea &&
face1->backarea == face2->frontarea)
{
AAS_FlipFace(face2);
} //end if
//recheck side
side2 = face2->frontarea != tmparea1;
} //end for
} //end for
qprintf("\r%6d", ++i);
} //end for
qprintf("\n");
Log_Write("%6d areas checked for shared face flipping\r\n", i);
} //end of the function AAS_FlipSharedFaces
//===========================================================================
// creates an .AAS file with the given name
// a MAP should be loaded before calling this
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Create(char *aasfile)
{
entity_t *e;
tree_t *tree;
double start_time;
//for a possible leak file
strcpy(source, aasfile);
StripExtension(source);
//the time started
start_time = I_FloatTime();
//set the default number of threads (depends on number of processors)
ThreadSetDefault();
//set the global entity number to the world model
entity_num = 0;
//the world entity
e = &entities[entity_num];
//process the whole world
tree = ProcessWorldBrushes(e->firstbrush, e->firstbrush + e->numbrushes);
//if the conversion is cancelled
if (cancelconversion)
{
Tree_Free(tree);
return;
} //end if
//display BSP tree creation time
Log_Print("BSP tree created in %5.0f seconds\n", I_FloatTime() - start_time);
//prune the bsp tree
Tree_PruneNodes(tree->headnode);
//if the conversion is cancelled
if (cancelconversion)
{
Tree_Free(tree);
return;
} //end if
//create the tree portals
MakeTreePortals(tree);
//if the conversion is cancelled
if (cancelconversion)
{
Tree_Free(tree);
return;
} //end if
//Marks all nodes that can be reached by entites
if (FloodEntities(tree))
{
//fill out nodes that can't be reached
FillOutside(tree->headnode);
} //end if
else
{
LeakFile(tree);
Error("**** leaked ****\n");
return;
} //end else
//create AAS from the BSP tree
//==========================================
//initialize tmp aas
AAS_InitTmpAAS();
//create the convex areas from the leaves
AAS_CreateAreas(tree->headnode);
//free the BSP tree because it isn't used anymore
if (freetree) Tree_Free(tree);
//try to merge area faces
AAS_MergeAreaFaces();
//do gravitational subdivision
AAS_GravitationalSubdivision();
//merge faces if possible
AAS_MergeAreaFaces();
AAS_RemoveAreaFaceColinearPoints();
//merge areas if possible
AAS_MergeAreas();
//NOTE: prune nodes directly after area merging
AAS_PruneNodes();
//flip shared faces so they are all facing to the same area
AAS_FlipSharedFaces();
AAS_RemoveAreaFaceColinearPoints();
//merge faces if possible
AAS_MergeAreaFaces();
//merge area faces in the same plane
AAS_MergeAreaPlaneFaces();
//do ladder subdivision
AAS_LadderSubdivision();
//FIXME: melting is buggy
AAS_MeltAreaFaceWindings();
//remove tiny faces
AAS_RemoveTinyFaces();
//create area settings
AAS_CreateAreaSettings();
//check if the winding plane is equal to the face plane
//AAS_CheckAreaWindingPlanes();
//
//AAS_CheckSharedFaces();
//==========================================
//if the conversion is cancelled
if (cancelconversion)
{
Tree_Free(tree);
AAS_FreeTmpAAS();
return;
} //end if
//store the created AAS stuff in the AAS file format and write the file
AAS_StoreFile(aasfile);
//free the temporary AAS memory
AAS_FreeTmpAAS();
//display creation time
Log_Print("\nAAS created in %5.0f seconds\n", I_FloatTime() - start_time);
} //end of the function AAS_Create
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -