#include "qbsp.h"
#include "l_mem.h"
Include dependency graph for portals.c:

Go to the source code of this file.
|
|
Definition at line 361 of file portals.c. Referenced by BaseWindingForNode(). |
|
|
|
|
|
Definition at line 362 of file portals.c. Referenced by SplitNodePortals(). |
|
||||||||||||||||
|
Definition at line 192 of file portals.c. References Error(), portal_s::next, node_t, portal_s::nodes, p, portal_t, and node_s::portals. 00193 {
00194 if (p->nodes[0] || p->nodes[1])
00195 Error ("AddPortalToNode: allready included");
00196
00197 p->nodes[0] = front;
00198 p->next[0] = front->portals;
00199 front->portals = p;
00200
00201 p->nodes[1] = back;
00202 p->next[1] = back->portals;
00203 back->portals = p;
00204 } //end of the function AddPortalToNodes
|
Here is the call graph for this function:

|
|
Definition at line 39 of file portals.c. References c_active_portals, c_peak_portals, c_portalmemory, GetMemory(), MemorySize(), memset(), numthreads, p, and portal_t. Referenced by MakeHeadnodePortals(), MakeNodePortal(), and SplitNodePortals(). 00040 {
00041 portal_t *p;
00042
00043 p = GetMemory(sizeof(portal_t));
00044 memset (p, 0, sizeof(portal_t));
00045
00046 if (numthreads == 1)
00047 {
00048 c_active_portals++;
00049 if (c_active_portals > c_peak_portals)
00050 {
00051 c_peak_portals = c_active_portals;
00052 } //end if
00053 c_portalmemory += MemorySize(p);
00054 } //end if
00055
00056 // p->nextportal = portallist;
00057 // portallist = p;
00058
00059 return p;
00060 } //end of the function AllocPortal
|
Here is the call graph for this function:

|
|
Definition at line 364 of file portals.c. References BASE_WINDING_EPSILON, BaseWindingForPlane(), node_s::children, ChopWindingInPlace(), plane_t::dist, mapplanes, n, node_t, plane_t::normal, node_s::parent, node_s::planenum, vec3_origin, vec3_t, vec_t, VectorSubtract, and w. 00365 {
00366 winding_t *w;
00367 node_t *n;
00368 plane_t *plane;
00369 vec3_t normal;
00370 vec_t dist;
00371
00372 w = BaseWindingForPlane (mapplanes[node->planenum].normal
00373 , mapplanes[node->planenum].dist);
00374
00375 // clip by all the parents
00376 for (n=node->parent ; n && w ; )
00377 {
00378 plane = &mapplanes[n->planenum];
00379
00380 if (n->children[0] == node)
00381 { // take front
00382 ChopWindingInPlace (&w, plane->normal, plane->dist, BASE_WINDING_EPSILON);
00383 }
00384 else
00385 { // take back
00386 VectorSubtract (vec3_origin, plane->normal, normal);
00387 dist = -plane->dist;
00388 ChopWindingInPlace (&w, normal, dist, BASE_WINDING_EPSILON);
00389 }
00390 node = n;
00391 n = n->parent;
00392 }
00393
00394 return w;
00395 } //end of the function BaseWindingForNode
|
Here is the call graph for this function:

|
|
Definition at line 588 of file portals.c. References AddPointToBounds(), ClearBounds(), i, node_s::maxs, node_s::mins, portal_s::next, node_t, portal_s::nodes, winding_t::numpoints, winding_t::p, p, portal_t, node_s::portals, s, and portal_s::winding. 00589 {
00590 portal_t *p;
00591 int s;
00592 int i;
00593
00594 // calc mins/maxs for both leaves and nodes
00595 ClearBounds (node->mins, node->maxs);
00596 for (p = node->portals ; p ; p = p->next[s])
00597 {
00598 s = (p->nodes[1] == node);
00599 for (i=0 ; i<p->winding->numpoints ; i++)
00600 AddPointToBounds (p->winding->p[i], node->mins, node->maxs);
00601 }
00602 } //end of the function CalcNodeBounds
|
Here is the call graph for this function:

|
|
Definition at line 101 of file portals.c. References c, node_s::children, node_s::contents, node_t, and node_s::planenum. Referenced by Portal_VisFlood(). 00102 {
00103 int c1, c2, c;
00104
00105 if (node->planenum == PLANENUM_LEAF)
00106 return node->contents;
00107
00108 c1 = ClusterContents(node->children[0]);
00109 c2 = ClusterContents(node->children[1]);
00110 c = c1|c2;
00111
00112 // a cluster may include some solid detail areas, but
00113 // still be seen into
00114 if ( ! (c1&CONTENTS_SOLID) || ! (c2&CONTENTS_SOLID) )
00115 c &= ~CONTENTS_SOLID;
00116 return c;
00117 } //end of the function ClusterContents
|
|
|
Definition at line 961 of file portals.c. 00962 {
00963 c_outside = 0;
00964 c_inside = 0;
00965 c_solid = 0;
00966 Log_Print("------- FillOutside --------\n");
00967 FillOutside_r (headnode);
00968 Log_Print("%5i solid leaves\n", c_solid);
00969 Log_Print("%5i leaves filled\n", c_outside);
00970 Log_Print("%5i inside leaves\n", c_inside);
00971 } //end of the function FillOutside
|
|
|
Definition at line 927 of file portals.c. References c_inside, c_outside, c_solid, node_s::children, node_s::contents, FillOutside_r(), node_t, node_s::occupied, and node_s::planenum. 00928 {
00929 if (node->planenum != PLANENUM_LEAF)
00930 {
00931 FillOutside_r (node->children[0]);
00932 FillOutside_r (node->children[1]);
00933 return;
00934 } //end if
00935 // anything not reachable by an entity
00936 // can be filled away (by setting solid contents)
00937 if (!node->occupied)
00938 {
00939 if (!(node->contents & CONTENTS_SOLID))
00940 {
00941 c_outside++;
00942 node->contents |= CONTENTS_SOLID;
00943 } //end if
00944 else
00945 {
00946 c_solid++;
00947 } //end else
00948 } //end if
00949 else
00950 {
00951 c_inside++;
00952 } //end else
00953 } //end of the function FillOutside_r
|
Here is the call graph for this function:

|
|
Definition at line 1046 of file portals.c. References node_s::area, c_areas, node_s::children, node_s::contents, FindAreas_r(), FloodAreas_r(), node_t, node_s::occupied, and node_s::planenum. 01047 {
01048 if (node->planenum != PLANENUM_LEAF)
01049 {
01050 FindAreas_r (node->children[0]);
01051 FindAreas_r (node->children[1]);
01052 return;
01053 }
01054
01055 if (node->area)
01056 return; // allready got it
01057
01058 if (node->contents & CONTENTS_SOLID)
01059 return;
01060
01061 if (!node->occupied)
01062 return; // not reachable by entities
01063
01064 // area portals are allways only flooded into, never
01065 // out of
01066 if (node->contents == CONTENTS_AREAPORTAL)
01067 return;
01068
01069 c_areas++;
01070 FloodAreas_r (node);
01071 } //end of the function FindAreas_r
|
Here is the call graph for this function:

|
|
Definition at line 1175 of file portals.c. References node_s::brushlist, bspbrush_t, mapbrush_s::contents, node_s::contents, DotProduct, side_s::flags, i, j, Log_Print(), mapbrush_t, mapplanes, n, bspbrush_s::next, node_t, portal_s::nodes, plane_t::normal, mapbrush_s::numsides, portal_s::onnode, bspbrush_s::original, mapbrush_s::original_sides, p, p2, side_s::planenum, node_s::planenum, portal_t, portal_s::side, side_t, portal_s::sidefound, side_s::texinfo, and VisibleContents(). Referenced by MarkVisibleSides_r(). 01176 {
01177 int viscontents;
01178 bspbrush_t *bb;
01179 mapbrush_t *brush;
01180 node_t *n;
01181 int i,j;
01182 int planenum;
01183 side_t *side, *bestside;
01184 float dot, bestdot;
01185 plane_t *p1, *p2;
01186
01187 // decide which content change is strongest
01188 // solid > lava > water, etc
01189 viscontents = VisibleContents (p->nodes[0]->contents ^ p->nodes[1]->contents);
01190 if (!viscontents)
01191 return;
01192
01193 planenum = p->onnode->planenum;
01194 bestside = NULL;
01195 bestdot = 0;
01196
01197 for (j=0 ; j<2 ; j++)
01198 {
01199 n = p->nodes[j];
01200 p1 = &mapplanes[p->onnode->planenum];
01201 for (bb=n->brushlist ; bb ; bb=bb->next)
01202 {
01203 brush = bb->original;
01204 if ( !(brush->contents & viscontents) )
01205 continue;
01206 for (i=0 ; i<brush->numsides ; i++)
01207 {
01208 side = &brush->original_sides[i];
01209 if (side->flags & SFL_BEVEL)
01210 continue;
01211 if (side->texinfo == TEXINFO_NODE)
01212 continue; // non-visible
01213 if ((side->planenum&~1) == planenum)
01214 { // exact match
01215 bestside = &brush->original_sides[i];
01216 goto gotit;
01217 } //end if
01218 // see how close the match is
01219 p2 = &mapplanes[side->planenum&~1];
01220 dot = DotProduct (p1->normal, p2->normal);
01221 if (dot > bestdot)
01222 {
01223 bestdot = dot;
01224 bestside = side;
01225 } //end if
01226 } //end for
01227 } //end for
01228 } //end for
01229
01230 gotit:
01231 if (!bestside)
01232 Log_Print("WARNING: side not found for portal\n");
01233
01234 p->sidefound = true;
01235 p->side = bestside;
01236 } //end of the function FindPortalSide
|
Here is the call graph for this function:

|
|
Definition at line 1161 of file portals.c. 01162 {
01163 Log_Print("--- FloodAreas ---\n");
01164 FindAreas_r (tree->headnode);
01165 SetAreaPortalAreas_r (tree->headnode);
01166 Log_Print("%5i areas\n", c_areas);
01167 } //end of the function FloodAreas
|
|
|
Definition at line 989 of file portals.c. References node_s::area, b, node_s::brushlist, bspbrush_t, c_areas, node_s::contents, e, entities, mapbrush_s::entitynum, FloodAreas_r(), Log_Print(), portal_s::next, node_t, portal_s::nodes, node_s::occupied, bspbrush_s::original, p, Portal_EntityFlood(), portal_t, entity_t::portalareas, node_s::portals, and s. 00990 {
00991 portal_t *p;
00992 int s;
00993 bspbrush_t *b;
00994 entity_t *e;
00995
00996 if (node->contents == CONTENTS_AREAPORTAL)
00997 {
00998 // this node is part of an area portal
00999 b = node->brushlist;
01000 e = &entities[b->original->entitynum];
01001
01002 // if the current area has allready touched this
01003 // portal, we are done
01004 if (e->portalareas[0] == c_areas || e->portalareas[1] == c_areas)
01005 return;
01006
01007 // note the current area as bounding the portal
01008 if (e->portalareas[1])
01009 {
01010 Log_Print("WARNING: areaportal entity %i touches > 2 areas\n", b->original->entitynum);
01011 return;
01012 }
01013 if (e->portalareas[0])
01014 e->portalareas[1] = c_areas;
01015 else
01016 e->portalareas[0] = c_areas;
01017
01018 return;
01019 } //end if
01020
01021 if (node->area)
01022 return; // allready got it
01023 node->area = c_areas;
01024
01025 for (p=node->portals ; p ; p = p->next[s])
01026 {
01027 s = (p->nodes[1] == node);
01028 #if 0
01029 if (p->nodes[!s]->occupied)
01030 continue;
01031 #endif
01032 if (!Portal_EntityFlood (p, s))
01033 continue;
01034
01035 FloodAreas_r (p->nodes[!s]);
01036 } //end for
01037 } //end of the function FloodAreas_r
|
Here is the call graph for this function:

|
|
Definition at line 843 of file portals.c. 00844 {
00845 int i;
00846 int x, y;
00847 vec3_t origin;
00848 char *cl;
00849 qboolean inside;
00850 node_t *headnode;
00851
00852 headnode = tree->headnode;
00853 Log_Print("------ FloodEntities -------\n");
00854 inside = false;
00855 tree->outside_node.occupied = 0;
00856
00857 //start at entity 1 not the world ( = 0)
00858 for (i = 1; i < num_entities; i++)
00859 {
00860 GetVectorForKey(&entities[i], "origin", origin);
00861 if (VectorCompare(origin, vec3_origin)) continue;
00862
00863 cl = ValueForKey(&entities[i], "classname");
00864 origin[2] += 1; //so objects on floor are ok
00865
00866 // Log_Print("flooding from entity %d: %s\n", i, cl);
00867 //nudge playerstart around if needed so clipping hulls allways
00868 //have a valid point
00869 if (!strcmp(cl, "info_player_start"))
00870 {
00871 for (x = -16; x <= 16; x += 16)
00872 {
00873 for (y = -16; y <= 16; y += 16)
00874 {
00875 origin[0] += x;
00876 origin[1] += y;
00877 if (PlaceOccupant(headnode, origin, &entities[i]))
00878 {
00879 inside = true;
00880 x = 999; //stop for this info_player_start
00881 break;
00882 } //end if
00883 origin[0] -= x;
00884 origin[1] -= y;
00885 } //end for
00886 } //end for
00887 } //end if
00888 else
00889 {
00890 if (PlaceOccupant(headnode, origin, &entities[i]))
00891 {
00892 inside = true;
00893 } //end if
00894 } //end else
00895 } //end for
00896
00897 if (!inside)
00898 {
00899 Log_Print("WARNING: no entities inside\n");
00900 } //end if
00901 else if (tree->outside_node.occupied)
00902 {
00903 Log_Print("WARNING: entity reached from outside\n");
00904 } //end else if
00905
00906 return (qboolean)(inside && !tree->outside_node.occupied);
00907 } //end of the function FloodEntities
|
|
|
Definition at line 728 of file portals.c. References firstnode, portal_s::next, node_t, portal_s::nodes, node_s::occupied, p, P_AddNodeToList(), P_NextNodeFromList(), Portal_EntityFlood(), portal_t, node_s::portals, and s. Referenced by PlaceOccupant(). 00729 {
00730 node_t *node;
00731 portal_t *p;
00732 int s;
00733
00734 firstnode->occupied = 1;
00735 P_AddNodeToList(firstnode);
00736
00737 for (node = P_NextNodeFromList(); node; node = P_NextNodeFromList())
00738 {
00739 for (p = node->portals; p; p = p->next[s])
00740 {
00741 s = (p->nodes[1] == node);
00742 //if the node at the other side of the portal is occupied already
00743 if (p->nodes[!s]->occupied) continue;
00744 //if it isn't possible to flood through this portal
00745 if (!Portal_EntityFlood(p, s)) continue;
00746 //
00747 p->nodes[!s]->occupied = node->occupied + 1;
00748 //
00749 P_AddNodeToList(p->nodes[!s]);
00750 } //end for
00751 } //end for
00752 } //end of the function FloodPortals
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 761 of file portals.c. References Error(), FloodPortals_r(), Log_Print(), portal_s::next, node_t, portal_s::nodes, numrec, node_s::occupied, p, Portal_EntityFlood(), portal_t, node_s::portals, and s. 00762 {
00763 portal_t *p;
00764 int s;
00765 // int i;
00766
00767 Log_Print("\r%6d", ++numrec);
00768
00769 if (node->occupied) Error("FloodPortals_r: node already occupied\n");
00770 if (!node)
00771 {
00772 Error("FloodPortals_r: NULL node\n");
00773 } //end if*/
00774 node->occupied = dist;
00775
00776 for (p = node->portals; p; p = p->next[s])
00777 {
00778 s = (p->nodes[1] == node);
00779 //if the node at the other side of the portal is occupied already
00780 if (p->nodes[!s]->occupied) continue;
00781 //if it isn't possible to flood through this portal
00782 if (!Portal_EntityFlood(p, s)) continue;
00783 //flood recursively through the current portal
00784 FloodPortals_r(p->nodes[!s], dist+1);
00785 } //end for
00786 Log_Print("\r%6d", --numrec);
00787 } //end of the function FloodPortals_r
|
Here is the call graph for this function:

|
|
Definition at line 67 of file portals.c. 00068 {
00069 if (p->winding) FreeWinding(p->winding);
00070 if (numthreads == 1)
00071 {
00072 c_active_portals--;
00073 c_portalmemory -= MemorySize(p);
00074 } //end if
00075 FreeMemory(p);
00076 } //end of the function FreePortal
|
|
|
Definition at line 295 of file portals.c. 00296 {
00297 vec3_t bounds[2];
00298 int i, j, n;
00299 portal_t *p, *portals[6];
00300 plane_t bplanes[6], *pl;
00301 node_t *node;
00302
00303 node = tree->headnode;
00304
00305 // pad with some space so there will never be null volume leaves
00306 for (i=0 ; i<3 ; i++)
00307 {
00308 bounds[0][i] = tree->mins[i] - SIDESPACE;
00309 bounds[1][i] = tree->maxs[i] + SIDESPACE;
00310 if ( bounds[0][i] > bounds[1][i] ) {
00311 Error("empty BSP tree");
00312 }
00313 }
00314
00315 tree->outside_node.planenum = PLANENUM_LEAF;
00316 tree->outside_node.brushlist = NULL;
00317 tree->outside_node.portals = NULL;
00318 tree->outside_node.contents = 0;
00319
00320 for (i=0 ; i<3 ; i++)
00321 for (j=0 ; j<2 ; j++)
00322 {
00323 n = j*3 + i;
00324
00325 p = AllocPortal ();
00326 portals[n] = p;
00327
00328 pl = &bplanes[n];
00329 memset (pl, 0, sizeof(*pl));
00330 if (j)
00331 {
00332 pl->normal[i] = -1;
00333 pl->dist = -bounds[j][i];
00334 }
00335 else
00336 {
00337 pl->normal[i] = 1;
00338 pl->dist = bounds[j][i];
00339 }
00340 p->plane = *pl;
00341 p->winding = BaseWindingForPlane (pl->normal, pl->dist);
00342 AddPortalToNodes (p, node, &tree->outside_node);
00343 }
00344
00345 // clip the basewindings by all the other planes
00346 for (i=0 ; i<6 ; i++)
00347 {
00348 for (j=0 ; j<6 ; j++)
00349 {
00350 if (j == i) continue;
00351 ChopWindingInPlace (&portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON);
00352 } //end for
00353 } //end for
00354 } //end of the function MakeHeadNodePortals
|
|
|
Definition at line 406 of file portals.c. 00407 {
00408 portal_t *new_portal, *p;
00409 winding_t *w;
00410 vec3_t normal;
00411 float dist;
00412 int side;
00413
00414 w = BaseWindingForNode (node);
00415
00416 // clip the portal by all the other portals in the node
00417 for (p = node->portals; p && w; p = p->next[side])
00418 {
00419 if (p->nodes[0] == node)
00420 {
00421 side = 0;
00422 VectorCopy (p->plane.normal, normal);
00423 dist = p->plane.dist;
00424 } //end if
00425 else if (p->nodes[1] == node)
00426 {
00427 side = 1;
00428 VectorSubtract (vec3_origin, p->plane.normal, normal);
00429 dist = -p->plane.dist;
00430 } //end else if
00431 else
00432 {
00433 Error ("MakeNodePortal: mislinked portal");
00434 } //end else
00435 ChopWindingInPlace (&w, normal, dist, 0.1);
00436 } //end for
00437
00438 if (!w)
00439 {
00440 return;
00441 } //end if
00442
00443 if (WindingIsTiny (w))
00444 {
00445 c_tinyportals++;
00446 FreeWinding(w);
00447 return;
00448 } //end if
00449
00450 #ifdef DEBUG
00451 /* //NOTE: don't use this winding ok check
00452 // all the invalid windings only have a degenerate edge
00453 if (WindingError(w))
00454 {
00455 Log_Print("MakeNodePortal: %s\n", WindingErrorString());
00456 FreeWinding(w);
00457 return;
00458 } //end if*/
00459 #endif //DEBUG
00460
00461
00462 new_portal = AllocPortal();
00463 new_portal->plane = mapplanes[node->planenum];
00464
00465 #ifdef ME
00466 new_portal->planenum = node->planenum;
00467 #endif //ME
00468
00469 new_portal->onnode = node;
00470 new_portal->winding = w;
00471 AddPortalToNodes (new_portal, node->children[0], node->children[1]);
00472 } //end of the function MakeNodePortal
|
|
|
Definition at line 649 of file portals.c. 00650 {
00651
00652 #ifdef ME
00653 Log_Print("---- Node Portalization ----\n");
00654 c_numportalizednodes = 0;
00655 c_portalmemory = 0;
00656 qprintf("%6d nodes portalized", c_numportalizednodes);
00657 #endif //ME
00658
00659 MakeHeadnodePortals(tree);
00660 MakeTreePortals_r(tree->headnode);
00661
00662 #ifdef ME
00663 qprintf("\n");
00664 Log_Write("%6d nodes portalized\r\n", c_numportalizednodes);
00665 Log_Print("%6d tiny portals\r\n", c_tinyportals);
00666 Log_Print("%6d KB of portal memory\r\n", c_portalmemory >> 10);
00667 Log_Print("%6i KB of winding memory\r\n", WindingMemory() >> 10);
00668 #endif //ME
00669 } //end of the function MakeTreePortals
|
|
|
Definition at line 611 of file portals.c. References c_numportalizednodes, CalcNodeBounds(), node_s::children, i, Log_Print(), MakeNodePortal(), MakeTreePortals_r(), MAX_MAP_BOUNDS, node_s::maxs, node_s::mins, node_t, node_s::planenum, qprintf(), and SplitNodePortals(). 00612 {
00613 int i;
00614
00615 #ifdef ME
00616 qprintf("\r%6d", ++c_numportalizednodes);
00617 if (cancelconversion) return;
00618 #endif //ME
00619
00620 CalcNodeBounds (node);
00621 if (node->mins[0] >= node->maxs[0])
00622 {
00623 Log_Print("WARNING: node without a volume\n");
00624 }
00625
00626 for (i=0 ; i<3 ; i++)
00627 {
00628 if (node->mins[i] < -MAX_MAP_BOUNDS || node->maxs[i] > MAX_MAP_BOUNDS)
00629 {
00630 Log_Print("WARNING: node with unbounded volume\n");
00631 break;
00632 }
00633 }
00634 if (node->planenum == PLANENUM_LEAF)
00635 return;
00636
00637 MakeNodePortal (node);
00638 SplitNodePortals (node);
00639
00640 MakeTreePortals_r (node->children[0]);
00641 MakeTreePortals_r (node->children[1]);
00642 } //end of the function MakeTreePortals_r
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1276 of file portals.c. References side_s::flags, i, j, Log_Print(), mapbrush_t, mapbrushes, MarkVisibleSides_r(), mapbrush_s::numsides, mapbrush_s::original_sides, and tree(). 01277 {
01278 int i, j;
01279 mapbrush_t *mb;
01280 int numsides;
01281
01282 Log_Print("--- MarkVisibleSides ---\n");
01283
01284 // clear all the visible flags
01285 for (i=startbrush ; i<endbrush ; i++)
01286 {
01287 mb = &mapbrushes[i];
01288
01289 numsides = mb->numsides;
01290 for (j=0 ; j<numsides ; j++)
01291 mb->original_sides[j].flags &= ~SFL_VISIBLE;
01292 }
01293
01294 // set visible flags on the sides that are used by portals
01295 MarkVisibleSides_r (tree->headnode);
01296 } //end of the function MarkVisibleSides
|
Here is the call graph for this function:

|
|
Definition at line 1243 of file portals.c. References node_s::children, node_s::contents, FindPortalSide(), side_s::flags, portal_s::next, node_t, portal_s::nodes, portal_s::onnode, p, node_s::planenum, portal_t, node_s::portals, s, portal_s::side, and portal_s::sidefound. Referenced by MarkVisibleSides(). 01244 {
01245 portal_t *p;
01246 int s;
01247
01248 if (node->planenum != PLANENUM_LEAF)
01249 {
01250 MarkVisibleSides_r (node->children[0]);
01251 MarkVisibleSides_r (node->children[1]);
01252 return;
01253 } //end if
01254
01255 // empty leaves are never boundary leaves
01256 if (!node->contents) return;
01257
01258 // see if there is a visible face
01259 for (p=node->portals ; p ; p = p->next[!s])
01260 {
01261 s = (p->nodes[0] == node);
01262 if (!p->onnode)
01263 continue; // edge of world
01264 if (!p->sidefound)
01265 FindPortalSide (p);
01266 if (p->side)
01267 p->side->flags |= SFL_VISIBLE;
01268 } //end for
01269 } //end of the function MarkVisibleSides_r
|
Here is the call graph for this function:
