⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aas_create.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 3 页
字号:

	//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 + -