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

facebsp.c File Reference

#include "qbsp.h"

Include dependency graph for facebsp.c:

Include dependency graph

Go to the source code of this file.

Defines

#define BLOCK_SIZE   1024

Functions

bspface_tAllocBspFace (void)
bspface_tBspFaceForPortal (portal_t *p)
void BuildFaceTree_r (node_t *node, bspface_t *list)
int CountFaceList (bspface_t *list)
tree_tFaceBSP (bspface_t *list)
void FreeBspFace (bspface_t *f)
bspface_tMakeStructuralBspFaceList (bspbrush_t *list)
bspface_tMakeVisibleBspFaceList (bspbrush_t *list)
int SelectSplitPlaneNum (node_t *node, bspface_t *list)

Variables

int c_faceLeafs
int hintsplit


Define Documentation

#define BLOCK_SIZE   1024
 

Definition at line 63 of file facebsp.c.


Function Documentation

bspface_t* AllocBspFace void   ) 
 

Definition at line 34 of file facebsp.c.

References bspface_t, f, malloc(), and memset().

Referenced by BspFaceForPortal(), BuildFaceTree_r(), MakeStructuralBspFaceList(), and MakeVisibleBspFaceList().

00034                                   {
00035     bspface_t   *f;
00036 
00037     f = malloc(sizeof(*f));
00038     memset( f, 0, sizeof(*f) );
00039 
00040     return f;
00041 }

Here is the call graph for this function:

bspface_t* BspFaceForPortal portal_t p  ) 
 

Definition at line 292 of file facebsp.c.

References AllocBspFace(), bspface_t, CopyWinding(), f, portal_s::onnode, p, bspface_s::planenum, node_s::planenum, portal_t, bspface_s::w, and portal_s::winding.

00292                                            {
00293     bspface_t   *f;
00294 
00295     f = AllocBspFace();
00296     f->w = CopyWinding( p->winding );
00297     f->planenum = p->onnode->planenum & ~1;
00298 
00299     return f;
00300 }

Here is the call graph for this function:

void BuildFaceTree_r node_t node,
bspface_t list
 

Definition at line 157 of file facebsp.c.

References AllocBspFace(), AllocNode(), bspface_t, c_faceLeafs, node_s::children, CLIP_EPSILON, ClipWindingEpsilon(), CountFaceList(), plane_t::dist, FreeBspFace(), bspface_s::hint, node_s::hint, i, mapplanes, node_s::maxs, node_s::mins, bspface_s::next, next, node_t, plane_t::normal, node_s::parent, bspface_s::planenum, node_s::planenum, bspface_s::priority, SelectSplitPlaneNum(), VectorCopy, bspface_s::w, and WindingOnPlaneSide().

Referenced by FaceBSP().

00157                                                          {
00158     bspface_t   *split;
00159     bspface_t   *next;
00160     int         side;
00161     plane_t     *plane;
00162     bspface_t   *newFace;
00163     bspface_t   *childLists[2];
00164     winding_t   *frontWinding, *backWinding;
00165     int         i;
00166     int         splitPlaneNum;
00167 
00168     i = CountFaceList( list );
00169 
00170     splitPlaneNum = SelectSplitPlaneNum( node, list );
00171     // if we don't have any more faces, this is a node
00172     if ( splitPlaneNum == -1 ) {
00173         node->planenum = PLANENUM_LEAF;
00174         c_faceLeafs++;
00175         return;
00176     }
00177 
00178     // partition the list
00179     node->planenum = splitPlaneNum;
00180     node->hint = hintsplit;
00181     plane = &mapplanes[ splitPlaneNum ];
00182     childLists[0] = NULL;
00183     childLists[1] = NULL;
00184     for ( split = list ; split ; split = next ) {
00185         next = split->next;
00186 
00187         if ( split->planenum == node->planenum ) {
00188             FreeBspFace( split );
00189             continue;
00190         }
00191 
00192         side = WindingOnPlaneSide( split->w, plane->normal, plane->dist );
00193 
00194         if ( side == SIDE_CROSS ) {
00195             ClipWindingEpsilon( split->w, plane->normal, plane->dist, CLIP_EPSILON * 2,
00196                 &frontWinding, &backWinding );
00197             if ( frontWinding ) {
00198                 newFace = AllocBspFace();
00199                 newFace->w = frontWinding;
00200                 newFace->next = childLists[0];
00201                 newFace->planenum = split->planenum;
00202                 newFace->priority = split->priority;
00203                 newFace->hint = split->hint;
00204                 childLists[0] = newFace;
00205             }
00206             if ( backWinding ) {
00207                 newFace = AllocBspFace();
00208                 newFace->w = backWinding;
00209                 newFace->next = childLists[1];
00210                 newFace->planenum = split->planenum;
00211                 newFace->priority = split->priority;
00212                 newFace->hint = split->hint;
00213                 childLists[1] = newFace;
00214             }
00215             FreeBspFace( split );
00216         } else if ( side == SIDE_FRONT ) {
00217             split->next = childLists[0];
00218             childLists[0] = split;
00219         } else if ( side == SIDE_BACK ) {
00220             split->next = childLists[1];
00221             childLists[1] = split;
00222         }
00223     }
00224 
00225 
00226     // recursively process children
00227     for ( i = 0 ; i < 2 ; i++ ) {
00228         node->children[i] = AllocNode();
00229         node->children[i]->parent = node;
00230         VectorCopy( node->mins, node->children[i]->mins );
00231         VectorCopy( node->maxs, node->children[i]->maxs );
00232     }
00233 
00234     for ( i = 0 ; i < 3 ; i++ ) {
00235         if ( plane->normal[i] == 1 ) {
00236             node->children[0]->mins[i] = plane->dist;
00237             node->children[1]->maxs[i] = plane->dist;
00238             break;
00239         }
00240     }
00241 
00242     for ( i = 0 ; i < 2 ; i++ ) {
00243         BuildFaceTree_r ( node->children[i], childLists[i]);
00244     }
00245 }

Here is the call graph for this function:

int CountFaceList bspface_t list  ) 
 

Definition at line 143 of file facebsp.c.

References bspface_t, c, and bspface_s::next.

Referenced by BuildFaceTree_r().

00143                                      {
00144     int     c;
00145     c = 0;
00146     for ( ; list ; list = list->next ) {
00147         c++;
00148     }
00149     return c;
00150 }

tree_t* FaceBSP bspface_t list  ) 
 

Definition at line 255 of file facebsp.c.

References AddPointToBounds(), AllocNode(), AllocTree(), bspface_t, BuildFaceTree_r(), c_faceLeafs, count, i, bspface_s::next, winding_t::numpoints, winding_t::p, qprintf(), tree(), VectorCopy, and bspface_s::w.

Referenced by ProcessWorldModel().

00255                                    {
00256     tree_t      *tree;
00257     bspface_t   *face;
00258     int         i;
00259     int         count;
00260 
00261     qprintf( "--- FaceBSP ---\n" );
00262 
00263     tree = AllocTree ();
00264 
00265     count = 0;
00266     for ( face = list ; face ; face = face->next ) {
00267         count++;
00268         for ( i = 0 ; i < face->w->numpoints ; i++ ) {
00269             AddPointToBounds( face->w->p[i], tree->mins, tree->maxs);
00270         }
00271     }
00272     qprintf( "%5i faces\n", count );
00273 
00274     tree->headnode = AllocNode();
00275     VectorCopy( tree->mins, tree->headnode->mins );
00276     VectorCopy( tree->maxs, tree->headnode->maxs );
00277     c_faceLeafs = 0;
00278 
00279     BuildFaceTree_r ( tree->headnode, list );
00280 
00281     qprintf( "%5i leafs\n", c_faceLeafs );
00282 
00283     return tree;
00284 }

Here is the call graph for this function:

void FreeBspFace bspface_t f  ) 
 

Definition at line 48 of file facebsp.c.

References bspface_t, f, free(), FreeWinding(), and bspface_s::w.

Referenced by BuildFaceTree_r().

00048                                     {
00049     if ( f->w ) {
00050         FreeWinding( f->w );
00051     }
00052     free( f );
00053 }

Here is the call graph for this function:

bspface_t* MakeStructuralBspFaceList bspbrush_t list  ) 
 

Definition at line 309 of file facebsp.c.

References AllocBspFace(), b, bspbrush_t, bspface_t, CopyWinding(), bspbrush_s::detail, f, bspface_s::hint, i, bspbrush_s::next, bspface_s::next, bspbrush_s::numsides, bspface_s::planenum, side_s::planenum, s, side_t, bspbrush_s::sides, side_s::surfaceFlags, w, bspface_s::w, and side_s::winding.

Referenced by ProcessWorldModel().

00309                                                            {
00310     bspbrush_t  *b;
00311     int         i;
00312     side_t      *s;
00313     winding_t   *w;
00314     bspface_t   *f, *flist;
00315 
00316     flist = NULL;
00317     for ( b = list ; b ; b = b->next ) {
00318         if ( b->detail ) {
00319             continue;
00320         }
00321         for ( i = 0 ; i < b->numsides ; i++ ) {
00322             s = &b->sides[i];
00323             w = s->winding;
00324             if ( !w ) {
00325                 continue;
00326             }
00327             f = AllocBspFace();
00328             f->w = CopyWinding( w );
00329             f->planenum = s->planenum & ~1;
00330             f->next = flist;
00331             if (s->surfaceFlags & SURF_HINT) {
00332                 //f->priority = HINT_PRIORITY;
00333                 f->hint = qtrue;
00334             }
00335             flist = f;
00336         }
00337     }
00338 
00339     return flist;
00340 }

Here is the call graph for this function:

bspface_t* MakeVisibleBspFaceList bspbrush_t list  ) 
 

Definition at line 347 of file facebsp.c.

References AllocBspFace(), b, bspbrush_t, bspface_t, CopyWinding(), bspbrush_s::detail, f, bspface_s::hint, i, bspbrush_s::next, bspface_s::next, bspbrush_s::numsides, bspface_s::planenum, side_s::planenum, s, side_t, bspbrush_s::sides, side_s::surfaceFlags, side_s::visibleHull, w, and bspface_s::w.

Referenced by ProcessWorldModel().

00347                                                         {
00348     bspbrush_t  *b;
00349     int         i;
00350     side_t      *s;
00351     winding_t   *w;
00352     bspface_t   *f, *flist;
00353 
00354     flist = NULL;
00355     for ( b = list ; b ; b = b->next ) {
00356         if ( b->detail ) {
00357             continue;
00358         }
00359         for ( i = 0 ; i < b->numsides ; i++ ) {
00360             s = &b->sides[i];
00361             w = s->visibleHull;
00362             if ( !w ) {
00363                 continue;
00364             }
00365             f = AllocBspFace();
00366             f->w = CopyWinding( w );
00367             f->planenum = s->planenum & ~1;
00368             f->next = flist;
00369             if (s->surfaceFlags & SURF_HINT) {
00370                 //f->priority = HINT_PRIORITY;
00371                 f->hint = qtrue;
00372             }
00373             flist = f;
00374         }
00375     }
00376 
00377     return flist;
00378 }

Here is the call graph for this function:

int SelectSplitPlaneNum node_t node,
bspface_t list
 

Definition at line 64 of file facebsp.c.

References BLOCK_SIZE, bspface_t, check(), bspface_s::checked, plane_t::dist, FindFloatPlane(), floor(), bspface_s::hint, hintsplit, i, mapplanes, node_s::maxs, node_s::mins, bspface_s::next, node_t, plane_t::normal, bspface_s::planenum, bspface_s::priority, plane_t::type, value, vec3_t, VectorClear, bspface_s::w, and WindingOnPlaneSide().

Referenced by BuildFaceTree_r().

00064                                                          {
00065     bspface_t   *split;
00066     bspface_t   *check;
00067     bspface_t   *bestSplit;
00068     int         splits, facing, front, back;
00069     int         side;
00070     plane_t     *plane;
00071     int         value, bestValue;
00072     int         i;
00073     vec3_t      normal;
00074     float       dist;
00075     int         planenum;
00076 
00077     hintsplit = qfalse;
00078     // if it is crossing a 1k block boundary, force a split
00079     for ( i = 0 ; i < 2 ; i++ ) {
00080         dist = BLOCK_SIZE * ( floor( node->mins[i] / BLOCK_SIZE ) + 1 );    
00081         if ( node->maxs[i] > dist ) {
00082             VectorClear( normal );
00083             normal[i] = 1;
00084             planenum = FindFloatPlane( normal, dist );
00085             return planenum;
00086         }
00087     }
00088 
00089     // pick one of the face planes
00090     bestValue = -99999;
00091     bestSplit = list;
00092 
00093     for ( split = list ; split ; split = split->next ) {
00094         split->checked = qfalse;
00095     }
00096 
00097     for ( split = list ; split ; split = split->next ) {
00098         if ( split->checked ) {
00099             continue;
00100         }
00101         plane = &mapplanes[ split->planenum ];
00102         splits = 0;
00103         facing = 0;
00104         front = 0;
00105         back = 0;
00106         for ( check = list ; check ; check = check->next ) {
00107             if ( check->planenum == split->planenum ) {
00108                 facing++;
00109                 check->checked = qtrue; // won't need to test this plane again
00110                 continue;
00111             }
00112             side = WindingOnPlaneSide( check->w, plane->normal, plane->dist );
00113             if ( side == SIDE_CROSS ) {
00114                 splits++;
00115             } else if ( side == SIDE_FRONT ) {
00116                 front++;
00117             } else if ( side == SIDE_BACK ) {
00118                 back++;
00119             }
00120         }
00121         value =  5*facing - 5*splits; // - abs(front-back);
00122         if ( plane->type < 3 ) {
00123             value+=5;       // axial is better
00124         }
00125         value += split->priority;       // prioritize hints higher
00126 
00127         if ( value > bestValue ) {
00128             bestValue = value;
00129             bestSplit = split;
00130         }
00131     }
00132 
00133     if ( bestValue == -99999 ) {
00134         return -1;
00135     }
00136 
00137     if (bestSplit->hint)
00138         hintsplit = qtrue;
00139 
00140     return bestSplit->planenum;
00141 }

Here is the call graph for this function:


Variable Documentation

int c_faceLeafs
 

Definition at line 26 of file facebsp.c.

Referenced by BuildFaceTree_r(), and FaceBSP().

int hintsplit
 

Definition at line 61 of file facebsp.c.

Referenced by SelectSplitPlaneNum(), SelectSplitSide(), and TestBrushToPlanenum().


Generated on Thu Aug 25 16:41:30 2005 for Quake III Arena by  doxygen 1.3.9.1