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

aas_gsubdiv.c File Reference

#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
#include "aas_store.h"
#include "aas_cfg.h"

Include dependency graph for aas_gsubdiv.c:

Include dependency graph

Go to the source code of this file.

Defines

#define FACE_EPSILON   1.0
#define FACECLIP_EPSILON   0.2

Functions

int AAS_FindBestAreaSplitPlane (tmp_area_t *tmparea, vec3_t normal, float *dist)
void AAS_GravitationalSubdivision (void)
tmp_node_tAAS_GravitationalSubdivision_r (tmp_node_t *tmpnode)
tmp_node_tAAS_LadderSubdivideArea_r (tmp_node_t *tmpnode)
void AAS_LadderSubdivision (void)
tmp_node_tAAS_LadderSubdivision_r (tmp_node_t *tmpnode)
tmp_node_tAAS_RefreshLadderSubdividedTree_r (tmp_node_t *tmpnode, tmp_area_t *tmparea, tmp_node_t *tmpnode1, tmp_node_t *tmpnode2, int planenum)
void AAS_SplitArea (tmp_area_t *tmparea, int planenum, tmp_area_t **frontarea, tmp_area_t **backarea)
void AAS_SplitFace (tmp_face_t *face, vec3_t normal, float dist, tmp_face_t **frontface, tmp_face_t **backface)
winding_tAAS_SplitWinding (tmp_area_t *tmparea, int planenum)
tmp_node_tAAS_SubdivideArea_r (tmp_node_t *tmpnode)
int AAS_TestSplitPlane (tmp_area_t *tmparea, vec3_t normal, float dist, int *facesplits, int *groundsplits, int *epsilonfaces)

Variables

int numgravitationalsubdivisions = 0
int numladdersubdivisions = 0


Define Documentation

#define FACE_EPSILON   1.0
 

Definition at line 30 of file aas_gsubdiv.c.

#define FACECLIP_EPSILON   0.2
 

Definition at line 29 of file aas_gsubdiv.c.

Referenced by AAS_SplitFace(), and AAS_TestSplitPlane().


Function Documentation

int AAS_FindBestAreaSplitPlane tmp_area_t tmparea,
vec3_t  normal,
float *  dist
 

Definition at line 327 of file aas_gsubdiv.c.

References AAS_GapFace(), AAS_TestSplitPlane(), tmp_area_s::areanum, cfg, tmp_face_s::faceflags, FindPlaneSeperatingWindings(), tmp_face_s::frontarea, Log_Print(), Log_Write(), tmp_face_s::next, cfg_s::phys_gravitydirection, tmp_area_t, tmp_face_t, tmp_area_s::tmpfaces, value, vec3_t, VectorCopy, VectorInverse(), tmp_face_s::winding, and WindingIsTiny().

Referenced by AAS_SubdivideArea_r().

00328 {
00329     int side1, side2;
00330     int foundsplitter, facesplits, groundsplits, epsilonfaces, bestepsilonfaces;
00331     float bestvalue, value;
00332     tmp_face_t *face1, *face2;
00333     vec3_t tmpnormal, invgravity;
00334     float tmpdist;
00335 
00336     //get inverse of gravity direction
00337     VectorCopy(cfg.phys_gravitydirection, invgravity);
00338     VectorInverse(invgravity);
00339 
00340     foundsplitter = false;
00341     bestvalue = -999999;
00342     bestepsilonfaces = 0;
00343     //
00344 #ifdef AW_DEBUG
00345     Log_Print("finding split plane for area %d\n", tmparea->areanum);
00346 #endif //AW_DEBUG
00347     for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
00348     {
00349         //side of the face the area is on
00350         side1 = face1->frontarea != tmparea;
00351         //
00352         if (WindingIsTiny(face1->winding))
00353         {
00354             Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
00355             continue;
00356         } //end if
00357         //if the face isn't a gap or ground there's no split edge
00358         if (!(face1->faceflags & FACE_GROUND) && !AAS_GapFace(face1, side1)) continue;
00359         //
00360         for (face2 = face1->next[side1]; face2; face2 = face2->next[side2])
00361         {
00362             //side of the face the area is on
00363             side2 = face2->frontarea != tmparea;
00364             //
00365             if (WindingIsTiny(face1->winding))
00366             {
00367                 Log_Write("gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum);
00368                 continue;
00369             } //end if
00370             //if the face isn't a gap or ground there's no split edge
00371             if (!(face2->faceflags & FACE_GROUND) && !AAS_GapFace(face2, side2)) continue;
00372             //only split between gaps and ground
00373             if (!(((face1->faceflags & FACE_GROUND) && AAS_GapFace(face2, side2)) ||
00374                     ((face2->faceflags & FACE_GROUND) && AAS_GapFace(face1, side1)))) continue;
00375             //find a plane seperating the windings of the faces
00376             if (!FindPlaneSeperatingWindings(face1->winding, face2->winding, invgravity,
00377                                                         tmpnormal, &tmpdist)) continue;
00378 #ifdef AW_DEBUG
00379             Log_Print("normal = \'%f %f %f\', dist = %f\n",
00380                             tmpnormal[0], tmpnormal[1], tmpnormal[2], tmpdist);
00381 #endif //AW_DEBUG
00382             //get metrics for this vertical plane
00383             if (!AAS_TestSplitPlane(tmparea, tmpnormal, tmpdist,
00384                                         &facesplits, &groundsplits, &epsilonfaces))
00385             {
00386                 continue;
00387             } //end if
00388 #ifdef AW_DEBUG
00389             Log_Print("face splits = %d\nground splits = %d\n",
00390                             facesplits, groundsplits);
00391 #endif //AW_DEBUG
00392             value = 100 - facesplits - 2 * groundsplits;
00393             //avoid epsilon faces
00394             value += epsilonfaces * -1000;
00395             if (value > bestvalue)
00396             {
00397                 VectorCopy(tmpnormal, normal);
00398                 *dist = tmpdist;
00399                 bestvalue = value;
00400                 bestepsilonfaces = epsilonfaces;
00401                 foundsplitter = true;
00402             } //end if
00403         } //end for
00404     } //end for
00405     if (bestepsilonfaces)
00406     {
00407         Log_Write("found %d epsilon faces trying to split area %d\r\n",
00408                                     epsilonfaces, tmparea->areanum);
00409     } //end else
00410     return foundsplitter;
00411 } //end of the function AAS_FindBestAreaSplitPlane

Here is the call graph for this function:

void AAS_GravitationalSubdivision void   ) 
 

Definition at line 474 of file aas_gsubdiv.c.

References AAS_GravitationalSubdivision_r(), Log_Write(), tmp_aas_s::nodes, numgravitationalsubdivisions, qprintf(), and tmpaasworld.

Referenced by AAS_Create().

00475 {
00476     Log_Write("AAS_GravitationalSubdivision\r\n");
00477     numgravitationalsubdivisions = 0;
00478     qprintf("%6i gravitational subdivisions", numgravitationalsubdivisions);
00479     //start with the head node
00480     AAS_GravitationalSubdivision_r(tmpaasworld.nodes);
00481     qprintf("\n");
00482     Log_Write("%6i gravitational subdivisions\r\n", numgravitationalsubdivisions);
00483 } //end of the function AAS_GravitationalSubdivision

Here is the call graph for this function:

tmp_node_t* AAS_GravitationalSubdivision_r tmp_node_t tmpnode  ) 
 

Definition at line 456 of file aas_gsubdiv.c.

References AAS_SubdivideArea_r(), tmp_node_s::children, tmp_node_t, and tmp_node_s::tmparea.

Referenced by AAS_GravitationalSubdivision().

00457 {
00458     //if this is a solid leaf
00459     if (!tmpnode) return NULL;
00460     //negative so it's an area
00461     if (tmpnode->tmparea) return AAS_SubdivideArea_r(tmpnode);
00462     //do the children recursively
00463     tmpnode->children[0] = AAS_GravitationalSubdivision_r(tmpnode->children[0]);
00464     tmpnode->children[1] = AAS_GravitationalSubdivision_r(tmpnode->children[1]);
00465     return tmpnode;
00466 } //end of the function AAS_GravitationalSubdivision_r

Here is the call graph for this function:

tmp_node_t* AAS_LadderSubdivideArea_r tmp_node_t tmpnode  ) 
 

Definition at line 523 of file aas_gsubdiv.c.

References AAS_AllocTmpNode(), AAS_RefreshLadderSubdividedTree_r(), AAS_SplitArea(), AAS_SplitWinding(), AREACONTENTS_LAVA, AREACONTENTS_WATER, tmp_node_s::children, tmp_area_s::contents, plane_t::dist, DotProduct, tmp_face_s::faceflags, FindFloatPlane(), FreeWinding(), tmp_face_s::frontarea, i, mapplanes, tmp_face_s::next, tmp_aas_s::nodes, plane_t::normal, numladdersubdivisions, winding_t::numpoints, winding_t::p, tmp_node_s::planenum, tmp_face_s::planenum, tmp_area_s::presencetype, qprintf(), tmp_area_t, tmp_face_t, tmp_node_t, tmpaasworld, tmp_node_s::tmparea, tmp_area_s::tmpfaces, vec3_t, VectorCopy, w, and tmp_face_s::winding.

Referenced by AAS_LadderSubdivision_r().

00524 {
00525     int side1, i, planenum;
00526     int foundladderface, foundgroundface;
00527     float dist;
00528     tmp_area_t *tmparea, *frontarea, *backarea;
00529     tmp_face_t *face1;
00530     tmp_node_t *tmpnode1, *tmpnode2;
00531     vec3_t lowestpoint, normal = {0, 0, 1};
00532     plane_t *plane;
00533     winding_t *w;
00534 
00535     tmparea = tmpnode->tmparea;
00536     //skip areas with a liquid
00537     if (tmparea->contents & (AREACONTENTS_WATER
00538                                     | AREACONTENTS_LAVA
00539                                     | AREACONTENTS_SLIME)) return tmpnode;
00540     //must be possible to stand in the area
00541     if (!(tmparea->presencetype & PRESENCE_NORMAL)) return tmpnode;
00542     //
00543     foundladderface = false;
00544     foundgroundface = false;
00545     lowestpoint[2] = 99999;
00546     //
00547     for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
00548     {
00549         //side of the face the area is on
00550         side1 = face1->frontarea != tmparea;
00551         //if the face is a ladder face
00552         if (face1->faceflags & FACE_LADDER)
00553         {
00554             plane = &mapplanes[face1->planenum];
00555             //the ladder face plane should be pretty much vertical
00556             if (DotProduct(plane->normal, normal) > -0.1)
00557             {
00558                 foundladderface = true;
00559                 //find lowest point
00560                 for (i = 0; i < face1->winding->numpoints; i++)
00561                 {
00562                     if (face1->winding->p[i][2] < lowestpoint[2])
00563                     {
00564                         VectorCopy(face1->winding->p[i], lowestpoint);
00565                     } //end if
00566                 } //end for
00567             } //end if
00568         } //end if
00569         else if (face1->faceflags & FACE_GROUND)
00570         {
00571             foundgroundface = true;
00572         } //end else if
00573     } //end for
00574     //
00575     if ((!foundladderface) || (!foundgroundface)) return tmpnode;
00576     //
00577     for (face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1])
00578     {
00579         //side of the face the area is on
00580         side1 = face1->frontarea != tmparea;
00581         //if the face isn't a ground face
00582         if (!(face1->faceflags & FACE_GROUND)) continue;
00583         //the ground plane
00584         plane = &mapplanes[face1->planenum];
00585         //get the difference between the ground plane and the lowest point
00586         dist = DotProduct(plane->normal, lowestpoint) - plane->dist;
00587         //if the lowest point is very near one of the ground planes
00588         if (dist > -1 && dist < 1)
00589         {
00590             return tmpnode;
00591         } //end if
00592     } //end for
00593     //
00594     dist = DotProduct(normal, lowestpoint);
00595     planenum = FindFloatPlane(normal, dist);
00596     //
00597     w = AAS_SplitWinding(tmparea, planenum);
00598     if (!w) return tmpnode;
00599     FreeWinding(w);
00600     //split the area with a horizontal plane through the lowest point
00601     qprintf("\r%6d", ++numladdersubdivisions);
00602     //
00603     AAS_SplitArea(tmparea, planenum, &frontarea, &backarea);
00604     //
00605     tmpnode->tmparea = NULL;
00606     tmpnode->planenum = planenum;
00607     //
00608     tmpnode1 = AAS_AllocTmpNode();
00609     tmpnode1->planenum = 0;
00610     tmpnode1->tmparea = frontarea;
00611     //
00612     tmpnode2 = AAS_AllocTmpNode();
00613     tmpnode2->planenum = 0;
00614     tmpnode2->tmparea = backarea;
00615     //subdivide the areas created by splitting recursively
00616     tmpnode->children[0] = AAS_LadderSubdivideArea_r(tmpnode1);
00617     tmpnode->children[1] = AAS_LadderSubdivideArea_r(tmpnode2);
00618     //refresh the tree
00619     AAS_RefreshLadderSubdividedTree_r(tmpaasworld.nodes, tmparea, tmpnode1, tmpnode2, planenum);
00620     //
00621     return tmpnode;
00622 } //end of the function AAS_LadderSubdivideArea_r

Here is the call graph for this function:

void AAS_LadderSubdivision void   ) 
 

Definition at line 646 of file aas_gsubdiv.c.

References AAS_LadderSubdivision_r(), Log_Write(), tmp_aas_s::nodes, numladdersubdivisions, qprintf(), and tmpaasworld.

Referenced by AAS_Create().

00647 {
00648     Log_Write("AAS_LadderSubdivision\r\n");
00649     numladdersubdivisions = 0;
00650     qprintf("%6i ladder subdivisions", numladdersubdivisions);
00651     //start with the head node
00652     AAS_LadderSubdivision_r(tmpaasworld.nodes);
00653     //
00654     qprintf("\n");
00655     Log_Write("%6i ladder subdivisions\r\n", numladdersubdivisions);
00656 } //end of the function AAS_LadderSubdivision

Here is the call graph for this function:

tmp_node_t* AAS_LadderSubdivision_r tmp_node_t tmpnode  ) 
 

Definition at line 629 of file aas_gsubdiv.c.

References AAS_LadderSubdivideArea_r(), tmp_node_s::children, tmp_node_t, and tmp_node_s::tmparea.

Referenced by AAS_LadderSubdivision().

00630 {
00631     //if this is a solid leaf
00632     if (!tmpnode) return 0;
00633     //negative so it's an area
00634     if (tmpnode->tmparea) return AAS_LadderSubdivideArea_r(tmpnode);
00635     //do the children recursively
00636     tmpnode->children[0] = AAS_LadderSubdivision_r(tmpnode->children[0]);
00637     tmpnode->children[1] = AAS_LadderSubdivision_r(tmpnode->children[1]);
00638     return tmpnode;
00639 } //end of the function AAS_LadderSubdivision_r

Here is the call graph for this function:

tmp_node_t* AAS_RefreshLadderSubdividedTree_r tmp_node_t tmpnode,
tmp_area_t tmparea,
tmp_node_t tmpnode1,
tmp_node_t tmpnode2,
int  planenum
 

Definition at line 490 of file aas_gsubdiv.c.

References tmp_node_s::children, tmp_node_s::planenum, tmp_area_t, tmp_node_t, and tmp_node_s::tmparea.

Referenced by AAS_LadderSubdivideArea_r().

00492 {
00493     //if this is a solid leaf
00494     if (!tmpnode) return NULL;
00495     //negative so it's an area
00496     if (tmpnode->tmparea)
00497     {
00498         if (tmpnode->tmparea == tmparea)
00499         {
00500             tmpnode->tmparea = NULL;
00501             tmpnode->planenum = planenum;
00502             tmpnode->children[0] = tmpnode1;
00503             tmpnode->children[1] = tmpnode2;
00504         } //end if
00505         return tmpnode;
00506     } //end if
00507     //do the children recursively
00508     tmpnode->children[0] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[0],
00509                                     tmparea, tmpnode1, tmpnode2, planenum);
00510     tmpnode->children[1] = AAS_RefreshLadderSubdividedTree_r(tmpnode->children[1],
00511                                     tmparea, tmpnode1, tmpnode2, planenum);
00512     return tmpnode;
00513 } //end of the function AAS_RefreshLadderSubdividedTree_r

void AAS_SplitArea tmp_area_t tmparea,
int  planenum,
tmp_area_t **  frontarea,
tmp_area_t **  backarea
 

Definition at line 193 of file aas_gsubdiv.c.

References AAS_AddFaceSideToArea(), AAS_AllocTmpArea(), AAS_AllocTmpFace(), AAS_CheckArea(), AAS_FlipAreaFaces(), AAS_FreeTmpFace(), AAS_RemoveFaceFromArea(), AAS_SplitFace(), AAS_SplitWinding(), tmp_area_s::areanum, tmp_face_s::backarea, tmp_area_s::contents, plane_t::dist, Error(), tmp_face_s::frontarea, tmp_area_s::invalid, Log_Print(), mapplanes, tmp_area_s::modelnum, tmp_face_s::next, plane_t::normal, tmp_face_s::planenum, tmp_area_s::presencetype, tmp_area_t, tmp_face_t, tmp_area_s::tmpfaces, and tmp_face_s::winding.

Referenced by AAS_LadderSubdivideArea_r(), and AAS_SubdivideArea_r().

00194 {
00195     int side;
00196     tmp_area_t *facefrontarea, *facebackarea, *faceotherarea;
00197     tmp_face_t *face, *frontface, *backface, *splitface, *nextface;
00198     winding_t *splitwinding;
00199     plane_t *splitplane;
00200 
00201 /*
00202 #ifdef AW_DEBUG
00203     int facesplits, groundsplits, epsilonface;
00204     Log_Print("\n----------------------\n");
00205     Log_Print("splitting area %d\n", areanum);
00206     Log_Print("with normal = \'%f %f %f\', dist = %f\n", normal[0], normal[1], normal[2], dist);
00207     AAS_TestSplitPlane(areanum, normal, dist,
00208                                         &facesplits, &groundsplits, &epsilonface);
00209     Log_Print("face splits = %d\nground splits = %d\n", facesplits, groundsplits);
00210     if (epsilonface) Log_Print("aaahh epsilon face\n");
00211 #endif //AW_DEBUG*/
00212     //the original area
00213 
00214     AAS_FlipAreaFaces(tmparea);
00215     AAS_CheckArea(tmparea);
00216     //
00217     splitplane = &mapplanes[planenum];
00218 /*  //create a split winding, first base winding for plane
00219     splitwinding = BaseWindingForPlane(splitplane->normal, splitplane->dist);
00220     //chop with all the faces of the area
00221     for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
00222     {
00223         //side of the face the original area was on
00224         side = face->frontarea != tmparea->areanum;
00225         plane = &mapplanes[face->planenum ^ side];
00226         ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
00227     } //end for*/
00228     splitwinding = AAS_SplitWinding(tmparea, planenum);
00229     if (!splitwinding)
00230     {
00231 /*
00232 #ifdef DEBUG
00233         AAS_TestSplitPlane(areanum, normal, dist,
00234                                             &facesplits, &groundsplits, &epsilonface);
00235         Log_Print("\nface splits = %d\nground splits = %d\n", facesplits, groundsplits);
00236         if (epsilonface) Log_Print("aaahh epsilon face\n");
00237 #endif //DEBUG*/
00238         Error("AAS_SplitArea: no split winding when splitting area %d\n", tmparea->areanum);
00239     } //end if
00240     //create a split face
00241     splitface = AAS_AllocTmpFace();
00242     //get the map plane
00243     splitface->planenum = planenum;
00244     //store the split winding
00245     splitface->winding = splitwinding;
00246     //the new front area
00247     (*frontarea) = AAS_AllocTmpArea();
00248     (*frontarea)->presencetype = tmparea->presencetype;
00249     (*frontarea)->contents = tmparea->contents;
00250     (*frontarea)->modelnum = tmparea->modelnum;
00251     (*frontarea)->tmpfaces = NULL;
00252     //the new back area
00253     (*backarea) = AAS_AllocTmpArea();
00254     (*backarea)->presencetype = tmparea->presencetype;
00255     (*backarea)->contents = tmparea->contents;
00256     (*backarea)->modelnum = tmparea->modelnum;
00257     (*backarea)->tmpfaces = NULL;
00258     //add the split face to the new areas
00259     AAS_AddFaceSideToArea(splitface, 0, (*frontarea));
00260     AAS_AddFaceSideToArea(splitface, 1, (*backarea));
00261 
00262     //split all the faces of the original area
00263     for (face = tmparea->tmpfaces; face; face = nextface)
00264     {
00265         //side of the face the original area was on
00266         side = face->frontarea != tmparea;
00267         //next face of the original area
00268         nextface = face->next[side];
00269         //front area of the face
00270         facefrontarea = face->frontarea;
00271         //back area of the face
00272         facebackarea = face->backarea;
00273         //remove the face from both the front and back areas
00274         if (facefrontarea) AAS_RemoveFaceFromArea(face, facefrontarea);
00275         if (facebackarea) AAS_RemoveFaceFromArea(face, facebackarea);
00276         //split the face
00277         AAS_SplitFace(face, splitplane->normal, splitplane->dist, &frontface, &backface);
00278         //free the original face
00279         AAS_FreeTmpFace(face);
00280         //get the number of the area at the other side of the face
00281         if (side) faceotherarea = facefrontarea;
00282         else faceotherarea = facebackarea;
00283         //if there is an area at the other side of the original face
00284         if (faceotherarea)
00285         {
00286             if (frontface) AAS_AddFaceSideToArea(frontface, !side, faceotherarea);
00287             if (backface) AAS_AddFaceSideToArea(backface, !side, faceotherarea);
00288         } //end if
00289         //add the front and back part left after splitting the original face to the new areas
00290         if (frontface) AAS_AddFaceSideToArea(frontface, side, (*frontarea));
00291         if (backface) AAS_AddFaceSideToArea(backface, side, (*backarea));
00292     } //end for
00293 
00294     if (!(*frontarea)->tmpfaces) Log_Print("AAS_SplitArea: front area without faces\n");
00295     if (!(*backarea)->tmpfaces) Log_Print("AAS_SplitArea: back area without faces\n");
00296 
00297     tmparea->invalid = true;
00298 /*
00299 #ifdef AW_DEBUG
00300     for (i = 0, face = frontarea->tmpfaces; face; face = face->next[side])
00301     {
00302         side = face->frontarea != frontarea->areanum;
00303         i++;
00304     } //end for
00305     Log_Print("created front area %d with %d faces\n", frontarea->areanum, i);
00306 
00307     for (i = 0, face = backarea->tmpfaces; face; face = face->next[side])
00308     {
00309         side = face->frontarea != backarea->areanum;
00310         i++;
00311     } //end for
00312     Log_Print("created back area %d with %d faces\n", backarea->areanum, i);
00313 #endif //AW_DEBUG*/
00314 
00315     AAS_FlipAreaFaces((*frontarea));
00316     AAS_FlipAreaFaces((*backarea));
00317     //
00318     AAS_CheckArea((*frontarea));
00319     AAS_CheckArea((*backarea));
00320 } //end of the function AAS_SplitArea

Here is the call graph for this function:

void AAS_SplitFace tmp_face_t face,
vec3_t  normal,
float  dist,
tmp_face_t **  frontface,
tmp_face_t **  backface
 

Definition at line 45 of file aas_gsubdiv.c.

References AAS_AllocTmpFace(), ClipWindingEpsilon(), FACECLIP_EPSILON, tmp_face_s::faceflags, FreeWinding(), Log_Write(), tmp_face_s::planenum, tmp_face_t, tmp_face_s::winding, and WindingIsTiny().

Referenced by AAS_SplitArea().

00047 {
00048     winding_t *frontw, *backw;
00049 
00050     //
00051     *frontface = *backface = NULL;
00052 
00053     ClipWindingEpsilon(face->winding, normal, dist, FACECLIP_EPSILON, &frontw, &backw);
00054 
00055 #ifdef DEBUG
00056     //
00057     if (frontw)
00058     {
00059         if (WindingIsTiny(frontw))
00060         {
00061             Log_Write("AAS_SplitFace: tiny back face\r\n");
00062             FreeWinding(frontw);
00063             frontw = NULL;
00064         } //end if
00065     } //end if
00066     if (backw)
00067     {
00068         if (WindingIsTiny(backw))
00069         {
00070             Log_Write("AAS_SplitFace: tiny back face\r\n");
00071             FreeWinding(backw);
00072             backw = NULL;
00073         } //end if
00074     } //end if
00075 #endif //DEBUG
00076     //if the winding was split
00077     if (frontw)
00078     {
00079         //check bounds
00080         (*frontface) = AAS_AllocTmpFace();
00081         (*frontface)->planenum = face->planenum;
00082         (*frontface)->winding = frontw;
00083         (*frontface)->faceflags = face->faceflags;
00084     } //end if
00085     if (backw)
00086     {
00087         //check bounds
00088         (*backface) = AAS_AllocTmpFace();
00089         (*backface)->planenum = face->planenum;
00090         (*backface)->winding = backw;
00091         (*backface)->faceflags = face->faceflags;
00092     } //end if
00093 } //end of the function AAS_SplitFace

Here is the call graph for this function:

winding_t* AAS_SplitWinding tmp_area_t tmparea,
int  planenum
 

Definition at line 100 of file aas_gsubdiv.c.

References BaseWindingForPlane(), ChopWindingInPlace(), plane_t::dist, tmp_face_s::frontarea, mapplanes, tmp_face_s::next, plane_t::normal, tmp_face_s::planenum, tmp_area_t, tmp_face_t, and tmp_area_s::tmpfaces.

Referenced by AAS_LadderSubdivideArea_r(), AAS_SplitArea(), and AAS_TestSplitPlane().

00101 {
00102     tmp_face_t *face;
00103     plane_t *plane;
00104     int side;
00105     winding_t *splitwinding;
00106 
00107     //
00108     plane = &mapplanes[planenum];
00109     //create a split winding, first base winding for plane
00110     splitwinding = BaseWindingForPlane(plane->normal, plane->dist);
00111     //chop with all the faces of the area
00112     for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
00113     {
00114         //side of the face the original area was on
00115         side = face->frontarea != tmparea;
00116         plane = &mapplanes[face->planenum ^ side];
00117         ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
00118     } //end for
00119     return splitwinding;
00120 } //end of the function AAS_SplitWinding

Here is the call graph for this function:

tmp_node_t* AAS_SubdivideArea_r tmp_node_t tmpnode  ) 
 

Definition at line 418 of file aas_gsubdiv.c.

References AAS_AllocTmpNode(), AAS_FindBestAreaSplitPlane(), AAS_SplitArea(), tmp_node_s::children, FindFloatPlane(), numgravitationalsubdivisions, tmp_node_s::planenum, qprintf(), tmp_area_t, tmp_node_t, tmp_node_s::tmparea, and vec3_t.

Referenced by AAS_GravitationalSubdivision_r().

00419 {
00420     int planenum;
00421     tmp_area_t *frontarea, *backarea;
00422     tmp_node_t *tmpnode1, *tmpnode2;
00423     vec3_t normal;
00424     float dist;
00425 
00426     if (AAS_FindBestAreaSplitPlane(tmpnode->tmparea, normal, &dist))
00427     {
00428         qprintf("\r%6d", ++numgravitationalsubdivisions);
00429         //
00430         planenum = FindFloatPlane(normal, dist);
00431         //split the area
00432         AAS_SplitArea(tmpnode->tmparea, planenum, &frontarea, &backarea);
00433         //
00434         tmpnode->tmparea = NULL;
00435         tmpnode->planenum = FindFloatPlane(normal, dist);
00436         //
00437         tmpnode1 = AAS_AllocTmpNode();
00438         tmpnode1->planenum = 0;
00439         tmpnode1->tmparea = frontarea;
00440         //
00441         tmpnode2 = AAS_AllocTmpNode();
00442         tmpnode2->planenum = 0;
00443         tmpnode2->tmparea = backarea;
00444         //subdivide the areas created by splitting recursively
00445         tmpnode->children[0] = AAS_SubdivideArea_r(tmpnode1);
00446         tmpnode->children[1] = AAS_SubdivideArea_r(tmpnode2);
00447     } //end if
00448     return tmpnode;
00449 } //end of the function AAS_SubdivideArea_r

Here is the call graph for this function:

int AAS_TestSplitPlane tmp_area_t tmparea,
vec3_t  normal,
float  dist,
int *  facesplits,
int *  groundsplits,
int *  epsilonfaces
 

Definition at line 127 of file aas_gsubdiv.c.

References AAS_SplitWinding(), d, DotProduct, FACECLIP_EPSILON, tmp_face_s::faceflags, FindFloatPlane(), FreeWinding(), tmp_face_s::frontarea, j, Log_Print(), tmp_face_s::next, winding_t::numpoints, winding_t::p, tmp_face_s::planenum, tmp_area_t, tmp_face_t, tmp_area_s::tmpfaces, w, and tmp_face_s::winding.

Referenced by AAS_FindBestAreaSplitPlane().

00129 {
00130     int j, side, front, back, planenum;
00131     float d, d_front, d_back;
00132     tmp_face_t *face;
00133     winding_t *w;
00134 
00135     *facesplits = *groundsplits = *epsilonfaces = 0;
00136 
00137     planenum = FindFloatPlane(normal, dist);
00138 
00139     w = AAS_SplitWinding(tmparea, planenum);
00140     if (!w) return false;
00141     FreeWinding(w);
00142     //
00143     for (face = tmparea->tmpfaces; face; face = face->next[side])
00144     {
00145         //side of the face the area is on
00146         side = face->frontarea != tmparea;
00147 
00148         if ((face->planenum & ~1) == (planenum & ~1))
00149         {
00150             Log_Print("AAS_TestSplitPlane: tried face plane as splitter\n");
00151             return false;
00152         } //end if
00153         w = face->winding;
00154         //reset distance at front and back side of plane
00155         d_front = d_back = 0;
00156         //reset front and back flags
00157         front = back = 0;
00158         for (j = 0; j < w->numpoints; j++)
00159         {
00160             d = DotProduct(w->p[j], normal) - dist;
00161             if (d > d_front) d_front = d;
00162             if (d < d_back) d_back = d;
00163 
00164             if (d > 0.4) // PLANESIDE_EPSILON)
00165                 front = 1;
00166             if (d < -0.4) // PLANESIDE_EPSILON)
00167                 back = 1;
00168         } //end for
00169         //check for an epsilon face
00170         if ( (d_front > FACECLIP_EPSILON && d_front < FACE_EPSILON)
00171             || (d_back < -FACECLIP_EPSILON && d_back > -FACE_EPSILON) )
00172         {
00173             (*epsilonfaces)++;
00174         } //end if
00175         //if the face has points at both sides of the plane
00176         if (front && back)
00177         {
00178             (*facesplits)++;
00179             if (face->faceflags & FACE_GROUND)
00180             {
00181                 (*groundsplits)++;
00182             } //end if
00183         } //end if
00184     } //end for
00185     return true;
00186 } //end of the function AAS_TestSplitPlane

Here is the call graph for this function:


Variable Documentation

int numgravitationalsubdivisions = 0
 

Definition at line 32 of file aas_gsubdiv.c.

Referenced by AAS_GravitationalSubdivision(), and AAS_SubdivideArea_r().

int numladdersubdivisions = 0
 

Definition at line 33 of file aas_gsubdiv.c.

Referenced by AAS_LadderSubdivideArea_r(), and AAS_LadderSubdivision().


Generated on Thu Aug 25 12:46:25 2005 for Quake III Arena by  doxygen 1.3.9.1