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

brush.c File Reference

#include "qbsp.h"

Include dependency graph for brush.c:

Include dependency graph

Go to the source code of this file.

Defines

#define EDGE_LENGTH   0.2
#define PLANESIDE_EPSILON   0.001

Functions

bspbrush_tAllocBrush (int numsides)
node_tAllocNode (void)
tree_tAllocTree (void)
qboolean BoundBrush (bspbrush_t *brush)
bspbrush_tBrushFromBounds (vec3_t mins, vec3_t maxs)
int BrushMostlyOnSide (bspbrush_t *brush, plane_t *plane)
vec_t BrushVolume (bspbrush_t *brush)
bspbrush_tCopyBrush (bspbrush_t *brush)
int CountBrushList (bspbrush_t *brushes)
qboolean CreateBrushWindings (bspbrush_t *brush)
void DrawBrushList (bspbrush_t *brush)
int FilterBrushIntoTree_r (bspbrush_t *b, node_t *node)
void FilterDetailBrushesIntoTree (entity_t *e, tree_t *tree)
void FilterStructuralBrushesIntoTree (entity_t *e, tree_t *tree)
void FreeBrush (bspbrush_t *brushes)
void FreeBrushList (bspbrush_t *brushes)
void PrintBrush (bspbrush_t *brush)
void SplitBrush (bspbrush_t *brush, int planenum, bspbrush_t **front, bspbrush_t **back)
qboolean WindingIsHuge (winding_t *w)
qboolean WindingIsTiny (winding_t *w)
void WriteBrushList (char *name, bspbrush_t *brush, qboolean onlyvis)
void WriteBspBrushMap (char *name, bspbrush_t *list)

Variables

int c_active_brushes
int c_nodes


Define Documentation

#define EDGE_LENGTH   0.2
 

Definition at line 581 of file brush.c.

#define PLANESIDE_EPSILON   0.001
 

Definition at line 31 of file brush.c.


Function Documentation

bspbrush_t* AllocBrush int  numsides  ) 
 

Definition at line 58 of file brush.c.

References bspbrush_t, c, c_active_brushes, c_brushmemory, c_peak_brushmemory, GetMemory(), malloc(), MemorySize(), memset(), and numthreads.

Referenced by BrushFromBounds(), CopyBrush(), HL_SplitBrush(), LoadMapFile(), MakeBspBrushList(), Q1_SplitBrush(), SplitBrush(), and TryMergeBrushes().

00059 {
00060     bspbrush_t  *bb;
00061     int         c;
00062 
00063     c = (int)&(((bspbrush_t *)0)->sides[numsides]);
00064     bb = malloc(c);
00065     memset (bb, 0, c);
00066     if (numthreads == 1)
00067         c_active_brushes++;
00068     return bb;
00069 }

Here is the call graph for this function:

node_t* AllocNode void   ) 
 

Definition at line 562 of file brush.c.

References c_nodememory, GetMemory(), malloc(), MemorySize(), memset(), node_t, and numthreads.

00563 {
00564     node_t  *node;
00565 
00566     node = malloc(sizeof(*node));
00567     memset (node, 0, sizeof(*node));
00568 
00569     return node;
00570 }

Here is the call graph for this function:

tree_t* AllocTree void   ) 
 

Definition at line 546 of file brush.c.

References ClearBounds(), malloc(), memset(), and tree().

Referenced by FaceBSP(), and ProcessSubModel().

00547 {
00548     tree_t  *tree;
00549 
00550     tree = malloc(sizeof(*tree));
00551     memset (tree, 0, sizeof(*tree));
00552     ClearBounds (tree->mins, tree->maxs);
00553 
00554     return tree;
00555 }

Here is the call graph for this function:

qboolean BoundBrush bspbrush_t brush  ) 
 

Definition at line 216 of file brush.c.

References AddPointToBounds(), bspbrush_t, ClearBounds(), i, j, MAX_WORLD_COORD, bspbrush_s::maxs, MIN_WORLD_COORD, bspbrush_s::mins, winding_t::numpoints, bspbrush_s::numsides, winding_t::p, qboolean, bspbrush_s::sides, w, and side_s::winding.

Referenced by CheckBSPBrush(), CreateBrushWindings(), HL_SplitBrush(), Q1_SplitBrush(), SplitBrush(), and TryMergeBrushes().

00217 {
00218     int         i, j;
00219     winding_t   *w;
00220 
00221     ClearBounds (brush->mins, brush->maxs);
00222     for (i=0 ; i<brush->numsides ; i++)
00223     {
00224         w = brush->sides[i].winding;
00225         if (!w)
00226             continue;
00227         for (j=0 ; j<w->numpoints ; j++)
00228             AddPointToBounds (w->p[j], brush->mins, brush->maxs);
00229     }
00230 
00231     for (i=0 ; i<3 ; i++) {
00232         if (brush->mins[i] < MIN_WORLD_COORD || brush->maxs[i] > MAX_WORLD_COORD
00233             || brush->mins[i] >= brush->maxs[i] ) {
00234             return qfalse;
00235         }
00236     }
00237 
00238     return qtrue;
00239 }

Here is the call graph for this function:

bspbrush_t* BrushFromBounds vec3_t  mins,
vec3_t  maxs
 

Definition at line 295 of file brush.c.

References AllocBrush(), b, bspbrush_t, CreateBrushWindings(), FindFloatPlane(), i, bspbrush_s::numsides, side_s::planenum, bspbrush_s::sides, vec3_t, vec_t, and VectorClear.

Referenced by BrushBSP(), HL_CreateBrushesFromBSP(), and Q1_CreateBrushesFromBSP().

00296 {
00297     bspbrush_t  *b;
00298     int         i;
00299     vec3_t      normal;
00300     vec_t       dist;
00301 
00302     b = AllocBrush (6);
00303     b->numsides = 6;
00304     for (i=0 ; i<3 ; i++)
00305     {
00306         VectorClear (normal);
00307         normal[i] = 1;
00308         dist = maxs[i];
00309         b->sides[i].planenum = FindFloatPlane (normal, dist);
00310 
00311         normal[i] = -1;
00312         dist = -mins[i];
00313         b->sides[3+i].planenum = FindFloatPlane (normal, dist);
00314     }
00315 
00316     CreateBrushWindings (b);
00317 
00318     return b;
00319 }

Here is the call graph for this function:

int BrushMostlyOnSide bspbrush_t brush,
plane_t plane
 

Definition at line 638 of file brush.c.

References bspbrush_t, d, plane_t::dist, DotProduct, i, j, max, plane_t::normal, winding_t::numpoints, bspbrush_s::numsides, winding_t::p, bspbrush_s::sides, vec_t, w, and side_s::winding.

Referenced by HL_SplitBrush(), Q1_SplitBrush(), and SplitBrush().

00639 {
00640     int         i, j;
00641     winding_t   *w;
00642     vec_t       d, max;
00643     int         side;
00644 
00645     max = 0;
00646     side = PSIDE_FRONT;
00647     for (i=0 ; i<brush->numsides ; i++)
00648     {
00649         w = brush->sides[i].winding;
00650         if (!w)
00651             continue;
00652         for (j=0 ; j<w->numpoints ; j++)
00653         {
00654             d = DotProduct (w->p[j], plane->normal) - plane->dist;
00655             if (d > max)
00656             {
00657                 max = d;
00658                 side = PSIDE_FRONT;
00659             }
00660             if (-d > max)
00661             {
00662                 max = -d;
00663                 side = PSIDE_BACK;
00664             }
00665         }
00666     }
00667     return side;
00668 }

vec_t BrushVolume bspbrush_t brush  ) 
 

Definition at line 327 of file brush.c.

References bspbrush_t, d, plane_t::dist, DotProduct, i, mapplanes, plane_t::normal, bspbrush_s::numsides, winding_t::p, side_s::planenum, bspbrush_s::sides, vec3_t, vec_t, VectorCopy, w, side_s::winding, and WindingArea().

Referenced by BrushBSP(), HL_SplitBrush(), Q1_SplitBrush(), and SplitBrush().

00328 {
00329     int         i;
00330     winding_t   *w;
00331     vec3_t      corner;
00332     vec_t       d, area, volume;
00333     plane_t     *plane;
00334 
00335     if (!brush)
00336         return 0;
00337 
00338     // grab the first valid point as the corner
00339 
00340     w = NULL;
00341     for (i=0 ; i<brush->numsides ; i++)
00342     {
00343         w = brush->sides[i].winding;
00344         if (w)
00345             break;
00346     }
00347     if (!w)
00348         return 0;
00349     VectorCopy (w->p[0], corner);
00350 
00351     // make tetrahedrons to all other faces
00352 
00353     volume = 0;
00354     for ( ; i<brush->numsides ; i++)
00355     {
00356         w = brush->sides[i].winding;
00357         if (!w)
00358             continue;
00359         plane = &mapplanes[brush->sides[i].planenum];
00360         d = -(DotProduct (corner, plane->normal) - plane->dist);
00361         area = WindingArea (w);
00362         volume += d*area;
00363     }
00364 
00365     volume /= 3;
00366     return volume;
00367 }

Here is the call graph for this function:

bspbrush_t* CopyBrush bspbrush_t brush  ) 
 

Definition at line 113 of file brush.c.

References AllocBrush(), bspbrush_t, CopyWinding(), i, memcpy(), bspbrush_s::numsides, bspbrush_s::sides, and side_s::winding.

00114 {
00115     bspbrush_t *newbrush;
00116     int         size;
00117     int         i;
00118     
00119     size = (int)&(((bspbrush_t *)0)->sides[brush->numsides]);
00120 
00121     newbrush = AllocBrush (brush->numsides);
00122     memcpy (newbrush, brush, size);
00123 
00124     for (i=0 ; i<brush->numsides ; i++)
00125     {
00126         if (brush->sides[i].winding)
00127             newbrush->sides[i].winding = CopyWinding (brush->sides[i].winding);
00128     }
00129 
00130     return newbrush;
00131 }

Here is the call graph for this function:

int CountBrushList bspbrush_t brushes  ) 
 

Definition at line 42 of file brush.c.

References bspbrush_t, c, and bspbrush_s::next.

Referenced by ChopBrushes(), and LoadMapFile().

00043 {
00044     int c;
00045 
00046     c = 0;
00047     for ( ; brushes ; brushes = brushes->next)
00048         c++;
00049     return c;
00050 }

qboolean CreateBrushWindings bspbrush_t brush  ) 
 

Definition at line 249 of file brush.c.

References side_s::backSide, BaseWindingForPlane(), side_s::bevel, BoundBrush(), bspbrush_t, ChopWindingInPlace(), plane_t::dist, side_s::flags, FreeWinding(), i, j, mapplanes, plane_t::normal, bspbrush_s::numsides, side_s::planenum, qboolean, side_t, bspbrush_s::sides, w, and side_s::winding.

Referenced by AdjustBrushesForOrigin(), BrushFromBounds(), and FinishBrush().

00250 {
00251     int         i, j;
00252     winding_t   *w;
00253     side_t      *side;
00254     plane_t     *plane;
00255 
00256     for ( i = 0; i < brush->numsides; i++ )
00257     {
00258         side = &brush->sides[i];
00259         // don't create a winding for a bevel
00260         if ( side->bevel ) {
00261             continue;
00262         }
00263         plane = &mapplanes[side->planenum];
00264         w = BaseWindingForPlane (plane->normal, plane->dist);
00265         for ( j = 0; j < brush->numsides && w; j++ )
00266         {
00267             if (i == j)
00268                 continue;
00269             if ( brush->sides[j].planenum == ( brush->sides[i].planenum ^ 1 ) )
00270                 continue;       // back side clipaway
00271             if (brush->sides[j].bevel)
00272                 continue;
00273             if (brush->sides[j].backSide)
00274                 continue;
00275             plane = &mapplanes[brush->sides[j].planenum^1];
00276             ChopWindingInPlace (&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
00277         }
00278         // free any existing winding
00279         if ( side->winding ) {
00280             FreeWinding( side->winding );
00281         }
00282         side->winding = w;
00283     }
00284 
00285     return BoundBrush (brush);
00286 }

Here is the call graph for this function:

void DrawBrushList bspbrush_t brush  ) 
 

Definition at line 139 of file brush.c.

References bspbrush_t, GLS_BeginScene(), GLS_EndScene(), GLS_Winding(), i, bspbrush_s::next, bspbrush_s::numsides, s, side_t, bspbrush_s::sides, and side_s::winding.

Referenced by BuildTree_r(), and BuildTreeThread().

00140 {
00141     int     i;
00142     side_t  *s;
00143 
00144     GLS_BeginScene ();
00145     for ( ; brush ; brush=brush->next)
00146     {
00147         for (i=0 ; i<brush->numsides ; i++)
00148         {
00149             s = &brush->sides[i];
00150             if (!s->winding)
00151                 continue;
00152             GLS_Winding (s->winding, 0);
00153         }
00154     }
00155     GLS_EndScene ();
00156 }

Here is the call graph for this function:

int FilterBrushIntoTree_r bspbrush_t b,
node_t node
 

Definition at line 420 of file brush.c.

References node_s::areaportal, b, node_s::brushlist, bspbrush_t, c, node_s::children, bspbrush_s::contents, bspbrush_s::detail, FreeBrush(), bspbrush_s::next, node_t, node_s::opaque, bspbrush_s::opaque, node_s::planenum, and SplitBrush().

Referenced by FilterDetailBrushesIntoTree(), and FilterStructuralBrushesIntoTree().

00420                                                          {
00421     bspbrush_t      *front, *back;
00422     int             c;
00423 
00424     if ( !b ) {
00425         return 0;
00426     }
00427 
00428     // add it to the leaf list
00429     if ( node->planenum == PLANENUM_LEAF ) {
00430         b->next = node->brushlist;
00431         node->brushlist = b;
00432 
00433         // classify the leaf by the structural brush
00434         if ( !b->detail ) {
00435             if ( b->opaque ) {
00436                 node->opaque = qtrue;
00437                 node->areaportal = qfalse;
00438             } else if ( b->contents & CONTENTS_AREAPORTAL ) {
00439                 if ( !node->opaque ) {
00440                     node->areaportal = qtrue;
00441                 }
00442             }
00443         }
00444 
00445         return 1;
00446     }
00447 
00448     // split it by the node plane
00449     SplitBrush ( b, node->planenum, &front, &back );
00450     FreeBrush( b );
00451 
00452     c = 0;
00453     c += FilterBrushIntoTree_r( front, node->children[0] );
00454     c += FilterBrushIntoTree_r( back, node->children[1] );
00455 
00456     return c;
00457 }

Here is the call graph for this function:

void FilterDetailBrushesIntoTree entity_t e,
tree_t tree
 

Definition at line 466 of file brush.c.

References b, entity_t::brushes, bspbrush_t, CopyBrush(), bspbrush_s::detail, e, FilterBrushIntoTree_r(), i, bspbrush_s::next, bspbrush_s::numsides, qprintf(), r, bspbrush_s::sides, tree(), side_s::visible, and side_s::winding.

Referenced by ProcessWorldModel().

00466                                                               {
00467     bspbrush_t          *b, *newb;
00468     int                 r;
00469     int                 c_unique, c_clusters;
00470     int                 i;
00471 
00472     qprintf( "----- FilterDetailBrushesIntoTree -----\n");
00473 
00474     c_unique = 0;
00475     c_clusters = 0;
00476     for ( b = e->brushes ; b ; b = b->next ) {
00477         if ( !b->detail ) {
00478             continue;
00479         }
00480         c_unique++;
00481         newb = CopyBrush( b );
00482         r = FilterBrushIntoTree_r( newb, tree->headnode );
00483         c_clusters += r;
00484 
00485         // mark all sides as visible so drawsurfs are created
00486         if ( r ) {
00487             for ( i = 0 ; i < b->numsides ; i++ ) {
00488                 if ( b->sides[i].winding ) {
00489                     b->sides[i].visible = qtrue;
00490                 }
00491             }
00492         }
00493     }
00494 
00495     qprintf( "%5i detail brushes\n", c_unique );
00496     qprintf( "%5i cluster references\n", c_clusters );
00497 }

Here is the call graph for this function:

void FilterStructuralBrushesIntoTree entity_t e,
tree_t tree
 

Definition at line 506 of file brush.c.

References b, entity_t::brushes, bspbrush_t, CopyBrush(), bspbrush_s::detail, e, FilterBrushIntoTree_r(), i, bspbrush_s::next, bspbrush_s::numsides, qprintf(), r, bspbrush_s::sides, tree(), side_s::visible, and side_s::winding.

Referenced by ProcessWorldModel().

00506                                                                   {
00507     bspbrush_t          *b, *newb;
00508     int                 r;
00509     int                 c_unique, c_clusters;
00510     int                 i;
00511 
00512     qprintf( "----- FilterStructuralBrushesIntoTree -----\n");
00513 
00514     c_unique = 0;
00515     c_clusters = 0;
00516     for ( b = e->brushes ; b ; b = b->next ) {
00517         if ( b->detail ) {
00518             continue;
00519         }
00520         c_unique++;
00521         newb = CopyBrush( b );
00522         r = FilterBrushIntoTree_r( newb, tree->headnode );
00523         c_clusters += r;
00524 
00525         // mark all sides as visible so drawsurfs are created
00526         if ( r ) {
00527             for ( i = 0 ; i < b->numsides ; i++ ) {
00528                 if ( b->sides[i].winding ) {
00529                     b->sides[i].visible = qtrue;
00530                 }
00531             }
00532         }
00533     }
00534 
00535     qprintf( "%5i structural brushes\n", c_unique );
00536     qprintf( "%5i cluster references\n", c_clusters );
00537 }

Here is the call graph for this function:

void FreeBrush bspbrush_t brushes  ) 
 

Definition at line 76 of file brush.c.

References bspbrush_t, c_active_brushes, c_brushmemory, free(), FreeMemory(), FreeWinding(), i, MemorySize(), bspbrush_s::numsides, numthreads, bspbrush_s::sides, and side_s::winding.

Referenced by BuildTree_r(), BuildTreeThread(), CheckPlaneAgainstVolume(), ClipBrushToBox(), CullList(), FilterBrushIntoTree_r(), FreeBrushList(), FreeTree_r(), HL_CreateBrushes_r(), HL_CreateMapBrushes(), HL_MergeBrushes(), HL_SplitBrush(), HL_SplitBrushWithFace(), HL_TextureBrushes(), IntersectBrush(), MergeBrushes(), ParseBrush(), Q1_CreateBrushes_r(), Q1_CreateMapBrushes(), Q1_MergeBrushes(), Q1_SplitBrush(), Q1_SplitBrushWithFace(), Q1_TextureBrushes(), SplitBrush(), SubtractBrush(), and Tree_Free_r().

00077 {
00078     int         i;
00079 
00080     for (i=0 ; i<brushes->numsides ; i++)
00081         if (brushes->sides[i].winding)
00082             FreeWinding(brushes->sides[i].winding);
00083     free (brushes);
00084     if (numthreads == 1)
00085         c_active_brushes--;
00086 }

Here is the call graph for this function:

void FreeBrushList bspbrush_t brushes  ) 
 

Definition at line 94 of file brush.c.

References bspbrush_t, FreeBrush(), bspbrush_s::next, and next.

Referenced by BuildTree_r(), BuildTreeThread(), ChopBrushes(), FreeTree_r(), HL_SplitBrushWithFace(), ProcessWorldBrushes(), Q1_SplitBrushWithFace(), and SubtractBrush().

00095 {
00096     bspbrush_t  *next;
00097 
00098     for ( ; brushes ; brushes = next)
00099     {
00100         next = brushes->next;
00101 
00102         FreeBrush (brushes);
00103     }       
00104 }

Here is the call graph for this function:

void PrintBrush bspbrush_t brush  ) 
 

Definition at line 196 of file brush.c.

References _printf(), bspbrush_t, i, bspbrush_s::numsides, printf(), pw(), bspbrush_s::sides, and side_s::winding.

00197 {
00198     int     i;
00199 
00200     _printf ("brush: %p\n", brush);
00201     for (i=0;i<brush->numsides ; i++)
00202     {
00203         pw(brush->sides[i].winding);
00204         _printf ("\n");
00205     }
00206 }

Here is the call graph for this function:

void SplitBrush bspbrush_t brush,
int  planenum,
bspbrush_t **  front,
bspbrush_t **  back
 

Definition at line 678 of file brush.c.

References AllocBrush(), b, side_s::backSide, BaseWindingForPlane(), BoundBrush(), BrushMostlyOnSide(), BrushVolume(), bspbrush_t, ChopWindingInPlace(), ClipWindingEpsilon(), CopyBrush(), CopyWinding(), d, plane_t::dist, DotProduct, side_s::flags, FreeBrush(), FreeWinding(), i, j, Log_Write(), mapplanes, MAX_MAP_BOUNDS, bspbrush_s::maxs, memcpy(), MIN_WORLD_COORD, bspbrush_s::mins, bspbrush_s::next, plane_t::normal, winding_t::numpoints, bspbrush_s::numsides, bspbrush_s::original, winding_t::p, side_s::planenum, qprintf(), s, side_s::shaderInfo, side_t, bspbrush_s::sides, side_s::texinfo, v1, vec_t, w, side_s::winding, WindingIsHuge(), and WindingIsTiny().

Referenced by BuildTree_r(), BuildTreeThread(), CheckPlaneAgainstVolume(), ClipBrushToBox(), FilterBrushIntoTree_r(), HL_SplitBrushWithFace(), Q1_SplitBrushWithFace(), SplitBrush2(), and SplitBrushList().

00680 {
00681     bspbrush_t  *b[2];
00682     int         i, j;
00683     winding_t   *w, *cw[2], *midwinding;
00684     plane_t     *plane, *plane2;
00685     side_t      *s, *cs;
00686     float       d, d_front, d_back;
00687 
00688     *front = *back = NULL;
00689     plane = &mapplanes[planenum];
00690 
00691     // check all points
00692     d_front = d_back = 0;
00693     for (i=0 ; i<brush->numsides ; i++)
00694     {
00695         w = brush->sides[i].winding;
00696         if (!w)
00697             continue;
00698         for (j=0 ; j<w->numpoints ; j++)
00699         {
00700             d = DotProduct (w->p[j], plane->normal) - plane->dist;
00701             if (d > 0 && d > d_front)
00702                 d_front = d;
00703             if (d < 0 && d < d_back)
00704                 d_back = d;
00705         }
00706     }
00707     if (d_front < 0.1) // PLANESIDE_EPSILON)
00708     {   // only on back
00709         *back = CopyBrush (brush);
00710         return;
00711     }
00712     if (d_back > -0.1) // PLANESIDE_EPSILON)
00713     {   // only on front
00714         *front = CopyBrush (brush);
00715         return;
00716     }
00717 
00718     // create a new winding from the split plane
00719 
00720     w = BaseWindingForPlane (plane->normal, plane->dist);
00721     for (i=0 ; i<brush->numsides && w ; i++)
00722     {
00723         if ( brush->sides[i].backSide ) {
00724             continue;   // fake back-sided polygons never split
00725         }
00726         plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
00727         ChopWindingInPlace (&w, plane2->normal, plane2->dist, 0); // PLANESIDE_EPSILON);
00728     }
00729 
00730     if (!w || WindingIsTiny (w) )
00731     {   // the brush isn't really split
00732         int     side;
00733 
00734         side = BrushMostlyOnSide (brush, plane);
00735         if (side == PSIDE_FRONT)
00736             *front = CopyBrush (brush);
00737         if (side == PSIDE_BACK)
00738             *back = CopyBrush (brush);
00739         return;
00740     }
00741 
00742     if (WindingIsHuge (w))
00743     {
00744         qprintf ("WARNING: huge winding\n");
00745     }
00746 
00747     midwinding = w;
00748 
00749     // split it for real
00750 
00751     for (i=0 ; i<2 ; i++)
00752     {
00753         b[i] = AllocBrush (brush->numsides+1);
00754         memcpy( b[i], brush, sizeof( bspbrush_t ) - sizeof( brush->sides ) );
00755         b[i]->numsides = 0;
00756         b[i]->next = NULL;
00757         b[i]->original = brush->original;
00758     }
00759 
00760     // split all the current windings
00761 
00762     for (i=0 ; i<brush->numsides ; i++)
00763     {
00764         s = &brush->sides[i];
00765         w = s->winding;
00766         if (!w)
00767             continue;
00768         ClipWindingEpsilon (w, plane->normal, plane->dist,
00769             0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]);
00770         for (j=0 ; j<2 ; j++)
00771         {
00772             if (!cw[j])
00773                 continue;
00774 /*
00775             if (WindingIsTiny (cw[j]))
00776             {
00777                 FreeWinding (cw[j]);
00778                 continue;
00779             }
00780 */
00781             cs = &b[j]->sides[b[j]->numsides];
00782             b[j]->numsides++;
00783             *cs = *s;
00784             cs->winding = cw[j];
00785         }
00786     }
00787 
00788 
00789     // see if we have valid polygons on both sides
00790 
00791     for (i=0 ; i<2 ; i++)
00792     {
00793         BoundBrush (b[i]);
00794         for (j=0 ; j<3 ; j++)
00795         {
00796             if (b[i]->mins[j] < MIN_WORLD_COORD || b[i]->maxs[j] > MAX_WORLD_COORD)
00797             {
00798                 qprintf ("bogus brush after clip\n");
00799                 break;
00800             }
00801         }
00802 
00803         if (b[i]->numsides < 3 || j < 3)
00804         {
00805             FreeBrush (b[i]);
00806             b[i] = NULL;
00807         }
00808     }
00809 
00810     if ( !(b[0] && b[1]) )
00811     {
00812         if (!b[0] && !b[1])
00813             qprintf ("split removed brush\n");
00814         else
00815             qprintf ("split not on both sides\n");
00816         if (b[0])
00817         {
00818             FreeBrush (b[0]);
00819             *front = CopyBrush (brush);
00820         }
00821         if (b[1])
00822         {
00823             FreeBrush (b[1]);
00824             *back = CopyBrush (brush);
00825         }
00826         return;
00827     }
00828 
00829     // add the midwinding to both sides
00830     for (i=0 ; i<2 ; i++)
00831     {
00832         cs = &b[i]->sides[b[i]->numsides];
00833         b[i]->numsides++;
00834 
00835         cs->planenum = planenum^i^1;
00836         cs->shaderInfo = NULL;
00837         if (i==0)
00838             cs->winding = CopyWinding (midwinding);
00839         else
00840             cs->winding = midwinding;
00841     }
00842 
00843 {
00844     vec_t   v1;
00845     int     i;
00846 
00847     for (i=0 ; i<2 ; i++)
00848     {
00849         v1 = BrushVolume (b[i]);
00850         if (v1 < 1.0)
00851         {
00852             FreeBrush (b[i]);
00853             b[i] = NULL;
00854 //          qprintf ("tiny volume after clip\n");
00855         }
00856     }
00857 }
00858 
00859     *front = b[0];
00860     *back = b[1];
00861 }

Here is the call graph for this function:

qboolean WindingIsHuge winding_t w  ) 
 

Definition at line 617 of file brush.c.

References BOGUS_RANGE, i, j, MIN_WORLD_COORD, winding_t::numpoints, winding_t::p, qboolean, and w.

Referenced by HL_SplitBrush(), Q1_SplitBrush(), and SplitBrush().

00618 {
00619     int     i, j;
00620 
00621     for (i=0 ; i<w->numpoints ; i++)
00622     {
00623         for (j=0 ; j<3 ; j++)
00624             if (w->p[i][j] <= MIN_WORLD_COORD || w->p[i][j] >= MAX_WORLD_COORD)
00625                 return qtrue;
00626     }
00627     return qfalse;
00628 }

qboolean WindingIsTiny winding_t w  ) 
 

Definition at line 582 of file brush.c.

References i, j, winding_t::numpoints, winding_t::p, qboolean, vec3_t, vec_t, VectorLength(), VectorSubtract, w, and WindingArea().

Referenced by AAS_FindBestAreaSplitPlane(), AAS_SplitFace(), HL_SplitBrush(), MakeNodePortal(), MarkBrushBevels(), Q1_SplitBrush(), Q2_FixTextureReferences(), Q3_FindVisibleBrushSides(), Sin_FixTextureReferences(), SplitBrush(), and SplitNodePortals().

00583 {
00584 /*
00585     if (WindingArea (w) < 1)
00586         return qtrue;
00587     return qfalse;
00588 */
00589     int     i, j;
00590     vec_t   len;
00591     vec3_t  delta;
00592     int     edges;
00593 
00594     edges = 0;
00595     for (i=0 ; i<w->numpoints ; i++)
00596     {
00597         j = i == w->numpoints - 1 ? 0 : i+1;
00598         VectorSubtract (w->p[j], w->p[i], delta);
00599         len = VectorLength (delta);
00600         if (len > EDGE_LENGTH)
00601         {
00602             if (++edges == 3)
00603                 return qfalse;
00604         }
00605     }
00606