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

visflow.c File Reference

#include "vis.h"

Include dependency graph for visflow.c:

Include dependency graph

Go to the source code of this file.

Functions

int AddSeperators (winding_t *source, winding_t *pass, qboolean flipclip, plane_t *seperators, int maxseperators)
winding_tAllocStackWinding (pstack_t *stack)
void BasePortalVis (int portalnum)
void BetterPortalVis (int portalnum)
void CheckStack (leaf_t *leaf, threaddata_t *thread)
winding_tClipToSeperators (winding_t *source, winding_t *pass, winding_t *target, qboolean flipclip, pstack_t *stack)
int CountBits (byte *bits, int numbits)
void CreatePassages (int portalnum)
void FreeStackWinding (winding_t *w, pstack_t *stack)
winding_tPassageChopWinding (winding_t *in, winding_t *out, plane_t *split)
void PassageFlow (int portalnum)
void PassageMemory (void)
void PassagePortalFlow (int portalnum)
void PortalFlow (int portalnum)
void RecursiveLeafBitFlow (int leafnum, byte *mightsee, byte *cansee)
void RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
void RecursivePassageFlow (vportal_t *portal, threaddata_t *thread, pstack_t *prevstack)
void RecursivePassagePortalFlow (vportal_t *portal, threaddata_t *thread, pstack_t *prevstack)
void SimpleFlood (vportal_t *srcportal, int leafnum)
winding_tVisChopWinding (winding_t *in, pstack_t *stack, plane_t *split)

Variables

int active
int c_chop
int c_flood
int c_fullskip
int c_leafskip
int c_mighttest
int c_nochop
int c_portalskip
int c_vis
int c_vistest


Function Documentation

int AddSeperators winding_t source,
winding_t pass,
qboolean  flipclip,
plane_t seperators,
int  maxseperators
 

Definition at line 1160 of file visflow.c.

References d, plane_t::dist, DotProduct, Error(), i, j, k, l, length(), plane_t::normal, winding_t::numpoints, winding_t::points, qboolean, source, sqrt(), v1, v2, vec3_origin, vec3_t, vec_t, and VectorSubtract.

Referenced by CreatePassages().

01161 {
01162     int         i, j, k, l;
01163     plane_t     plane;
01164     vec3_t      v1, v2;
01165     float       d;
01166     vec_t       length;
01167     int         counts[3], numseperators;
01168     qboolean    fliptest;
01169 
01170     numseperators = 0;
01171     // check all combinations   
01172     for (i=0 ; i<source->numpoints ; i++)
01173     {
01174         l = (i+1)%source->numpoints;
01175         VectorSubtract (source->points[l] , source->points[i], v1);
01176 
01177         // find a vertex of pass that makes a plane that puts all of the
01178         // vertexes of pass on the front side and all of the vertexes of
01179         // source on the back side
01180         for (j=0 ; j<pass->numpoints ; j++)
01181         {
01182             VectorSubtract (pass->points[j], source->points[i], v2);
01183 
01184             plane.normal[0] = v1[1]*v2[2] - v1[2]*v2[1];
01185             plane.normal[1] = v1[2]*v2[0] - v1[0]*v2[2];
01186             plane.normal[2] = v1[0]*v2[1] - v1[1]*v2[0];
01187             
01188             // if points don't make a valid plane, skip it
01189 
01190             length = plane.normal[0] * plane.normal[0]
01191             + plane.normal[1] * plane.normal[1]
01192             + plane.normal[2] * plane.normal[2];
01193             
01194             if (length < ON_EPSILON)
01195                 continue;
01196 
01197             length = 1/sqrt(length);
01198             
01199             plane.normal[0] *= length;
01200             plane.normal[1] *= length;
01201             plane.normal[2] *= length;
01202 
01203             plane.dist = DotProduct (pass->points[j], plane.normal);
01204 
01205             //
01206             // find out which side of the generated seperating plane has the
01207             // source portal
01208             //
01209 #if 1
01210             fliptest = qfalse;
01211             for (k=0 ; k<source->numpoints ; k++)
01212             {
01213                 if (k == i || k == l)
01214                     continue;
01215                 d = DotProduct (source->points[k], plane.normal) - plane.dist;
01216                 if (d < -ON_EPSILON)
01217                 {   // source is on the negative side, so we want all
01218                     // pass and target on the positive side
01219                     fliptest = qfalse;
01220                     break;
01221                 }
01222                 else if (d > ON_EPSILON)
01223                 {   // source is on the positive side, so we want all
01224                     // pass and target on the negative side
01225                     fliptest = qtrue;
01226                     break;
01227                 }
01228             }
01229             if (k == source->numpoints)
01230                 continue;       // planar with source portal
01231 #else
01232             fliptest = flipclip;
01233 #endif
01234             //
01235             // flip the normal if the source portal is backwards
01236             //
01237             if (fliptest)
01238             {
01239                 VectorSubtract (vec3_origin, plane.normal, plane.normal);
01240                 plane.dist = -plane.dist;
01241             }
01242 #if 1
01243             //
01244             // if all of the pass portal points are now on the positive side,
01245             // this is the seperating plane
01246             //
01247             counts[0] = counts[1] = counts[2] = 0;
01248             for (k=0 ; k<pass->numpoints ; k++)
01249             {
01250                 if (k==j)
01251                     continue;
01252                 d = DotProduct (pass->points[k], plane.normal) - plane.dist;
01253                 if (d < -ON_EPSILON)
01254                     break;
01255                 else if (d > ON_EPSILON)
01256                     counts[0]++;
01257                 else
01258                     counts[2]++;
01259             }
01260             if (k != pass->numpoints)
01261                 continue;   // points on negative side, not a seperating plane
01262                 
01263             if (!counts[0])
01264                 continue;   // planar with seperating plane
01265 #else
01266             k = (j+1)%pass->numpoints;
01267             d = DotProduct (pass->points[k], plane.normal) - plane.dist;
01268             if (d < -ON_EPSILON)
01269                 continue;
01270             k = (j+pass->numpoints-1)%pass->numpoints;
01271             d = DotProduct (pass->points[k], plane.normal) - plane.dist;
01272             if (d < -ON_EPSILON)
01273                 continue;           
01274 #endif
01275             //
01276             // flip the normal if we want the back side
01277             //
01278             if (flipclip)
01279             {
01280                 VectorSubtract (vec3_origin, plane.normal, plane.normal);
01281                 plane.dist = -plane.dist;
01282             }
01283 
01284             if (numseperators >= maxseperators)
01285                 Error("max seperators");
01286             seperators[numseperators] = plane;
01287             numseperators++;
01288             break;
01289         }
01290     }
01291     return numseperators;
01292 }

Here is the call graph for this function:

winding_t* AllocStackWinding pstack_t stack  ) 
 

Definition at line 81 of file visflow.c.

References Error(), pstack_s::freewindings, i, pstack_t, and pstack_s::windings.

Referenced by VisChopWinding().

00082 {
00083     int     i;
00084 
00085     for (i=0 ; i<3 ; i++)
00086     {
00087         if (stack->freewindings[i])
00088         {
00089             stack->freewindings[i] = 0;
00090             return &stack->windings[i];
00091         }
00092     }
00093 
00094     Error ("AllocStackWinding: failed");
00095 
00096     return NULL;
00097 }

Here is the call graph for this function:

void BasePortalVis int  portalnum  ) 
 

Definition at line 1505 of file visflow.c.

References c_flood, CountBits(), d, plane_t::dist, DotProduct, j, k, vportal_t::leaf, malloc(), memset(), plane_t::normal, vportal_t::nummightsee, winding_t::numpoints, numportals, p, vportal_t::plane, winding_t::points, portalbytes, vportal_t::portalflood, vportal_t::portalfront, portals, vportal_t::portalvis, vportal_t::removed, SimpleFlood(), w, and vportal_t::winding.

Referenced by CalcVis().

01506 {
01507     int         j, k;
01508     vportal_t   *tp, *p;
01509     float       d;
01510     winding_t   *w;
01511 
01512     p = portals+portalnum;
01513 
01514     if (p->removed)
01515         return;
01516 
01517     p->portalfront = malloc (portalbytes);
01518     memset (p->portalfront, 0, portalbytes);
01519 
01520     p->portalflood = malloc (portalbytes);
01521     memset (p->portalflood, 0, portalbytes);
01522     
01523     p->portalvis = malloc (portalbytes);
01524     memset (p->portalvis, 0, portalbytes);
01525     
01526     for (j=0, tp = portals ; j<numportals*2 ; j++, tp++)
01527     {
01528         if (j == portalnum)
01529             continue;
01530         if (tp->removed)
01531             continue;
01532         /*
01533         if (farplanedist >= 0)
01534         {
01535             vec3_t dir;
01536             VectorSubtract(p->origin, tp->origin, dir);
01537             if (VectorLength(dir) > farplanedist - p->radius - tp->radius)
01538                 continue;
01539         }
01540         */
01541         w = tp->winding;
01542         for (k=0 ; k<w->numpoints ; k++)
01543         {
01544             d = DotProduct (w->points[k], p->plane.normal)
01545                 - p->plane.dist;
01546             if (d > ON_EPSILON)
01547                 break;
01548         }
01549         if (k == w->numpoints)
01550             continue;   // no points on front
01551 
01552         w = p->winding;
01553         for (k=0 ; k<w->numpoints ; k++)
01554         {
01555             d = DotProduct (w->points[k], tp->plane.normal)
01556                 - tp->plane.dist;
01557             if (d < -ON_EPSILON)
01558                 break;
01559         }
01560         if (k == w->numpoints)
01561             continue;   // no points on front
01562 
01563         p->portalfront[j>>3] |= (1<<(j&7));
01564     }
01565     
01566     SimpleFlood (p, p->leaf);
01567 
01568     p->nummightsee = CountBits (p->portalflood, numportals*2);
01569 //  _printf ("portal %i: %i mightsee\n", portalnum, p->nummightsee);
01570     c_flood += p->nummightsee;
01571 }

Here is the call graph for this function:

void BetterPortalVis int  portalnum  ) 
 

Definition at line 1641 of file visflow.c.

References c_vis, CountBits(), vportal_t::leaf, vportal_t::nummightsee, numportals, p, vportal_t::portalflood, portals, vportal_t::portalvis, RecursiveLeafBitFlow(), and vportal_t::removed.

01642 {
01643     vportal_t   *p;
01644 
01645     p = portals+portalnum;
01646 
01647     if (p->removed)
01648         return;
01649 
01650     RecursiveLeafBitFlow (p->leaf, p->portalflood, p->portalvis);
01651 
01652     // build leaf vis information
01653     p->nummightsee = CountBits (p->portalvis, numportals*2);
01654     c_vis += p->nummightsee;
01655 }

Here is the call graph for this function:

void CheckStack leaf_t leaf,
threaddata_t thread
 

Definition at line 64 of file visflow.c.

References Error(), pstack_s::leaf, leaf_t, pstack_s::next, p, p2, threaddata_t::pstack_head, and pstack_t.

00065 {
00066     pstack_t    *p, *p2;
00067 
00068     for (p=thread->pstack_head.next ; p ; p=p->next)
00069     {
00070 //      _printf ("=");
00071         if (p->leaf == leaf)
00072             Error ("CheckStack: leaf recursion");
00073         for (p2=thread->pstack_head.next ; p2 != p ; p2=p2->next)
00074             if (p2->leaf == p->leaf)
00075                 Error ("CheckStack: late leaf recursion");
00076     }
00077 //  _printf ("\n");
00078 }

Here is the call graph for this function:

winding_t* ClipToSeperators winding_t source,
winding_t pass,
winding_t target,
qboolean  flipclip,
pstack_t stack
 

Definition at line 237 of file visflow.c.

References d, plane_t::dist, DotProduct, Error(), i, j, k, l, length(), plane_t::normal, winding_t::numpoints, pstack_s::numseperators, vportal_t::origin, winding_t::points, pstack_s::portal, pstack_t, qboolean, vportal_t::radius, pstack_s::seperators, source, sqrt(), v1, v2, vec3_origin, vec3_t, vec_t, VectorSubtract, and VisChopWinding().

Referenced by RecursiveLeafFlow(), and RecursivePassagePortalFlow().

00238 {
00239     int         i, j, k, l;
00240     plane_t     plane;
00241     vec3_t      v1, v2;
00242     float       d;
00243     vec_t       length;
00244     int         counts[3];
00245     qboolean        fliptest;
00246 
00247     // check all combinations   
00248     for (i=0 ; i<source->numpoints ; i++)
00249     {
00250         l = (i+1)%source->numpoints;
00251         VectorSubtract (source->points[l] , source->points[i], v1);
00252 
00253         // find a vertex of pass that makes a plane that puts all of the
00254         // vertexes of pass on the front side and all of the vertexes of
00255         // source on the back side
00256         for (j=0 ; j<pass->numpoints ; j++)
00257         {
00258             VectorSubtract (pass->points[j], source->points[i], v2);
00259 
00260             plane.normal[0] = v1[1]*v2[2] - v1[2]*v2[1];
00261             plane.normal[1] = v1[2]*v2[0] - v1[0]*v2[2];
00262             plane.normal[2] = v1[0]*v2[1] - v1[1]*v2[0];
00263             
00264             // if points don't make a valid plane, skip it
00265 
00266             length = plane.normal[0] * plane.normal[0]
00267             + plane.normal[1] * plane.normal[1]
00268             + plane.normal[2] * plane.normal[2];
00269             
00270             if (length < ON_EPSILON)
00271                 continue;
00272 
00273             length = 1/sqrt(length);
00274             
00275             plane.normal[0] *= length;
00276             plane.normal[1] *= length;
00277             plane.normal[2] *= length;
00278 
00279             plane.dist = DotProduct (pass->points[j], plane.normal);
00280 
00281             //
00282             // find out which side of the generated seperating plane has the
00283             // source portal
00284             //
00285 #if 1
00286             fliptest = qfalse;
00287             for (k=0 ; k<source->numpoints ; k++)
00288             {
00289                 if (k == i || k == l)
00290                     continue;
00291                 d = DotProduct (source->points[k], plane.normal) - plane.dist;
00292                 if (d < -ON_EPSILON)
00293                 {   // source is on the negative side, so we want all
00294                     // pass and target on the positive side
00295                     fliptest = qfalse;
00296                     break;
00297                 }
00298                 else if (d > ON_EPSILON)
00299                 {   // source is on the positive side, so we want all
00300                     // pass and target on the negative side
00301                     fliptest = qtrue;
00302                     break;
00303                 }
00304             }
00305             if (k == source->numpoints)
00306                 continue;       // planar with source portal
00307 #else
00308             fliptest = flipclip;
00309 #endif
00310             //
00311             // flip the normal if the source portal is backwards
00312             //
00313             if (fliptest)
00314             {
00315                 VectorSubtract (vec3_origin, plane.normal, plane.normal);
00316                 plane.dist = -plane.dist;
00317             }
00318 #if 1
00319             //
00320             // if all of the pass portal points are now on the positive side,
00321             // this is the seperating plane
00322             //
00323             counts[0] = counts[1] = counts[2] = 0;
00324             for (k=0 ; k<pass->numpoints ; k++)
00325             {
00326                 if (k==j)
00327                     continue;
00328                 d = DotProduct (pass->points[k], plane.normal) - plane.dist;
00329                 if (d < -ON_EPSILON)
00330                     break;
00331                 else if (d > ON_EPSILON)
00332                     counts[0]++;
00333                 else
00334                     counts[2]++;
00335             }
00336             if (k != pass->numpoints)
00337                 continue;   // points on negative side, not a seperating plane
00338                 
00339             if (!counts[0])
00340                 continue;   // planar with seperating plane
00341 #else
00342             k = (j+1)%pass->numpoints;
00343             d = DotProduct (pass->points[k], plane.normal) - plane.dist;
00344             if (d < -ON_EPSILON)
00345                 continue;
00346             k = (j+pass->numpoints-1)%pass->numpoints;
00347             d = DotProduct (pass->points[k], plane.normal) - plane.dist;
00348             if (d < -ON_EPSILON)
00349                 continue;           
00350 #endif
00351             //
00352             // flip the normal if we want the back side
00353             //
00354             if (flipclip)
00355             {
00356                 VectorSubtract (vec3_origin, plane.normal, plane.normal);
00357                 plane.dist = -plane.dist;
00358             }
00359 
00360 #ifdef SEPERATORCACHE
00361             stack->seperators[flipclip][stack->numseperators[flipclip]] = plane;
00362             if (++stack->numseperators[flipclip] >= MAX_SEPERATORS)
00363                 Error("MAX_SEPERATORS");
00364 #endif
00365             //MrE: fast check first
00366             d = DotProduct (stack->portal->origin, plane.normal) - plane.dist;
00367             //if completely at the back of the seperator plane
00368             if (d < -stack->portal->radius)
00369                 return NULL;
00370             //if completely on the front of the seperator plane
00371             if (d > stack->portal->radius)
00372                 break;
00373 
00374             //
00375             // clip target by the seperating plane
00376             //
00377             target = VisChopWinding (target, stack, &plane);
00378             if (!target)
00379                 return NULL;        // target is not visible
00380 
00381             break;      // optimization by Antony Suter
00382         }
00383     }
00384     
00385     return target;
00386 }

Here is the call graph for this function:

int CountBits byte bits,
int  numbits
 

Definition at line 43 of file visflow.c.

References bits, byte, c, and i.

Referenced by BasePortalVis(), BetterPortalVis(), LeafVectorFromPortalVector(), and PortalFlow().

00044 {
00045     int     i;
00046     int     c;
00047 
00048     c = 0;
00049     for (i=0 ; i<numbits ; i++)
00050         if (bits[i>>3] & (1<<(i&7)) )
00051             c++;
00052 
00053     return c;
00054 }

void CreatePassages int  portalnum  ) 
 

Definition at line 1303 of file visflow.c.

References _printf(), AddSeperators(), passage_s::cansee, d, plane_t::dist, DotProduct, i, in, j, k, vportal_t::leaf, leaf_t, leafs, malloc(), MAX_SEPERATORS, memcpy(), memset(), n, passage_s::next, plane_t::normal, winding_t::numpoints, numportals, leaf_s::numportals, vportal_t::origin, p, passage_t, PassageChopWinding(), vportal_t::passages, winding_t::points, portalbytes, vportal_t::portalflood, portals, leaf_s::portals, qfalse, qtrue, vportal_t::radius, vportal_t::removed, sorted_portals, vportal_t::status, w, and vportal_t::winding.

Referenced by CalcPassagePortalVis(), and CalcPassageVis().

01304 {
01305     int i, j, k, n, numseperators, numsee;
01306     float d;
01307     vportal_t *portal, *p, *target;
01308     leaf_t *leaf;
01309     passage_t   *passage, *lastpassage;
01310     plane_t seperators[MAX_SEPERATORS*2];
01311     winding_t *w;
01312     winding_t in, out, *res;
01313 
01314 #ifdef MREDEBUG
01315     _printf("\r%6d", portalnum);
01316 #endif
01317 
01318     portal = sorted_portals[portalnum];
01319 
01320     if (portal->removed)
01321     {
01322         portal->status = stat_done;
01323         return;
01324     }
01325 
01326     lastpassage = NULL;
01327     leaf = &leafs[portal->leaf];
01328     for (i = 0; i < leaf->numportals; i++)
01329     {
01330         target = leaf->portals[i];
01331         if (target->removed)
01332             continue;
01333 
01334         passage = (passage_t *) malloc(sizeof(passage_t) + portalbytes);
01335         memset(passage, 0, sizeof(passage_t) + portalbytes);
01336         numseperators = AddSeperators(portal->winding, target->winding, qfalse, seperators, MAX_SEPERATORS*2);
01337         numseperators += AddSeperators(target->winding, portal->winding, qtrue, &seperators[numseperators], MAX_SEPERATORS*2-numseperators);
01338 
01339         passage->next = NULL;
01340         if (lastpassage)
01341             lastpassage->next = passage;
01342         else
01343             portal->passages = passage;
01344         lastpassage = passage;
01345 
01346         numsee = 0;
01347         //create the passage->cansee
01348         for (j = 0; j < numportals * 2; j++)
01349         {
01350             p = &portals[j];
01351             if (p->removed)
01352                 continue;
01353             if ( ! (target->portalflood[j >> 3] & (1<<(j&7)) ) )
01354                 continue;
01355             if ( ! (portal->portalflood[j >> 3] & (1<<(j&7)) ) )
01356                 continue;
01357             for (k = 0; k < numseperators; k++)
01358             {
01359                 //
01360                 d = DotProduct (p->origin, seperators[k].normal) - seperators[k].dist;
01361                 //if completely at the back of the seperator plane
01362                 if (d < -p->radius + ON_EPSILON)
01363                     break;
01364                 w = p->winding;
01365                 for (n = 0; n < w->numpoints; n++)
01366                 {
01367                     d = DotProduct (w->points[n], seperators[k].normal) - seperators[k].dist;
01368                     //if at the front of the seperator
01369                     if (d > ON_EPSILON)
01370                         break;
01371                 }
01372                 //if no points are at the front of the seperator
01373                 if (n >= w->numpoints)
01374                     break;
01375             }
01376             if (k < numseperators)
01377                 continue;
01378             memcpy(&in, p->winding, sizeof(winding_t));
01379             for (k = 0; k < numseperators; k++)
01380             {
01381                 res = PassageChopWinding(&in, &out, &seperators[k]);
01382                 if (res == &out)
01383                     memcpy(&in, &out, sizeof(winding_t));
01384                 if (res == NULL)
01385                     break;
01386             }
01387             if (k < numseperators)
01388                 continue;
01389             passage->cansee[j >> 3] |= (1<<(j&7));
01390             numsee++;
01391         }
01392     }
01393 }

Here is the call graph for this function:

void FreeStackWinding winding_t w,
pstack_t stack
 

Definition at line 99 of file visflow.c.

References Error(), pstack_s::freewindings, i, pstack_t, w, and pstack_s::windings.

Referenced by VisChopWinding().

00100 {
00101     int     i;
00102 
00103     i = w - stack->windings;
00104 
00105     if (i<0 || i>2)
00106         return;     // not from local
00107 
00108     if (stack->freewindings[i])
00109         Error ("FreeStackWinding: allready free");
00110     stack->freewindings[i] = 1;
00111 }

Here is the call graph for this function:

winding_t* PassageChopWinding winding_t in,
winding_t out,
plane_t split
 

Definition at line 1059 of file visflow.c.

References plane_t::dist, DotProduct, i, in, j, plane_t::normal, winding_t::numpoints, p2, winding_t::points, SIDE_ON, vec3_t, vec_t, and VectorCopy.

Referenced by CreatePassages().

01060 {
01061     vec_t   dists[128];
01062     int     sides[128];
01063     int     counts[3];
01064     vec_t   dot;
01065     int     i, j;
01066     vec_t   *p1, *p2;
01067     vec3_t  mid;
01068     winding_t   *neww;
01069 
01070     counts[0] = counts[1] = counts[2] = 0;
01071 
01072     // determine sides for each point
01073     for (i=0 ; i<in->numpoints ; i++)
01074     {
01075         dot = DotProduct (in->points[i], split->normal);
01076         dot -= split->dist;
01077         dists[i] = dot;
01078         if (dot > ON_EPSILON)
01079             sides[i] = SIDE_FRONT;
01080         else if (dot < -ON_EPSILON)
01081             sides[i] = SIDE_BACK;
01082         else
01083         {
01084             sides[i] = SIDE_ON;
01085         }
01086         counts[sides[i]]++;
01087     }
01088 
01089     if (!counts[1])
01090         return in;      // completely on front side
01091     
01092     if (!counts[0])
01093     {
01094         return NULL;
01095     }
01096 
01097     sides[i] = sides[0];
01098     dists[i] = dists[0];
01099     
01100     neww = out;
01101 
01102     neww->numpoints = 0;
01103 
01104     for (i=0 ; i<in->numpoints ; i++)
01105     {
01106         p1 = in->points[i];
01107 
01108         if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
01109         {
01110             return in;      // can't chop -- fall back to original
01111         }
01112 
01113         if (sides[i] == SIDE_ON)
01114         {
01115             VectorCopy (p1, neww->points[neww->numpoints]);
01116             neww->numpoints++;
01117             continue;
01118         }
01119     
01120         if (sides[i] == SIDE_FRONT)
01121         {
01122             VectorCopy (p1, neww->points[neww->numpoints]);
01123             neww->numpoints++;
01124         }
01125         
01126         if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
01127             continue;
01128             
01129         if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
01130         {
01131             return in;      // can't chop -- fall back to original
01132         }
01133 
01134         // generate a split point
01135         p2 = in->points[(i+1)%in->numpoints];
01136         
01137         dot = dists[i] / (dists[i]-dists[i+1]);
01138         for (j=0 ; j<3 ; j++)
01139         {   // avoid round off error when possible
01140             if (split->normal[j] == 1)
01141                 mid[j] = split->dist;
01142             else if (split->normal[j] == -1)
01143                 mid[j] = -split->dist;
01144             else
01145                 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
01146         }
01147             
01148         VectorCopy (mid, neww->points[neww->numpoints]);
01149         neww->numpoints++;
01150     }
01151     
01152     return neww;
01153 }

void PassageFlow int  portalnum  ) 
 

Definition at line 751 of file visflow.c.

References _printf(), data, i, memset(), p, vportal_t::plane, vportal_t::portalflood, RecursivePassageFlow(), vportal_t::removed, sorted_portals, vportal_t::status, and vportal_t::winding.

Referenced by CalcPassageVis().

00752 {
00753     threaddata_t    data;
00754     int             i;
00755     vportal_t       *p;
00756 //  int             c_might, c_can;
00757 
00758 #ifdef MREDEBUG
00759     _printf("\r%6d", portalnum);
00760 #endif
00761 
00762     p = sorted_portals[portalnum];
00763 
00764     if (p->removed)
00765     {
00766         p->status = stat_done;
00767         return;
00768     }
00769 
00770     p->status = stat_working;
00771 
00772 //  c_might = CountBits (p->portalflood, numportals*2);
00773 
00774     memset (&data, 0, sizeof(data));
00775     data.base = p;
00776     
00777     data.pstack_head.portal = p;
00778     data.pstack_head.source = p->winding;
00779     data.pstack_head.portalplane = p->plane;
00780     data.pstack_head.depth = 0;
00781     for (i=0 ; i<portallongs ; i++)
00782         ((long *)data.pstack_head.mightsee)[i] = ((long *)p->portalflood)[i];
00783 
00784     RecursivePassageFlow (p, &data, &data.pstack_head);
00785 
00786     p->status = stat_done;
00787 
00788     /*
00789     c_can = CountBits (p->portalvis, numportals*2);
00790 
00791     qprintf ("portal:%4i  mightsee:%4i  cansee:%4i (%i chains)\n", 
00792         (int)(p - portals), c_might, c_can, data.c_chains);
00793     */
00794 }

Here is the call graph for this function:

void PassageMemory void   ) 
 

Definition at line 1395 of file visflow.c.

References _printf(), i, j, vportal_t::leaf, leaf_t, leafs, numportals, leaf_s::numportals, passage_t, leaf_s::portals, vportal_t::removed, and sorted_portals.

Referenced by CalcPassagePortalVis(), and CalcPassageVis().

01396 {
01397     int i, j, totalmem, totalportals;
01398     vportal_t *portal, *target;
01399     leaf_t *leaf;
01400 
01401     totalmem = 0;
01402     totalportals = 0;
01403     for (i = 0; i < numportals; i++)
01404     {
01405         portal = sorted_portals[i];
01406         if (portal->removed)
01407             continue;
01408         leaf = &leafs[portal->leaf];
01409         for (j = 0; j < leaf->numportals; j++)
01410         {
01411             target = leaf->portals[j];
01412             if (target->removed)
01413                 continue;
01414             totalmem += sizeof(passage_t) + portalbytes;
01415             totalportals++;
01416         }
01417     }
01418     _printf("%7i average number of passages per leaf\n", totalportals / numportals);
01419     _printf("%7i MB required passage memory\n", totalmem >> 10 >> 10);
01420 }

Here is the call graph for this function:

void PassagePortalFlow int  portalnum  ) 
 

Definition at line 1014 of file visflow.c.

References _printf(), data, i, memset(), p, vportal_t::plane, vportal_t::portalflood, RecursivePassagePortalFlow(), vportal_t::removed, sorted_portals, vportal_t::status, and vportal_t::winding.

Referenced by CalcPassagePortalVis().

01015 {
01016     threaddata_t    data;
01017     int             i;
01018     vportal_t       *p;
01019 //  int             c_might, c_can;
01020 
01021 #ifdef MREDEBUG
01022     _printf("\r%6d", portalnum);
01023 #endif
01024 
01025     p = sorted_portals[portalnum];
01026 
01027     if (p->removed)
01028     {
01029         p->status = stat_done;
01030         return;
01031     }
01032 
01033     p->status = stat_working;
01034 
01035 //  c_might = CountBits (p->portalflood, numportals*2);
01036 
01037     memset (&data, 0, sizeof(data));
01038     data.base = p;
01039     
01040     data.pstack_head.portal = p;
01041     data.pstack_head.source = p->winding;
01042     data.pstack_head.portalplane = p->plane;
01043     data.pstack_head.depth = 0;
01044     for (i=0 ; i<portallongs ; i++)
01045         ((long *)data.pstack_head.mightsee)[i] = ((long *)p->portalflood)[i];
01046 
01047     RecursivePassagePortalFlow (p, &data, &data.pstack_head);
01048 
01049     p->status = stat_done;
01050 
01051     /*
01052     c_can = CountBits (p->portalvis, numportals*2);
01053 
01054     qprintf ("portal:%4i  mightsee:%4i  cansee:%4i (%i chains)\n", 
01055         (int)(p - portals), c_might, c_can, data.c_chains);
01056     */
01057 }

Here is the call graph for this function:

void PortalFlow int  portalnum  ) 
 

Definition at line 624 of file visflow.c.

References _printf(), CountBits(), data, i,