Code Search for Developers
 
 
  

aas_gsubdiv.c from Nxabega at Krugle


Show aas_gsubdiv.c syntax highlighted

/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.

This file is part of Quake III Arena source code.

Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/

#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
#include "aas_store.h"
#include "aas_cfg.h"

#define FACECLIP_EPSILON			0.2
#define FACE_EPSILON					1.0

int             numgravitationalsubdivisions = 0;
int             numladdersubdivisions = 0;

//NOTE: only do gravitational subdivision BEFORE area merging!!!!!!!
//          because the bsp tree isn't refreshes like with ladder subdivision

//===========================================================================
// NOTE: the original face is invalid after splitting
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
void AAS_SplitFace(tmp_face_t * face, vec3_t normal, float dist, tmp_face_t ** frontface, tmp_face_t ** backface)
{
	winding_t      *frontw, *backw;

	//
	*frontface = *backface = NULL;

	ClipWindingEpsilon(face->winding, normal, dist, FACECLIP_EPSILON, &frontw, &backw);

#ifdef DEBUG
	//
	if(frontw)
	{
		if(WindingIsTiny(frontw))
		{
			Log_Write("AAS_SplitFace: tiny back face\r\n");
			FreeWinding(frontw);
			frontw = NULL;
		}						//end if
	}							//end if
	if(backw)
	{
		if(WindingIsTiny(backw))
		{
			Log_Write("AAS_SplitFace: tiny back face\r\n");
			FreeWinding(backw);
			backw = NULL;
		}						//end if
	}							//end if
#endif							//DEBUG
	//if the winding was split
	if(frontw)
	{
		//check bounds
		(*frontface) = AAS_AllocTmpFace();
		(*frontface)->planenum = face->planenum;
		(*frontface)->winding = frontw;
		(*frontface)->faceflags = face->faceflags;
	}							//end if
	if(backw)
	{
		//check bounds
		(*backface) = AAS_AllocTmpFace();
		(*backface)->planenum = face->planenum;
		(*backface)->winding = backw;
		(*backface)->faceflags = face->faceflags;
	}							//end if
}								//end of the function AAS_SplitFace

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
winding_t      *AAS_SplitWinding(tmp_area_t * tmparea, int planenum)
{
	tmp_face_t     *face;
	plane_t        *plane;
	int             side;
	winding_t      *splitwinding;

	//
	plane = &mapplanes[planenum];
	//create a split winding, first base winding for plane
	splitwinding = BaseWindingForPlane(plane->normal, plane->dist);
	//chop with all the faces of the area
	for(face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
	{
		//side of the face the original area was on
		side = face->frontarea != tmparea;
		plane = &mapplanes[face->planenum ^ side];
		ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0);	// PLANESIDE_EPSILON);
	}							//end for
	return splitwinding;
}								//end of the function AAS_SplitWinding

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
int AAS_TestSplitPlane(tmp_area_t * tmparea, vec3_t normal, float dist, int *facesplits, int *groundsplits, int *epsilonfaces)
{
	int             j, side, front, back, planenum;
	float           d, d_front, d_back;
	tmp_face_t     *face;
	winding_t      *w;

	*facesplits = *groundsplits = *epsilonfaces = 0;

	planenum = FindFloatPlane(normal, dist);

	w = AAS_SplitWinding(tmparea, planenum);
	if(!w)
		return false;
	FreeWinding(w);
	//
	for(face = tmparea->tmpfaces; face; face = face->next[side])
	{
		//side of the face the area is on
		side = face->frontarea != tmparea;

		if((face->planenum & ~1) == (planenum & ~1))
		{
			Log_Print("AAS_TestSplitPlane: tried face plane as splitter\n");
			return false;
		}						//end if
		w = face->winding;
		//reset distance at front and back side of plane
		d_front = d_back = 0;
		//reset front and back flags
		front = back = 0;
		for(j = 0; j < w->numpoints; j++)
		{
			d = DotProduct(w->p[j], normal) - dist;
			if(d > d_front)
				d_front = d;
			if(d < d_back)
				d_back = d;

			if(d > 0.4)			// PLANESIDE_EPSILON)
				front = 1;
			if(d < -0.4)		// PLANESIDE_EPSILON)
				back = 1;
		}						//end for
		//check for an epsilon face
		if((d_front > FACECLIP_EPSILON && d_front < FACE_EPSILON) || (d_back < -FACECLIP_EPSILON && d_back > -FACE_EPSILON))
		{
			(*epsilonfaces)++;
		}						//end if
		//if the face has points at both sides of the plane
		if(front && back)
		{
			(*facesplits)++;
			if(face->faceflags & FACE_GROUND)
			{
				(*groundsplits)++;
			}					//end if
		}						//end if
	}							//end for
	return true;
}								//end of the function AAS_TestSplitPlane

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
void AAS_SplitArea(tmp_area_t * tmparea, int planenum, tmp_area_t ** frontarea, tmp_area_t ** backarea)
{
	int             side;
	tmp_area_t     *facefrontarea, *facebackarea, *faceotherarea;
	tmp_face_t     *face, *frontface, *backface, *splitface, *nextface;
	winding_t      *splitwinding;
	plane_t        *splitplane;

/*
#ifdef AW_DEBUG
	int facesplits, groundsplits, epsilonface;
	Log_Print("\n----------------------\n");
	Log_Print("splitting area %d\n", areanum);
	Log_Print("with normal = \'%f %f %f\', dist = %f\n", normal[0], normal[1], normal[2], dist);
	AAS_TestSplitPlane(areanum, normal, dist,
										&facesplits, &groundsplits, &epsilonface);
	Log_Print("face splits = %d\nground splits = %d\n", facesplits, groundsplits);
	if (epsilonface) Log_Print("aaahh epsilon face\n");
#endif //AW_DEBUG*/
	//the original area

	AAS_FlipAreaFaces(tmparea);
	AAS_CheckArea(tmparea);
	//
	splitplane = &mapplanes[planenum];
/*	//create a split winding, first base winding for plane
	splitwinding = BaseWindingForPlane(splitplane->normal, splitplane->dist);
	//chop with all the faces of the area
	for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
	{
		//side of the face the original area was on
		side = face->frontarea != tmparea->areanum;
		plane = &mapplanes[face->planenum ^ side];
		ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
	} //end for*/
	splitwinding = AAS_SplitWinding(tmparea, planenum);
	if(!splitwinding)
	{
/*
#ifdef DEBUG
		AAS_TestSplitPlane(areanum, normal, dist,
											&facesplits, &groundsplits, &epsilonface);
		Log_Print("\nface splits = %d\nground splits = %d\n", facesplits, groundsplits);
		if (epsilonface) Log_Print("aaahh epsilon face\n");
#endif //DEBUG*/
		Error("AAS_SplitArea: no split winding when splitting area %d\n", tmparea->areanum);
	}							//end if
	//create a split face
	splitface = AAS_AllocTmpFace();
	//get the map plane
	splitface->planenum = planenum;
	//store the split winding
	splitface->winding = splitwinding;
	//the new front area
	(*frontarea) = AAS_AllocTmpArea();
	(*frontarea)->presencetype = tmparea->presencetype;
	(*frontarea)->contents = tmparea->contents;
	(*frontarea)->modelnum = tmparea->modelnum;
	(*frontarea)->tmpfaces = NULL;
	//the new back area
	(*backarea) = AAS_AllocTmpArea();
	(*backarea)->presencetype = tmparea->presencetype;
	(*backarea)->contents = tmparea->contents;
	(*backarea)->modelnum = tmparea->modelnum;
	(*backarea)->tmpfaces = NULL;
	//add the split face to the new areas
	AAS_AddFaceSideToArea(splitface, 0, (*frontarea));
	AAS_AddFaceSideToArea(splitface, 1, (*backarea));

	//split all the faces of the original area
	for(face = tmparea->tmpfaces; face; face = nextface)
	{
		//side of the face the original area was on
		side = face->frontarea != tmparea;
		//next face of the original area
		nextface = face->next[side];
		//front area of the face
		facefrontarea = face->frontarea;
		//back area of the face
		facebackarea = face->backarea;
		//remove the face from both the front and back areas
		if(facefrontarea)
			AAS_RemoveFaceFromArea(face, facefrontarea);
		if(facebackarea)
			AAS_RemoveFaceFromArea(face, facebackarea);
		//split the face
		AAS_SplitFace(face, splitplane->normal, splitplane->dist, &frontface, &backface);
		//free the original face
		AAS_FreeTmpFace(face);
		//get the number of the area at the other side of the face
		if(side)
			faceotherarea = facefrontarea;
		else
			faceotherarea = facebackarea;
		//if there is an area at the other side of the original face
		if(faceotherarea)
		{
			if(frontface)
				AAS_AddFaceSideToArea(frontface, !side, faceotherarea);
			if(backface)
				AAS_AddFaceSideToArea(backface, !side, faceotherarea);
		}						//end if
		//add the front and back part left after splitting the original face to the new areas
		if(frontface)
			AAS_AddFaceSideToArea(frontface, side, (*frontarea));
		if(backface)
			AAS_AddFaceSideToArea(backface, side, (*backarea));
	}							//end for

	if(!(*frontarea)->tmpfaces)
		Log_Print("AAS_SplitArea: front area without faces\n");
	if(!(*backarea)->tmpfaces)
		Log_Print("AAS_SplitArea: back area without faces\n");

	tmparea->invalid = true;
/*
#ifdef AW_DEBUG
	for (i = 0, face = frontarea->tmpfaces; face; face = face->next[side])
	{
		side = face->frontarea != frontarea->areanum;
		i++;
	} //end for
	Log_Print("created front area %d with %d faces\n", frontarea->areanum, i);

	for (i = 0, face = backarea->tmpfaces; face; face = face->next[side])
	{
		side = face->frontarea != backarea->areanum;
		i++;
	} //end for
	Log_Print("created back area %d with %d faces\n", backarea->areanum, i);
#endif //AW_DEBUG*/

	AAS_FlipAreaFaces((*frontarea));
	AAS_FlipAreaFaces((*backarea));
	//
	AAS_CheckArea((*frontarea));
	AAS_CheckArea((*backarea));
}								//end of the function AAS_SplitArea

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
int AAS_FindBestAreaSplitPlane(tmp_area_t * tmparea, vec3_t normal, float *dist)
{
	int             side1, side2;
	int             foundsplitter, facesplits, groundsplits, epsilonfaces, bestepsilonfaces;
	float           bestvalue, value;
	tmp_face_t     *face1, *face2;
	vec3_t          tmpnormal, invgravity;
	float           tmpdist;

	//get inverse of gravity direction
	VectorCopy(cfg.phys_gravitydirection, invgravity);
	VectorInverse(invgravity);

	foundsplitter = false;
	bestvalue = -999999;
	bestepsilonfaces = 0;
	//
#ifdef AW_DEBUG
	Log_Print("finding split plane for area %d\n", tmparea->areanum);
#endif							//AW_DEBUG
	for(face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
	{
		//side of the face the area is on
		side1 = face1->frontarea != tmparea;
		//
		if(WindingIsTiny(face1->winding))
		{
			Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
			continue;
		}						//end if
		//if the face isn't a gap or ground there's no split edge
		if(!(face1->faceflags & FACE_GROUND) && !AAS_GapFace(face1, side1))
			continue;
		//
		for(face2 = face1->next[side1]; face2; face2 = face2->next[side2])
		{
			//side of the face the area is on
			side2 = face2->frontarea != tmparea;
			//
			if(WindingIsTiny(face1->winding))
			{
				Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
				continue;
			}					//end if
			//if the face isn't a gap or ground there's no split edge
			if(!(face2->faceflags & FACE_GROUND) && !AAS_GapFace(face2, side2))
				continue;
			//only split between gaps and ground
			if(!(((face1->faceflags & FACE_GROUND) && AAS_GapFace(face2, side2)) ||
				 ((face2->faceflags & FACE_GROUND) && AAS_GapFace(face1, side1))))
				continue;
			//find a plane seperating the windings of the faces
			if(!FindPlaneSeperatingWindings(face1->winding, face2->winding, invgravity, tmpnormal, &tmpdist))
				continue;
#ifdef AW_DEBUG
			Log_Print("normal = \'%f %f %f\', dist = %f\n", tmpnormal[0], tmpnormal[1], tmpnormal[2], tmpdist);
#endif							//AW_DEBUG
			//get metrics for this vertical plane
			if(!AAS_TestSplitPlane(tmparea, tmpnormal, tmpdist, &facesplits, &groundsplits, &epsilonfaces))
			{
				continue;
			}					//end if
#ifdef AW_DEBUG
			Log_Print("face splits = %d\nground splits = %d\n", facesplits, groundsplits);
#endif							//AW_DEBUG
			value = 100 - facesplits - 2 * groundsplits;
			//avoid epsilon faces
			value += epsilonfaces * -1000;
			if(value > bestvalue)
			{
				VectorCopy(tmpnormal, normal);
				*dist = tmpdist;
				bestvalue = value;
				bestepsilonfaces = epsilonfaces;
				foundsplitter = true;
			}					//end if
		}						//end for
	}							//end for
	if(bestepsilonfaces)
	{
		Log_Write("found %d epsilon faces trying to split area %d\r\n", epsilonfaces, tmparea->areanum);
	}							//end else
	return foundsplitter;
}								//end of the function AAS_FindBestAreaSplitPlane

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
tmp_node_t     *AAS_SubdivideArea_r(tmp_node_t * tmpnode)
{
	int             planenum;
	tmp_area_t     *frontarea, *backarea;
	tmp_node_t     *tmpnode1, *tmpnode2;
	vec3_t          normal;
	float           dist;

	if(AAS_FindBestAreaSplitPlane(tmpnode->tmparea, normal, &dist))
	{
		qprintf("\r%6d", ++numgravitationalsubdivisions);
		//
		planenum = FindFloatPlane(normal, dist);
		//split the area
		AAS_SplitArea(tmpnode->tmparea, planenum, &frontarea, &backarea);
		//
		tmpnode->tmparea = NULL;
		tmpnode->planenum = FindFloatPlane(normal, dist);
		//
		tmpnode1 = AAS_AllocTmpNode();
		tmpnode1->planenum = 0;
		tmpnode1->tmparea = frontarea;
		//
		tmpnode2 = AAS_AllocTmpNode();
		tmpnode2->planenum = 0;
		tmpnode2->tmparea = backarea;
		//subdivide the areas created by splitting recursively
		tmpnode->children[0] = AAS_SubdivideArea_r(tmpnode1);
		tmpnode->children[1] = AAS_SubdivideArea_r(tmpnode2);
	}							//end if
	return tmpnode;
}								//end of the function AAS_SubdivideArea_r

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
tmp_node_t     *AAS_GravitationalSubdivision_r(tmp_node_t * tmpnode)
{
	//if this is a solid leaf
	if(!tmpnode)
		return NULL;
	//negative so it's an area
	if(tmpnode->tmparea)
		return AAS_SubdivideArea_r(tmpnode);
	//do the children recursively
	tmpnode->children[0] = AAS_GravitationalSubdivision_r(tmpnode->children[0]);
	tmpnode->children[1] = AAS_GravitationalSubdivision_r(tmpnode->children[1]);
	return tmpnode;
}								//end of the function AAS_GravitationalSubdivision_r

//===========================================================================
// NOTE: merge faces and melt edges first
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
void AAS_GravitationalSubdivision(void)
{
	Log_Write("AAS_GravitationalSubdivision\r\n");
	numgravitationalsubdivisions = 0;
	qprintf("%6i gravitational subdivisions", numgravitationalsubdivisions);
	//start with the head node
	AAS_GravitationalSubdivision_r(tmpaasworld.nodes);
	qprintf("\n");
	Log_Write("%6i gravitational subdivisions\r\n", numgravitationalsubdivisions);
}								//end of the function AAS_GravitationalSubdivision

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
tmp_node_t     *AAS_RefreshLadderSubdividedTree_r(tmp_node_t * tmpnode, tmp_area_t * tmparea,
												  tmp_node_t * tmpnode1, tmp_node_t * tmpnode2, int planenum)
{
	//if this is a solid leaf
	if(!tmpnode)
		return NULL;
	//negative so it's an area
	if(tmpnode->tmparea)
	{
		if(tmpnode->tmparea == tmparea)
		{
			tmpnode->tmparea = NULL;
			tmpnode->planenum = planenum;
			tmpnode->children[0] = tmpnode1;
			tmpnode->children[1] = tmpnode2;
		}						//end if
		return tmpnode;
	}							//end if
	//do the children recursively
	tmpnode->children[0] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[0], tmparea, tmpnode1, tmpnode2, planenum);
	tmpnode->children[1] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[1], tmparea, tmpnode1, tmpnode2, planenum);
	return tmpnode;
}								//end of the function AAS_RefreshLadderSubdividedTree_r

//===========================================================================
// find an area with ladder faces and ground faces that are not connected
// split the area with a horizontal plane at the lowest vertex of all
// ladder faces in the area
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
tmp_node_t     *AAS_LadderSubdivideArea_r(tmp_node_t * tmpnode)
{
	int             side1, i, planenum;
	int             foundladderface, foundgroundface;
	float           dist;
	tmp_area_t     *tmparea, *frontarea, *backarea;
	tmp_face_t     *face1;
	tmp_node_t     *tmpnode1, *tmpnode2;
	vec3_t          lowestpoint, normal = { 0, 0, 1 };
	plane_t        *plane;
	winding_t      *w;

	tmparea = tmpnode->tmparea;
	//skip areas with a liquid
	if(tmparea->contents & (AREACONTENTS_WATER | AREACONTENTS_LAVA | AREACONTENTS_SLIME))
		return tmpnode;
	//must be possible to stand in the area
	if(!(tmparea->presencetype & PRESENCE_NORMAL))
		return tmpnode;
	//
	foundladderface = false;
	foundgroundface = false;
	lowestpoint[2] = 99999;
	//
	for(face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
	{
		//side of the face the area is on
		side1 = face1->frontarea != tmparea;
		//if the face is a ladder face
		if(face1->faceflags & FACE_LADDER)
		{
			plane = &mapplanes[face1->planenum];
			//the ladder face plane should be pretty much vertical
			if(DotProduct(plane->normal, normal) > -0.1)
			{
				foundladderface = true;
				//find lowest point
				for(i = 0; i < face1->winding->numpoints; i++)
				{
					if(face1->winding->p[i][2] < lowestpoint[2])
					{
						VectorCopy(face1->winding->p[i], lowestpoint);
					}			//end if
				}				//end for
			}					//end if
		}						//end if
		else if(face1->faceflags & FACE_GROUND)
		{
			foundgroundface = true;
		}						//end else if
	}							//end for
	//
	if((!foundladderface) || (!foundgroundface))
		return tmpnode;
	//
	for(face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
	{
		//side of the face the area is on
		side1 = face1->frontarea != tmparea;
		//if the face isn't a ground face
		if(!(face1->faceflags & FACE_GROUND))
			continue;
		//the ground plane
		plane = &mapplanes[face1->planenum];
		//get the difference between the ground plane and the lowest point
		dist = DotProduct(plane->normal, lowestpoint) - plane->dist;
		//if the lowest point is very near one of the ground planes
		if(dist > -1 && dist < 1)
		{
			return tmpnode;
		}						//end if
	}							//end for
	//
	dist = DotProduct(normal, lowestpoint);
	planenum = FindFloatPlane(normal, dist);
	//
	w = AAS_SplitWinding(tmparea, planenum);
	if(!w)
		return tmpnode;
	FreeWinding(w);
	//split the area with a horizontal plane through the lowest point
	qprintf("\r%6d", ++numladdersubdivisions);
	//
	AAS_SplitArea(tmparea, planenum, &frontarea, &backarea);
	//
	tmpnode->tmparea = NULL;
	tmpnode->planenum = planenum;
	//
	tmpnode1 = AAS_AllocTmpNode();
	tmpnode1->planenum = 0;
	tmpnode1->tmparea = frontarea;
	//
	tmpnode2 = AAS_AllocTmpNode();
	tmpnode2->planenum = 0;
	tmpnode2->tmparea = backarea;
	//subdivide the areas created by splitting recursively
	tmpnode->children[0] = AAS_LadderSubdivideArea_r(tmpnode1);
	tmpnode->children[1] = AAS_LadderSubdivideArea_r(tmpnode2);
	//refresh the tree
	AAS_RefreshLadderSubdividedTree_r(tmpaasworld.nodes, tmparea, tmpnode1, tmpnode2, planenum);
	//
	return tmpnode;
}								//end of the function AAS_LadderSubdivideArea_r

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
tmp_node_t     *AAS_LadderSubdivision_r(tmp_node_t * tmpnode)
{
	//if this is a solid leaf
	if(!tmpnode)
		return 0;
	//negative so it's an area
	if(tmpnode->tmparea)
		return AAS_LadderSubdivideArea_r(tmpnode);
	//do the children recursively
	tmpnode->children[0] = AAS_LadderSubdivision_r(tmpnode->children[0]);
	tmpnode->children[1] = AAS_LadderSubdivision_r(tmpnode->children[1]);
	return tmpnode;
}								//end of the function AAS_LadderSubdivision_r

//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
void AAS_LadderSubdivision(void)
{
	Log_Write("AAS_LadderSubdivision\r\n");
	numladdersubdivisions = 0;
	qprintf("%6i ladder subdivisions", numladdersubdivisions);
	//start with the head node
	AAS_LadderSubdivision_r(tmpaasworld.nodes);
	//
	qprintf("\n");
	Log_Write("%6i ladder subdivisions\r\n", numladdersubdivisions);
}								//end of the function AAS_LadderSubdivision




See more files for this project here

Nxabega

Nxabega is a First Person Shooter (FPS) based upon the open sourced Quake 3 engine and game code. The final intention is to provide a rich single player game.

Project homepage: http://sourceforge.net/projects/nxabega
Programming language(s): C,C++
License: other

  Conscript
  Makefile
  _files.c
  aas_areamerging.c
  aas_areamerging.h
  aas_cfg.c
  aas_cfg.h
  aas_create.c
  aas_create.h
  aas_edgemelting.c
  aas_edgemelting.h
  aas_facemerging.c
  aas_facemerging.h
  aas_file.c
  aas_file.h
  aas_gsubdiv.c
  aas_gsubdiv.h
  aas_map.c
  aas_map.h
  aas_prunenodes.c
  aas_prunenodes.h
  aas_store.c
  aas_store.h
  aasfile.h
  be_aas_bspc.c
  be_aas_bspc.h
  brushbsp.c
  bspc.c
  bspc.sln
  bspc.vcproj
  cfgq3.c
  csg.c
  faces.c
  gldraw.c
  glfile.c
  l_bsp_ent.c
  l_bsp_ent.h
  l_bsp_hl.c
  l_bsp_hl.h
  l_bsp_q1.c
  l_bsp_q1.h
  l_bsp_q2.c
  l_bsp_q2.h
  l_bsp_q3.c
  l_bsp_q3.h
  l_bsp_sin.c
  l_bsp_sin.h
  l_cmd.c
  l_cmd.h
  l_log.c
  l_log.h
  l_math.c
  l_math.h
  l_mem.c
  l_mem.h
  l_poly.c
  l_poly.h
  l_qfiles.c
  l_qfiles.h
  l_threads.c
  l_threads.h
  l_utils.c
  l_utils.h
  lcc.mak
  leakfile.c
  linux-i386.mak
  map.c
  map_hl.c
  map_q1.c
  map_q2.c
  map_q3.c
  map_sin.c
  nodraw.c
  portals.c
  prtfile.c
  q2files.h
  q3files.h
  qbsp.h
  qfiles.h
  sinfiles.h
  tetrahedron.c
  tetrahedron.h
  textures.c
  tree.c
  writebsp.c