Exemplo n.º 1
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
int AAS_FindClusters(void)
{
	int i;
	aas_cluster_t *cluster;

	AAS_RemoveClusterAreas();
	//
	for (i = 1; i < aasworld.numareas; i++)
	{
		//if the area is already part of a cluster
		if (aasworld.areasettings[i].cluster)
			continue;
		// if not flooding through faces only use areas that have reachabilities
		if (nofaceflood)
		{
			if (!aasworld.areasettings[i].numreachableareas)
				continue;
		} //end if
		//if the area is a cluster portal
		if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
			continue;
		if (aasworld.numclusters >= AAS_MAX_CLUSTERS)
		{
			AAS_Error("AAS_MAX_CLUSTERS");
			return qfalse;
		} //end if
		cluster = &aasworld.clusters[aasworld.numclusters];
		cluster->numareas = 0;
		cluster->numreachabilityareas = 0;
		cluster->firstportal = aasworld.portalindexsize;
		cluster->numportals = 0;
		//flood the areas in this cluster
		if (!AAS_FloodClusterAreas_r(i, aasworld.numclusters))
			return qfalse;
		if (!AAS_FloodClusterAreasUsingReachabilities(aasworld.numclusters))
			return qfalse;
		//number the cluster areas
		//AAS_NumberClusterPortals(aasworld.numclusters);
		AAS_NumberClusterAreas(aasworld.numclusters);
		//Log_Write("cluster %d has %d areas\r\n", aasworld.numclusters, cluster->numareas);
		aasworld.numclusters++;
	} //end for
	return qtrue;
} //end of the function AAS_FindClusters
Exemplo n.º 2
0
//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
void AAS_RemoveNonGrounded(void)
{
	int             i, j;
	optimized_t     optimized;
	int             removed = 0, valid = 0, numoriginalareas;
	int             validreach = 0;
	aas_face_t     *face;

	AAS_RemoveNonReachabilityAlloc(&optimized);
	// mark portal areas as non-removable
	if(aasworld->numportals)
	{
		for(i = 0; i < aasworld->numportals; i++)
		{
			optimized.areakeep[aasworld->portals[i].areanum] = qtrue;
		}
	}
	// remove non-reachability areas
	numoriginalareas = aasworld->numareas;
	for(i = 1; i < (*aasworld).numareas; i++)
	{
		// is this a grounded area?
		if(optimized.areakeep[i] || (aasworld->areasettings[i].areaflags & (AREA_GROUNDED | AREA_LADDER)))
		{
			optimized.arearemap[i] = ++valid;
			// copy it to the optimized areas
			optimized.areas[valid] = (*aasworld).areas[i];
			optimized.areas[valid].areanum = valid;
			continue;
		}
		// yes it is if it made it to here
		removed++;
		optimized.removedareas[i] = qtrue;
	}
	optimized.numareas = valid + 1;
	// store the new areas
	if((*aasworld).areas)
	{
		FreeMemory((*aasworld).areas);
	}
	(*aasworld).areas = optimized.areas;
	(*aasworld).numareas = optimized.numareas;
	//
	// remove reachabilities that are no longer required
	validreach = 1;
	for(i = 1; i < aasworld->reachabilitysize; i++)
	{
		optimized.reachabilityremap[i] = validreach;
		if(optimized.removedareas[aasworld->reachability[i].areanum])
		{
			continue;
		}
		// save this reachability
		optimized.reachability[validreach] = aasworld->reachability[i];
		optimized.reachability[validreach].areanum = optimized.arearemap[optimized.reachability[validreach].areanum];
		//
		validreach++;
	}
	optimized.reachabilitysize = validreach;
	// store the reachabilities
	if((*aasworld).reachability)
	{
		FreeMemory((*aasworld).reachability);
	}
	(*aasworld).reachability = optimized.reachability;
	(*aasworld).reachabilitysize = optimized.reachabilitysize;
	//
	// remove and update areasettings
	for(i = 1; i < numoriginalareas; i++)
	{
		if(optimized.removedareas[i])
		{
			continue;
		}
		j = optimized.arearemap[i];
		optimized.areasettings[j] = aasworld->areasettings[i];
		optimized.areasettings[j].firstreachablearea = optimized.reachabilityremap[aasworld->areasettings[i].firstreachablearea];
		optimized.areasettings[j].numreachableareas =
			1 + optimized.reachabilityremap[aasworld->areasettings[i].firstreachablearea +
											aasworld->areasettings[i].numreachableareas - 1] -
			optimized.areasettings[j].firstreachablearea;
	}
	//
	// update faces (TODO: remove unused)
	for(i = 1, face = &aasworld->faces[1]; i < aasworld->numfaces; i++, face++)
	{
		if(!optimized.removedareas[face->backarea])
		{
			face->backarea = optimized.arearemap[face->backarea];
		}
		else
		{						// now points to a void
			face->backarea = 0;
		}
		if(!optimized.removedareas[face->frontarea])
		{
			face->frontarea = optimized.arearemap[face->frontarea];
		}
		else
		{
			face->frontarea = 0;
		}
	}
	// store the areasettings
	if((*aasworld).areasettings)
	{
		FreeMemory((*aasworld).areasettings);
	}
	(*aasworld).areasettings = optimized.areasettings;
	(*aasworld).numareasettings = optimized.numareas;
	//
	// update nodes
	for(i = 1; i < (*aasworld).numnodes; i++)
	{
		for(j = 0; j < 2; j++)
		{
			if(aasworld->nodes[i].children[j] < 0)
			{
				if(optimized.removedareas[-aasworld->nodes[i].children[j]])
				{
					aasworld->nodes[i].children[j] = 0;	//make it solid
				}
				else
				{				// remap
					aasworld->nodes[i].children[j] = -optimized.arearemap[-aasworld->nodes[i].children[j]];
				}
			}
		}
	}
	//
	// update portal areanums
	for(i = 0; i < aasworld->numportals; i++)
	{
		aasworld->portals[i].areanum = optimized.arearemap[aasworld->portals[i].areanum];
	}
	// update clusters and portals
	for(i = 0; i < (*aasworld).numclusters; i++)
	{
		AAS_NumberClusterAreas(i);
	}
	// free temporary memory
	FreeMemory(optimized.areakeep);
	FreeMemory(optimized.arearemap);
	FreeMemory(optimized.removedareas);
	FreeMemory(optimized.reachabilityremap);
	//print some nice stuff :)
	botimport.Print(PRT_MESSAGE, "%i non-grounded areas removed, %i remain.\n", removed, valid);
}								//end of the function AAS_Optimize