示例#1
0
/*
============
idBrush::Subtract
============
*/
bool idBrush::Subtract( const idBrush* b, idBrushList& list ) const
{
	int i;
	idBrush* front, *back;
	const idBrush* in;
	
	list.Clear();
	in = this;
	for( i = 0; i < b->sides.Num() && in; i++ )
	{
	
		in->Split( b->sides[i]->plane, b->sides[i]->planeNum, &front, &back );
		
		if( in != this )
		{
			delete in;
		}
		if( front )
		{
			list.AddToTail( front );
		}
		in = back;
	}
	// if didn't really intersect
	if( !in )
	{
		list.Free();
		return false;
	}
	
	delete in;
	return true;
}
/*
============
idAASBuild::ClipBrushSidesWithProcBSP
============
*/
void idAASBuild::ClipBrushSidesWithProcBSP( idBrushList &brushList ) {
	int i, clippedSides;
	idBrush *brush;
	idFixedWinding neww;
	idBounds bounds;
	float radius;
	idVec3 origin;
	// if the .proc file has no BSP tree
	if( idAASBuild::procNodes == NULL ) {
		return;
	}
	clippedSides = 0;
	for( brush = brushList.Head(); brush; brush = brush->Next() ) {
		for( i = 0; i < brush->GetNumSides(); i++ ) {
			if( !brush->GetSide( i )->GetWinding() ) {
				continue;
			}
			// make a local copy of the winding
			neww = *brush->GetSide( i )->GetWinding();
			neww.GetBounds( bounds );
			origin = ( bounds[1] - bounds[0] ) * 0.5f;
			radius = origin.Length() + ON_EPSILON;
			origin = bounds[0] + origin;
			if( ChoppedAwayByProcBSP( 0, &neww, brush->GetSide( i )->GetPlane().Normal(), origin, radius ) ) {
				brush->GetSide( i )->SetFlag( SFL_USED_SPLITTER );
				clippedSides++;
			}
		}
	}
	common->Printf( "%6d brush sides clipped\n", clippedSides );
}
/*
============
idAASBuild::AddBrushesForMapFile
============
*/
idBrushList idAASBuild::AddBrushesForMapFile( const idMapFile *mapFile, idBrushList brushList ) {
	int i;
	common->Printf( "[Brush Load]\n" );
	brushList = AddBrushesForMapEntity( mapFile->GetEntity( 0 ), 0, brushList );
	for( i = 1; i < mapFile->GetNumEntities(); i++ ) {
		const char *classname = mapFile->GetEntity( i )->epairs.GetString( "classname" );
		if( idStr::Icmp( classname, "func_aas_obstacle" ) == 0 ) {
			brushList = AddBrushesForMapEntity( mapFile->GetEntity( i ), i, brushList );
		}
	}
	common->Printf( "%6d brushes\n", brushList.Num() );
	return brushList;
}
示例#4
0
/*
============
idBrushList::Split
============
*/
void idBrushList::Split( const idPlane& plane, int planeNum, idBrushList& frontList, idBrushList& backList, bool useBrushSavedPlaneSide )
{
	idBrush* b, *front, *back;
	
	frontList.Clear();
	backList.Clear();
	
	if( !useBrushSavedPlaneSide )
	{
		for( b = head; b; b = b->next )
		{
			b->Split( plane, planeNum, &front, &back );
			if( front )
			{
				frontList.AddToTail( front );
			}
			if( back )
			{
				backList.AddToTail( back );
			}
		}
		return;
	}
	
	for( b = head; b; b = b->next )
	{
		if( b->savedPlaneSide & BRUSH_PLANESIDE_BOTH )
		{
			b->Split( plane, planeNum, &front, &back );
			if( front )
			{
				frontList.AddToTail( front );
			}
			if( back )
			{
				backList.AddToTail( back );
			}
		}
		else if( b->savedPlaneSide & BRUSH_PLANESIDE_FRONT )
		{
			frontList.AddToTail( b->Copy() );
		}
		else
		{
			backList.AddToTail( b->Copy() );
		}
	}
}
示例#5
0
/*
============
idBrushMap::WriteBrushList
============
*/
void idBrushMap::WriteBrushList( const idBrushList& brushList )
{
	idBrush* b;
	
	if( !fp )
	{
		return;
	}
	
	for( b = brushList.Head(); b; b = b->Next() )
	{
		WriteBrush( b );
	}
}
/*
============
idAASBuild::AddBrushForMapBrush
============
*/
idBrushList idAASBuild::AddBrushesForMapBrush( const idMapBrush* mapBrush, const idVec3& origin, const idMat3& axis, int entityNum, int primitiveNum, idBrushList brushList )
{
	int contents, i;
	idMapBrushSide* mapSide;
	const idMaterial* mat;
	idList<idBrushSide*> sideList;
	idBrush* brush;
	idPlane plane;
	
	contents = 0;
	for( i = 0; i < mapBrush->GetNumSides(); i++ )
	{
		mapSide = mapBrush->GetSide( i );
		mat = declManager->FindMaterial( mapSide->GetMaterial() );
		contents |= mat->GetContentFlags();
		plane = mapSide->GetPlane();
		plane.FixDegeneracies( DEGENERATE_DIST_EPSILON );
		sideList.Append( new idBrushSide( plane, -1 ) );
	}
	
	contents = ContentsForAAS( contents );
	if( !contents )
	{
		for( i = 0; i < sideList.Num(); i++ )
		{
			delete sideList[i];
		}
		return brushList;
	}
	
	brush = new idBrush();
	brush->SetContents( contents );
	
	if( !brush->FromSides( sideList ) )
	{
		common->Warning( "brush primitive %d on entity %d is degenerate", primitiveNum, entityNum );
		delete brush;
		return brushList;
	}
	
	brush->SetEntityNum( entityNum );
	brush->SetPrimitiveNum( primitiveNum );
	brush->Transform( origin, axis );
	brushList.AddToTail( brush );
	
	return brushList;
}
/*
============
idAASBuild::AddBrushesForPatch
============
*/
idBrushList idAASBuild::AddBrushesForMapPatch( const idMapPatch* mapPatch, const idVec3& origin, const idMat3& axis, int entityNum, int primitiveNum, idBrushList brushList )
{
	int i, j, contents, validBrushes;
	float dot;
	int v1, v2, v3, v4;
	idFixedWinding w;
	idPlane plane;
	idVec3 d1, d2;
	idBrush* brush;
	idSurface_Patch mesh;
	const idMaterial* mat;
	
	mat = declManager->FindMaterial( mapPatch->GetMaterial() );
	contents = ContentsForAAS( mat->GetContentFlags() );
	
	if( !contents )
	{
		return brushList;
	}
	
	mesh = idSurface_Patch( *mapPatch );
	
	// if the patch has an explicit number of subdivisions use it to avoid cracks
	if( mapPatch->GetExplicitlySubdivided() )
	{
		mesh.SubdivideExplicit( mapPatch->GetHorzSubdivisions(), mapPatch->GetVertSubdivisions(), false, true );
	}
	else
	{
		mesh.Subdivide( DEFAULT_CURVE_MAX_ERROR_CD, DEFAULT_CURVE_MAX_ERROR_CD, DEFAULT_CURVE_MAX_LENGTH_CD, false );
	}
	
	validBrushes = 0;
	
	for( i = 0; i < mesh.GetWidth() - 1; i++ )
	{
		for( j = 0; j < mesh.GetHeight() - 1; j++ )
		{
		
			v1 = j * mesh.GetWidth() + i;
			v2 = v1 + 1;
			v3 = v1 + mesh.GetWidth() + 1;
			v4 = v1 + mesh.GetWidth();
			
			d1 = mesh[v2].xyz - mesh[v1].xyz;
			d2 = mesh[v3].xyz - mesh[v1].xyz;
			plane.SetNormal( d1.Cross( d2 ) );
			if( plane.Normalize() != 0.0f )
			{
				plane.FitThroughPoint( mesh[v1].xyz );
				dot = plane.Distance( mesh[v4].xyz );
				// if we can turn it into a quad
				if( idMath::Fabs( dot ) < 0.1f )
				{
					w.Clear();
					w += mesh[v1].xyz;
					w += mesh[v2].xyz;
					w += mesh[v3].xyz;
					w += mesh[v4].xyz;
					
					brush = new idBrush();
					brush->SetContents( contents );
					if( brush->FromWinding( w, plane ) )
					{
						brush->SetEntityNum( entityNum );
						brush->SetPrimitiveNum( primitiveNum );
						brush->SetFlag( BFL_PATCH );
						brush->Transform( origin, axis );
						brushList.AddToTail( brush );
						validBrushes++;
					}
					else
					{
						delete brush;
					}
					continue;
				}
				else
				{
					// create one of the triangles
					w.Clear();
					w += mesh[v1].xyz;
					w += mesh[v2].xyz;
					w += mesh[v3].xyz;
					
					brush = new idBrush();
					brush->SetContents( contents );
					if( brush->FromWinding( w, plane ) )
					{
						brush->SetEntityNum( entityNum );
						brush->SetPrimitiveNum( primitiveNum );
						brush->SetFlag( BFL_PATCH );
						brush->Transform( origin, axis );
						brushList.AddToTail( brush );
						validBrushes++;
					}
					else
					{
						delete brush;
					}
				}
			}
			// create the other triangle
			d1 = mesh[v3].xyz - mesh[v1].xyz;
			d2 = mesh[v4].xyz - mesh[v1].xyz;
			plane.SetNormal( d1.Cross( d2 ) );
			if( plane.Normalize() != 0.0f )
			{
				plane.FitThroughPoint( mesh[v1].xyz );
				
				w.Clear();
				w += mesh[v1].xyz;
				w += mesh[v3].xyz;
				w += mesh[v4].xyz;
				
				brush = new idBrush();
				brush->SetContents( contents );
				if( brush->FromWinding( w, plane ) )
				{
					brush->SetEntityNum( entityNum );
					brush->SetPrimitiveNum( primitiveNum );
					brush->SetFlag( BFL_PATCH );
					brush->Transform( origin, axis );
					brushList.AddToTail( brush );
					validBrushes++;
				}
				else
				{
					delete brush;
				}
			}
		}
	}
	
	if( !validBrushes )
	{
		common->Warning( "patch primitive %d on entity %d is completely degenerate", primitiveNum, entityNum );
	}
	
	return brushList;
}