/*
===================
idRenderWorldLocal::FloodFrustumAreas_r
===================
*/
areaNumRef_t *idRenderWorldLocal::FloodFrustumAreas_r(const idFrustum &frustum, const int areaNum, const idBounds &bounds, areaNumRef_t *areas)
{
	portal_t *p;
	portalArea_t *portalArea;
	idBounds newBounds;
	areaNumRef_t *a;

	portalArea = &portalAreas[ areaNum ];

	// go through all the portals
	for (p = portalArea->portals; p; p = p->next) {

		// check if we already visited the area the portal leads to
		for (a = areas; a; a = a->next) {
			if (a->areaNum == p->intoArea) {
				break;
			}
		}

		if (a) {
			continue;
		}

		// the frustum origin must be at the front of the portal plane
		if (p->plane.Side(frustum.GetOrigin(), 0.1f) == SIDE_BACK) {
			continue;
		}

		// the frustum must cross the portal plane
		if (frustum.PlaneSide(p->plane, 0.0f) != PLANESIDE_CROSS) {
			continue;
		}

		// get the bounds for the portal winding projected in the frustum
		frustum.ProjectionBounds(*p->w, newBounds);

		newBounds.IntersectSelf(bounds);

		if (newBounds[0][0] > newBounds[1][0] || newBounds[0][1] > newBounds[1][1] || newBounds[0][2] > newBounds[1][2]) {
			continue;
		}

		newBounds[1][0] = frustum.GetFarDistance();

		a = areaNumRefAllocator.Alloc();
		a->areaNum = p->intoArea;
		a->next = areas;
		areas = a;

		areas = FloodFrustumAreas_r(frustum, p->intoArea, newBounds, areas);
	}

	return areas;
}
Exemple #2
0
/*
===================
idRenderWorldLocal::FloodFrustumAreas

  Retrieves all the portal areas the frustum floods into where the frustum starts in the given areas.
  All portals are assumed to be open.
===================
*/
areaNumRef_t *idRenderWorldLocal::FloodFrustumAreas( const idFrustum &frustum, areaNumRef_t *areas ) {
	idBounds bounds;
	areaNumRef_t *a;

	// bounds that cover the whole frustum
	bounds[0].Set( frustum.GetNearDistance(), -1.0f, -1.0f );
	bounds[1].Set( frustum.GetFarDistance(), 1.0f, 1.0f );

	for ( a = areas; a; a = a->next ) {
		areas = FloodFrustumAreas_r( frustum, a->areaNum, bounds, areas );
	}

	return areas;
}