Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

l_bsp_q2.c File Reference

#include "l_cmd.h"
#include "l_math.h"
#include "l_mem.h"
#include "l_log.h"
#include "l_poly.h"
#include "../botlib/l_script.h"
#include "q2files.h"
#include "l_bsp_q2.h"
#include "l_bsp_ent.h"

Include dependency graph for l_bsp_q2.c:

Include dependency graph

Go to the source code of this file.

Defines

#define MAX_MAP_DPOP   256
#define q2_darea_t   darea_t
#define q2_dareaportal_t   dareaportal_t
#define q2_dareaportals   dareaportals
#define q2_dareas   dareas
#define q2_dbrush_t   dbrush_t
#define q2_dbrushes   dbrushes
#define q2_dbrushside_t   dbrushside_t
#define q2_dbrushsides   dbrushsides
#define q2_dedge_t   dedge_t
#define q2_dedges   dedges
#define q2_dface_t   dface_t
#define q2_dfaces   dfaces
#define q2_dheader_t   dheader_t
#define q2_dleaf_t   dleaf_t
#define q2_dleafbrushes   dleafbrushes
#define q2_dleaffaces   dleaffaces
#define q2_dleafs   dleafs
#define q2_dmodel_t   dmodel_t
#define q2_dmodel_t   dmodel_t
#define q2_dmodels   dmodels
#define q2_dnode_t   dnode_t
#define q2_dnodes   dnodes
#define q2_dplane_t   dplane_t
#define q2_dplanes   dplanes
#define q2_dsurfedges   dsurfedges
#define q2_dvertex_t   dvertex_t
#define q2_dvertexes   dvertexes
#define q2_dvis_t   dvis_t
#define q2_lump_t   lump_t
#define q2_numareaportals   numareaportals
#define q2_numareas   numareas
#define q2_numbrushes   numbrushes
#define q2_numbrushsides   numbrushsides
#define q2_numedges   numedges
#define q2_numfaces   numfaces
#define q2_numleafbrushes   numleafbrushes
#define q2_numleaffaces   numleaffaces
#define q2_numleafs   numleafs
#define q2_nummodels   nummodels
#define q2_numnodes   numnodes
#define q2_numplanes   numplanes
#define q2_numtexinfo   numtexinfo
#define q2_numvertexes   numvertexes
#define q2_texinfo   texinfo
#define q2_texinfo_t   texinfo_t
#define WCONVEX_EPSILON   0.5

Functions

void GetLeafNums (void)
int InsideFace (dface_t *face, vec3_t point)
int InsideWinding (winding_t *w, vec3_t point, int planenum)
void Q2_AddLump (int lumpnum, void *data, int len)
void Q2_AllocMaxBSP (void)
winding_tQ2_BrushSideWinding (dbrush_t *brush, dbrushside_t *baseside)
int Q2_CompressVis (byte *vis, byte *dest)
int Q2_CopyLump (int lump, void *dest, int size, int maxsize)
void Q2_DecompressVis (byte *in, byte *decompressed)
float Q2_FaceOnWinding (q2_dface_t *face, winding_t *winding)
void Q2_FixTextureReferences (void)
void Q2_FreeMaxBSP (void)
int Q2_HintSkipBrush (dbrush_t *brush)
void Q2_LoadBSPFile (char *filename, int offset, int length)
void Q2_LoadBSPFileTexinfo (char *filename)
void Q2_ParseEntities (void)
void Q2_PrintBSPFileSizes (void)
void Q2_SwapBSPFile (qboolean todisk)
void Q2_UnparseEntities (void)
void Q2_WriteBSPFile (char *filename)
qboolean WindingIsTiny (winding_t *w)

Variables

int allocatedbspmem = 0
char brushsidetextured [MAX_MAP_BRUSHSIDES]
int bspallocated = false
dareaportal_tdareaportals
darea_tdareas
dbrush_tdbrushes
dbrushside_tdbrushsides
dedge_tdedges
char * dentdata
dface_tdfaces
unsigned short * dleafbrushes
unsigned short * dleaffaces
dleaf_tdleafs
bytedlightdata
dmodel_tdmodels
dnode_tdnodes
dplane_tdplanes
byte dpop [MAX_MAP_DPOP]
int * dsurfedges
dvertex_tdvertexes
dvis_tdvis
bytedvisdata
int entdatasize
dheader_theader
int lightdatasize
int numareaportals
int numareas
int numbrushes
int numbrushsides
int numedges
int numfaces
int numleafbrushes
int numleaffaces
int numleafs
int nummodels
int numnodes
int numplanes
int numsurfedges
int numtexinfo
int numvertexes
dheader_t outheader
texinfo_t texinfo [MAX_MAP_TEXINFO]
int visdatasize
FILEwadfile


Define Documentation

#define MAX_MAP_DPOP   256
 

Definition at line 140 of file l_bsp_q2.c.

Referenced by Q2_LoadBSPFile().

#define q2_darea_t   darea_t
 

Definition at line 48 of file l_bsp_q2.c.

#define q2_dareaportal_t   dareaportal_t
 

Definition at line 47 of file l_bsp_q2.c.

#define q2_dareaportals   dareaportals
 

Definition at line 78 of file l_bsp_q2.c.

#define q2_dareas   dareas
 

Definition at line 76 of file l_bsp_q2.c.

#define q2_dbrush_t   dbrush_t
 

Definition at line 45 of file l_bsp_q2.c.

#define q2_dbrushes   dbrushes
 

Definition at line 72 of file l_bsp_q2.c.

#define q2_dbrushside_t   dbrushside_t
 

Definition at line 44 of file l_bsp_q2.c.

#define q2_dbrushsides   dbrushsides
 

Definition at line 74 of file l_bsp_q2.c.

#define q2_dedge_t   dedge_t
 

Definition at line 41 of file l_bsp_q2.c.

#define q2_dedges   dedges
 

Definition at line 65 of file l_bsp_q2.c.

Referenced by Q2_FaceOnWinding().

#define q2_dface_t   dface_t
 

Definition at line 42 of file l_bsp_q2.c.

#define q2_dfaces   dfaces
 

Definition at line 63 of file l_bsp_q2.c.

#define q2_dheader_t   dheader_t
 

Definition at line 35 of file l_bsp_q2.c.

#define q2_dleaf_t   dleaf_t
 

Definition at line 43 of file l_bsp_q2.c.

#define q2_dleafbrushes   dleafbrushes
 

Definition at line 69 of file l_bsp_q2.c.

#define q2_dleaffaces   dleaffaces
 

Definition at line 67 of file l_bsp_q2.c.

#define q2_dleafs   dleafs
 

Definition at line 53 of file l_bsp_q2.c.

#define q2_dmodel_t   dmodel_t
 

Definition at line 36 of file l_bsp_q2.c.

#define q2_dmodel_t   dmodel_t
 

Definition at line 36 of file l_bsp_q2.c.

#define q2_dmodels   dmodels
 

Definition at line 51 of file l_bsp_q2.c.

#define q2_dnode_t   dnode_t
 

Definition at line 39 of file l_bsp_q2.c.

#define q2_dnodes   dnodes
 

Definition at line 59 of file l_bsp_q2.c.

#define q2_dplane_t   dplane_t
 

Definition at line 38 of file l_bsp_q2.c.

Referenced by Q2_FaceOnWinding().

#define q2_dplanes   dplanes
 

Definition at line 55 of file l_bsp_q2.c.

Referenced by Q2_FaceOnWinding().

#define q2_dsurfedges   dsurfedges
 

Definition at line 70 of file l_bsp_q2.c.

Referenced by Q2_FaceOnWinding().

#define q2_dvertex_t   dvertex_t
 

Definition at line 37 of file l_bsp_q2.c.

#define q2_dvertexes   dvertexes
 

Definition at line 57 of file l_bsp_q2.c.

Referenced by Q2_FaceOnWinding().

#define q2_dvis_t   dvis_t
 

Definition at line 46 of file l_bsp_q2.c.

#define q2_lump_t   lump_t
 

Definition at line 34 of file l_bsp_q2.c.

#define q2_numareaportals   numareaportals
 

Definition at line 77 of file l_bsp_q2.c.

#define q2_numareas   numareas
 

Definition at line 75 of file l_bsp_q2.c.

#define q2_numbrushes   numbrushes
 

Definition at line 71 of file l_bsp_q2.c.

#define q2_numbrushsides   numbrushsides
 

Definition at line 73 of file l_bsp_q2.c.

#define q2_numedges   numedges
 

Definition at line 64 of file l_bsp_q2.c.

#define q2_numfaces   numfaces
 

Definition at line 62 of file l_bsp_q2.c.

#define q2_numleafbrushes   numleafbrushes
 

Definition at line 68 of file l_bsp_q2.c.

#define q2_numleaffaces   numleaffaces
 

Definition at line 66 of file l_bsp_q2.c.

#define q2_numleafs   numleafs
 

Definition at line 52 of file l_bsp_q2.c.

#define q2_nummodels   nummodels
 

Definition at line 50 of file l_bsp_q2.c.

#define q2_numnodes   numnodes
 

Definition at line 58 of file l_bsp_q2.c.

#define q2_numplanes   numplanes
 

Definition at line 54 of file l_bsp_q2.c.

#define q2_numtexinfo   numtexinfo
 

Definition at line 60 of file l_bsp_q2.c.

#define q2_numvertexes   numvertexes
 

Definition at line 56 of file l_bsp_q2.c.

#define q2_texinfo   texinfo
 

Definition at line 61 of file l_bsp_q2.c.

#define q2_texinfo_t   texinfo_t
 

Definition at line 40 of file l_bsp_q2.c.

#define WCONVEX_EPSILON   0.5
 

Definition at line 318 of file l_bsp_q2.c.


Function Documentation

void GetLeafNums void   ) 
 

int InsideFace dface_t face,
vec3_t  point
 

Definition at line 344 of file l_bsp_q2.c.

References abs(), CrossProduct(), dedges, DotProduct, dplanes, dsurfedges, dvertexes, dface_t::firstedge, i, dplane_t::normal, dface_t::numedges, dface_t::planenum, point, dvertex_t::point, dedge_t::v, v1, v2, vec3_t, vec_t, VectorNormalize(), and VectorSubtract.

00345 {
00346     int i, edgenum, side;
00347     float dist;
00348     vec_t *v1, *v2;
00349     vec3_t normal, edgevec;
00350     dplane_t *plane;
00351 
00352     for (i = 0; i < face->numedges; i++)
00353     {
00354         //get the first and second vertex of the edge
00355         edgenum = dsurfedges[face->firstedge + i];
00356         side = edgenum < 0;
00357         v1 = dvertexes[dedges[abs(edgenum)].v[side]].point;
00358         v2 = dvertexes[dedges[abs(edgenum)].v[!side]].point;
00359         //create a plane through the edge vector, orthogonal to the face plane
00360         //and with the normal vector pointing out of the face
00361         VectorSubtract(v1, v2, edgevec);
00362         plane = &dplanes[face->planenum];
00363         CrossProduct(plane->normal, edgevec, normal);
00364         VectorNormalize(normal);
00365         dist = DotProduct(normal, v1);
00366         //
00367         if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
00368     } //end for
00369     return true;
00370 } //end of the function InsideFace

Here is the call graph for this function:

int InsideWinding winding_t w,
vec3_t  point,
int  planenum
 

Definition at line 320 of file l_bsp_q2.c.

References CrossProduct(), DotProduct, dplanes, i, dplane_t::normal, winding_t::numpoints, winding_t::p, point, v1, v2, vec3_t, vec_t, VectorNormalize(), VectorSubtract, and w.

00321 {
00322     int i;
00323     float dist;
00324     vec_t *v1, *v2;
00325     vec3_t normal, edgevec;
00326     dplane_t *plane;
00327 
00328     for (i = 1; i <= w->numpoints; i++)
00329     {
00330         v1 = w->p[i % w->numpoints];
00331         v2 = w->p[(i + 1) % w->numpoints];
00332 
00333         VectorSubtract(v2, v1, edgevec);
00334         plane = &dplanes[planenum];
00335         CrossProduct(plane->normal, edgevec, normal);
00336         VectorNormalize(normal);
00337         dist = DotProduct(normal, v1);
00338         //
00339         if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
00340     } //end for
00341     return true;
00342 } //end of the function InsideWinding

Here is the call graph for this function:

void Q2_AddLump int  lumpnum,
void *  data,
int  len
 

Definition at line 952 of file l_bsp_q2.c.

References data, lump_t::filelen, lump_t::fileofs, ftell(), header, LittleLong(), dheader_t::lumps, SafeWrite(), and wadfile.

Referenced by Q2_WriteBSPFile().

00953 {
00954     lump_t *lump;
00955 
00956     lump = &header->lumps[lumpnum];
00957     
00958     lump->fileofs = LittleLong( ftell(wadfile) );
00959     lump->filelen = LittleLong(len);
00960     SafeWrite (wadfile, data, (len+3)&~3);
00961 } //end of the function Q2_AddLump

Here is the call graph for this function:

void Q2_AllocMaxBSP void   ) 
 

Definition at line 151 of file l_bsp_q2.c.

References allocatedbspmem, byte, dareaportals, dareas, dbrushes, dbrushsides, dedges, dentdata, dfaces, dleafbrushes, dleaffaces, dleafs, dlightdata, dmodels, dnodes, dplanes, dsurfedges, dvertexes, dvis, dvisdata, entdatasize, GetClearedMemory(), lightdatasize, Log_Print(), MAX_MAP_AREAPORTALS, MAX_MAP_AREAS, MAX_MAP_BRUSHES, MAX_MAP_BRUSHSIDES, MAX_MAP_EDGES, MAX_MAP_ENTSTRING, MAX_MAP_FACES, MAX_MAP_LEAFBRUSHES, MAX_MAP_LEAFFACES, MAX_MAP_LEAFS, MAX_MAP_LIGHTING, MAX_MAP_MODELS, MAX_MAP_NODES, MAX_MAP_PLANES, MAX_MAP_SURFEDGES, MAX_MAP_VERTS, MAX_MAP_VISIBILITY, numareaportals, numareas, numbrushes, numbrushsides, numedges, numfaces, numleafbrushes, numleaffaces, numleafs, nummodels, numnodes, numplanes, numsurfedges, numvertexes, PrintMemorySize(), and visdatasize.

Referenced by LoadMapFromBSP().

00152 {
00153     //models
00154     nummodels = 0;
00155     dmodels = (dmodel_t *) GetClearedMemory(MAX_MAP_MODELS * sizeof(dmodel_t));
00156     allocatedbspmem += MAX_MAP_MODELS * sizeof(dmodel_t);
00157     //vis data
00158     visdatasize = 0;
00159     dvisdata = (byte *) GetClearedMemory(MAX_MAP_VISIBILITY * sizeof(byte));
00160     dvis = (dvis_t *) dvisdata;
00161     allocatedbspmem += MAX_MAP_VISIBILITY * sizeof(byte);
00162     //light data
00163     lightdatasize = 0;
00164     dlightdata = (byte *) GetClearedMemory(MAX_MAP_LIGHTING * sizeof(byte));
00165     allocatedbspmem += MAX_MAP_LIGHTING * sizeof(byte);
00166     //entity data
00167     entdatasize = 0;
00168     dentdata = (char *) GetClearedMemory(MAX_MAP_ENTSTRING * sizeof(char));
00169     allocatedbspmem += MAX_MAP_ENTSTRING * sizeof(char);
00170     //leafs
00171     numleafs = 0;
00172     dleafs = (dleaf_t *) GetClearedMemory(MAX_MAP_LEAFS * sizeof(dleaf_t));
00173     allocatedbspmem += MAX_MAP_LEAFS * sizeof(dleaf_t);
00174     //planes
00175     numplanes = 0;
00176     dplanes = (dplane_t *) GetClearedMemory(MAX_MAP_PLANES * sizeof(dplane_t));
00177     allocatedbspmem += MAX_MAP_PLANES * sizeof(dplane_t);
00178     //vertexes
00179     numvertexes = 0;
00180     dvertexes = (dvertex_t *) GetClearedMemory(MAX_MAP_VERTS * sizeof(dvertex_t));
00181     allocatedbspmem += MAX_MAP_VERTS * sizeof(dvertex_t);
00182     //nodes
00183     numnodes = 0;
00184     dnodes = (dnode_t *) GetClearedMemory(MAX_MAP_NODES * sizeof(dnode_t));
00185     allocatedbspmem += MAX_MAP_NODES * sizeof(dnode_t);
00186     /*
00187     //texture info
00188     numtexinfo = 0;
00189     texinfo = (texinfo_t *) GetClearedMemory(MAX_MAP_TEXINFO * sizeof(texinfo_t));
00190     allocatedbspmem += MAX_MAP_TEXINFO * sizeof(texinfo_t);
00191     //*/
00192     //faces
00193     numfaces = 0;
00194     dfaces = (dface_t *) GetClearedMemory(MAX_MAP_FACES * sizeof(dface_t));
00195     allocatedbspmem += MAX_MAP_FACES * sizeof(dface_t);
00196     //edges
00197     numedges = 0;
00198     dedges = (dedge_t *) GetClearedMemory(MAX_MAP_EDGES * sizeof(dedge_t));
00199     allocatedbspmem += MAX_MAP_EDGES * sizeof(dedge_t);
00200     //leaf faces
00201     numleaffaces = 0;
00202     dleaffaces = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFFACES * sizeof(unsigned short));
00203     allocatedbspmem += MAX_MAP_LEAFFACES * sizeof(unsigned short);
00204     //leaf brushes
00205     numleafbrushes = 0;
00206     dleafbrushes = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFBRUSHES * sizeof(unsigned short));
00207     allocatedbspmem += MAX_MAP_LEAFBRUSHES * sizeof(unsigned short);
00208     //surface edges
00209     numsurfedges = 0;
00210     dsurfedges = (int *) GetClearedMemory(MAX_MAP_SURFEDGES * sizeof(int));
00211     allocatedbspmem += MAX_MAP_SURFEDGES * sizeof(int);
00212     //brushes
00213     numbrushes = 0;
00214     dbrushes = (dbrush_t *) GetClearedMemory(MAX_MAP_BRUSHES * sizeof(dbrush_t));
00215     allocatedbspmem += MAX_MAP_BRUSHES * sizeof(dbrush_t);
00216     //brushsides
00217     numbrushsides = 0;
00218     dbrushsides = (dbrushside_t *) GetClearedMemory(MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t));
00219     allocatedbspmem += MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t);
00220     //areas
00221     numareas = 0;
00222     dareas = (darea_t *) GetClearedMemory(MAX_MAP_AREAS * sizeof(darea_t));
00223     allocatedbspmem += MAX_MAP_AREAS * sizeof(darea_t);
00224     //area portals
00225     numareaportals = 0;
00226     dareaportals = (dareaportal_t *) GetClearedMemory(MAX_MAP_AREAPORTALS * sizeof(dareaportal_t));
00227     allocatedbspmem += MAX_MAP_AREAPORTALS * sizeof(dareaportal_t);
00228     //print allocated memory
00229     Log_Print("allocated ");
00230     PrintMemorySize(allocatedbspmem);
00231     Log_Print(" of BSP memory\n");
00232 } //end of the function Q2_AllocMaxBSP

Here is the call graph for this function:

winding_t* Q2_BrushSideWinding dbrush_t brush,
dbrushside_t baseside
 

Definition at line 428 of file l_bsp_q2.c.

References BaseWindingForPlane(), ChopWindingInPlace(), dbrushsides, dplane_t::dist, DotProduct, dplanes, fabs(), dbrush_t::firstside, i, dplane_t::normal, dbrush_t::numsides, dbrushside_t::planenum, and w.

Referenced by Q2_FixTextureReferences().

00429 {
00430     int i;
00431     dplane_t *baseplane, *plane;
00432     winding_t *w;
00433     dbrushside_t *side;
00434     
00435     //create a winding for the brush side with the given planenumber
00436     baseplane = &dplanes[baseside->planenum];
00437     w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
00438     for (i = 0; i < brush->numsides && w; i++)
00439     {
00440         side = &dbrushsides[brush->firstside + i];
00441         //don't chop with the base plane
00442         if (side->planenum == baseside->planenum) continue;
00443         //also don't use planes that are almost equal
00444         plane = &dplanes[side->planenum];
00445         if (DotProduct(baseplane->normal, plane->normal) > 0.999
00446                 && fabs(baseplane->dist - plane->dist) < 0.01) continue;
00447         //
00448         plane = &dplanes[side->planenum^1];
00449         ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
00450     } //end for
00451     return w;
00452 } //end of the function Q2_BrushSideWinding

Here is the call graph for this function:

int Q2_CompressVis byte vis,
byte dest
 

Definition at line 568 of file l_bsp_q2.c.

References byte, dvis, j, and dvis_t::numclusters.

00569 {
00570     int     j;
00571     int     rep;
00572     int     visrow;
00573     byte    *dest_p;
00574     
00575     dest_p = dest;
00576 //  visrow = (r_numvisleafs + 7)>>3;
00577     visrow = (dvis->numclusters + 7)>>3;
00578     
00579     for (j=0 ; j<visrow ; j++)
00580     {
00581         *dest_p++ = vis[j];
00582         if (vis[j])
00583             continue;
00584 
00585         rep = 1;
00586         for ( j++; j<visrow ; j++)
00587             if (vis[j] || rep == 255)
00588                 break;
00589             else
00590                 rep++;
00591         *dest_p++ = rep;
00592         j--;
00593     }
00594     
00595     return dest_p - dest;
00596 }

int Q2_CopyLump int  lump,
void *  dest,
int  size,
int  maxsize
 

Definition at line 830 of file l_bsp_q2.c.

References byte, Error(), lump_t::filelen, lump_t::fileofs, header, length(), dheader_t::lumps, and memcpy().

Referenced by Q2_LoadBSPFile().

00831 {
00832     int     length, ofs;
00833 
00834     length = header->lumps[lump].filelen;
00835     ofs = header->lumps[lump].fileofs;
00836     
00837     if (length % size)
00838         Error ("LoadBSPFile: odd lump size");
00839 
00840    if ((length/size) > maxsize)
00841       Error ("Q2_LoadBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize);
00842 
00843     memcpy (dest, (byte *)header + ofs, length);
00844 
00845     return length / size;
00846 } //end of the function Q2_CopyLump

Here is the call graph for this function:

void Q2_DecompressVis byte in,
byte decompressed
 

Definition at line 604 of file l_bsp_q2.c.

References byte, c, dvis, Error(), in, and dvis_t::numclusters.

00605 {
00606     int     c;
00607     byte    *out;
00608     int     row;
00609 
00610 //  row = (r_numvisleafs+7)>>3; 
00611     row = (dvis->numclusters+7)>>3; 
00612     out = decompressed;
00613 
00614     do
00615     {
00616         if (*in)
00617         {
00618             *out++ = *in++;
00619             continue;
00620         }
00621     
00622         c = in[1];
00623         if (!c)
00624             Error ("DecompressVis: 0 repeat");
00625         in += 2;
00626         while (c)
00627         {
00628             *out++ = 0;
00629             c--;
00630         }
00631     } while (out - decompressed < row);
00632 }

Here is the call graph for this function:

float Q2_FaceOnWinding q2_dface_t *  face,
winding_t winding
 

Definition at line 378 of file l_bsp_q2.c.

References abs(), ChopWindingInPlace(), CopyWinding(), CrossProduct(), DotProduct, FreeWinding(), i, memcpy(), q2_dedges, q2_dplane_t, q2_dplanes, q2_dsurfedges, q2_dvertexes, v1, v2, vec3_t, vec_t, VectorNegate, VectorNormalize(), VectorSubtract, w, and WindingArea().

Referenced by Q2_FixTextureReferences().

00379 {
00380     int i, edgenum, side;
00381     float dist, area;
00382     q2_dplane_t plane;
00383     vec_t *v1, *v2;
00384     vec3_t normal, edgevec;
00385     winding_t *w;
00386 
00387     //
00388     w = CopyWinding(winding);
00389     memcpy(&plane, &q2_dplanes[face->planenum], sizeof(q2_dplane_t));
00390     //check on which side of the plane the face is
00391     if (face->side)
00392     {
00393         VectorNegate(plane.normal, plane.normal);
00394         plane.dist = -plane.dist;
00395     } //end if
00396     for (i = 0; i < face->numedges && w; i++)
00397     {
00398         //get the first and second vertex of the edge
00399         edgenum = q2_dsurfedges[face->firstedge + i];
00400         side = edgenum > 0;
00401         //if the face plane is flipped
00402         v1 = q2_dvertexes[q2_dedges[abs(edgenum)].v[side]].point;
00403         v2 = q2_dvertexes[q2_dedges[abs(edgenum)].v[!side]].point;
00404         //create a plane through the edge vector, orthogonal to the face plane
00405         //and with the normal vector pointing inward
00406         VectorSubtract(v1, v2, edgevec);
00407         CrossProduct(edgevec, plane.normal, normal);
00408         VectorNormalize(normal);
00409         dist = DotProduct(normal, v1);
00410         //
00411         ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
00412     } //end for
00413     if (w)
00414     {
004