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

cm_patch.c File Reference

#include "cm_local.h"
#include "cm_patch.h"

Include dependency graph for cm_patch.c:

Include dependency graph

Go to the source code of this file.

Defines

#define DIST_EPSILON   0.02
#define NORMAL_EPSILON   0.0001
#define POINT_EPSILON   0.1

Enumerations

enum  edgeName_t { EN_TOP, EN_RIGHT, EN_BOTTOM, EN_LEFT }

Functions

void BotDrawDebugPolygons (void(*drawPoly)(int color, int numPoints, float *points), int value)
void CM_AddFacetBevels (facet_t *facet)
int CM_CheckFacetPlane (float *plane, vec3_t start, vec3_t end, float *enterFrac, float *leaveFrac, int *hit)
void CM_ClearLevelPatches (void)
qboolean CM_ComparePoints (float *a, float *b)
void CM_DrawDebugSurface (void(*drawPoly)(int color, int numPoints, float *points))
int CM_EdgePlaneNum (cGrid_t *grid, int gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2], int i, int j, int k)
int CM_FindPlane (float *p1, float *p2, float *p3)
int CM_FindPlane2 (float plane[4], int *flipped)
patchCollide_sCM_GeneratePatchCollide (int width, int height, vec3_t *points)
int CM_GridPlane (int gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2], int i, int j, int tri)
qboolean CM_NeedsSubdivision (vec3_t a, vec3_t b, vec3_t c)
void CM_PatchCollideFromGrid (cGrid_t *grid, patchCollide_t *pf)
int CM_PlaneEqual (patchPlane_t *p, float plane[4], int *flipped)
qboolean CM_PlaneFromPoints (vec4_t plane, vec3_t a, vec3_t b, vec3_t c)
int CM_PointOnPlaneSide (float *p, int planeNum)
qboolean CM_PositionTestInPatchCollide (traceWork_t *tw, const struct patchCollide_s *pc)
void CM_RemoveDegenerateColumns (cGrid_t *grid)
void CM_SetBorderInward (facet_t *facet, cGrid_t *grid, int gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2], int i, int j, int which)
void CM_SetGridWrapWidth (cGrid_t *grid)
int CM_SignbitsForNormal (vec3_t normal)
void CM_SnapVector (vec3_t normal)
void CM_Subdivide (vec3_t a, vec3_t b, vec3_t c, vec3_t out1, vec3_t out2, vec3_t out3)
void CM_SubdivideGridColumns (cGrid_t *grid)
void CM_TracePointThroughPatchCollide (traceWork_t *tw, const struct patchCollide_s *pc)
void CM_TraceThroughPatchCollide (traceWork_t *tw, const struct patchCollide_s *pc)
void CM_TransposeGrid (cGrid_t *grid)
qboolean CM_ValidateFacet (facet_t *facet)

Variables

int c_totalPatchBlocks
int c_totalPatchEdges
int c_totalPatchSurfaces
qboolean debugBlock
vec3_t debugBlockPoints [4]
const facet_tdebugFacet
const patchCollide_tdebugPatchCollide
facet_t facets [MAX_PATCH_PLANES]
int numFacets
int numPlanes
patchPlane_t planes [MAX_PATCH_PLANES]


Define Documentation

#define DIST_EPSILON   0.02
 

Definition at line 424 of file cm_patch.c.

#define NORMAL_EPSILON   0.0001
 

Definition at line 423 of file cm_patch.c.

#define POINT_EPSILON   0.1
 

Definition at line 356 of file cm_patch.c.


Enumeration Type Documentation

enum edgeName_t
 

Enumeration values:
EN_TOP 
EN_RIGHT 
EN_BOTTOM 
EN_LEFT 

Definition at line 968 of file cm_patch.c.

00968              {
00969     EN_TOP,
00970     EN_RIGHT,
00971     EN_BOTTOM,
00972     EN_LEFT
00973 } edgeName_t;


Function Documentation

void BotDrawDebugPolygons void(*)(int color, int numPoints, float *points drawPoly,
int  value
 

Definition at line 96 of file sv_bot.c.

References bot_debugpoly_t, bot_enable, botlib_export, botlib_export_s::BotLibVarSet, usercmd_s::buttons, serverStatic_t::clients, bot_debugpoly_s::color, entityShared_t::currentAngles, entityShared_t::currentOrigin, Cvar_Get(), cvar_t, debugpolygons, client_s::gentity, i, cvar_s::integer, bot_debugpoly_s::inuse, client_s::lastUsercmd, NULL, bot_debugpoly_s::numPoints, bot_debugpoly_s::points, sharedEntity_t::r, cvar_s::string, svs, and botlib_export_s::Test.

Referenced by CM_DrawDebugSurface().

00096                                                                                                 {
00097     static cvar_t *bot_debug, *bot_groundonly, *bot_reachability, *bot_highlightarea;
00098     bot_debugpoly_t *poly;
00099     int i, parm0;
00100 
00101     if (!debugpolygons)
00102         return;
00103     //bot debugging
00104     if (!bot_debug) bot_debug = Cvar_Get("bot_debug", "0", 0);
00105     //
00106     if (bot_enable && bot_debug->integer) {
00107         //show reachabilities
00108         if (!bot_reachability) bot_reachability = Cvar_Get("bot_reachability", "0", 0);
00109         //show ground faces only
00110         if (!bot_groundonly) bot_groundonly = Cvar_Get("bot_groundonly", "1", 0);
00111         //get the hightlight area
00112         if (!bot_highlightarea) bot_highlightarea = Cvar_Get("bot_highlightarea", "0", 0);
00113         //
00114         parm0 = 0;
00115         if (svs.clients[0].lastUsercmd.buttons & BUTTON_ATTACK) parm0 |= 1;
00116         if (bot_reachability->integer) parm0 |= 2;
00117         if (bot_groundonly->integer) parm0 |= 4;
00118         botlib_export->BotLibVarSet("bot_highlightarea", bot_highlightarea->string);
00119         botlib_export->Test(parm0, NULL, svs.clients[0].gentity->r.currentOrigin, 
00120             svs.clients[0].gentity->r.currentAngles);
00121     } //end if
00122     //draw all debug polys
00123     for (i = 0; i < bot_maxdebugpolys; i++) {
00124         poly = &debugpolygons[i];
00125         if (!poly->inuse) continue;
00126         drawPoly(poly->color, poly->numPoints, (float *) poly->points);
00127         //Com_Printf("poly %i, numpoints = %d\n", i, poly->numPoints);
00128     }
00129 }

Here is the call graph for this function:

void CM_AddFacetBevels facet_t facet  ) 
 

Definition at line 807 of file cm_patch.c.

References BaseWindingForPlane(), facet_t::borderInward, facet_t::borderNoAdjust, facet_t::borderPlanes, ChopWindingInPlace(), CM_FindPlane2(), CM_PlaneEqual(), CM_SnapVector(), Com_DPrintf(), Com_Printf(), CopyWinding(), CrossProduct(), d, DotProduct, f, FreeWinding(), i, j, k, l, facet_t::numBorders, winding_t::numpoints, order, winding_t::p, planes, facet_t::surfacePlane, vec3_origin, vec3_t, Vector4Copy, VectorClear, VectorNegate, VectorNormalize(), VectorSubtract, w, and WindingBounds().

Referenced by CM_PatchCollideFromGrid().

00807                                          {
00808 
00809     int i, j, k, l;
00810     int axis, dir, order, flipped;
00811     float plane[4], d, newplane[4];
00812     winding_t *w, *w2;
00813     vec3_t mins, maxs, vec, vec2;
00814 
00815     Vector4Copy( planes[ facet->surfacePlane ].plane, plane );
00816 
00817     w = BaseWindingForPlane( plane,  plane[3] );
00818     for ( j = 0 ; j < facet->numBorders && w ; j++ ) {
00819         if (facet->borderPlanes[j] == facet->surfacePlane) continue;
00820         Vector4Copy( planes[ facet->borderPlanes[j] ].plane, plane );
00821 
00822         if ( !facet->borderInward[j] ) {
00823             VectorSubtract( vec3_origin, plane, plane );
00824             plane[3] = -plane[3];
00825         }
00826 
00827         ChopWindingInPlace( &w, plane, plane[3], 0.1f );
00828     }
00829     if ( !w ) {
00830         return;
00831     }
00832 
00833     WindingBounds(w, mins, maxs);
00834 
00835     // add the axial planes
00836     order = 0;
00837     for ( axis = 0 ; axis < 3 ; axis++ )
00838     {
00839         for ( dir = -1 ; dir <= 1 ; dir += 2, order++ )
00840         {
00841             VectorClear(plane);
00842             plane[axis] = dir;
00843             if (dir == 1) {
00844                 plane[3] = maxs[axis];
00845             }
00846             else {
00847                 plane[3] = -mins[axis];
00848             }
00849             //if it's the surface plane
00850             if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) {
00851                 continue;
00852             }
00853             // see if the plane is allready present
00854             for ( i = 0 ; i < facet->numBorders ; i++ ) {
00855                 if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped))
00856                     break;
00857             }
00858 
00859             if ( i == facet->numBorders ) {
00860                 if (facet->numBorders > 4 + 6 + 16) Com_Printf("ERROR: too many bevels\n");
00861                 facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped);
00862                 facet->borderNoAdjust[facet->numBorders] = 0;
00863                 facet->borderInward[facet->numBorders] = flipped;
00864                 facet->numBorders++;
00865             }
00866         }
00867     }
00868     //
00869     // add the edge bevels
00870     //
00871     // test the non-axial plane edges
00872     for ( j = 0 ; j < w->numpoints ; j++ )
00873     {
00874         k = (j+1)%w->numpoints;
00875         VectorSubtract (w->p[j], w->p[k], vec);
00876         //if it's a degenerate edge
00877         if (VectorNormalize (vec) < 0.5)
00878             continue;
00879         CM_SnapVector(vec);
00880         for ( k = 0; k < 3 ; k++ )
00881             if ( vec[k] == -1 || vec[k] == 1 )
00882                 break;  // axial
00883         if ( k < 3 )
00884             continue;   // only test non-axial edges
00885 
00886         // try the six possible slanted axials from this edge
00887         for ( axis = 0 ; axis < 3 ; axis++ )
00888         {
00889             for ( dir = -1 ; dir <= 1 ; dir += 2 )
00890             {
00891                 // construct a plane
00892                 VectorClear (vec2);
00893                 vec2[axis] = dir;
00894                 CrossProduct (vec, vec2, plane);
00895                 if (VectorNormalize (plane) < 0.5)
00896                     continue;
00897                 plane[3] = DotProduct (w->p[j], plane);
00898 
00899                 // if all the points of the facet winding are
00900                 // behind this plane, it is a proper edge bevel
00901                 for ( l = 0 ; l < w->numpoints ; l++ )
00902                 {
00903                     d = DotProduct (w->p[l], plane) - plane[3];
00904                     if (d > 0.1)
00905                         break;  // point in front
00906                 }
00907                 if ( l < w->numpoints )
00908                     continue;
00909 
00910                 //if it's the surface plane
00911                 if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) {
00912                     continue;
00913                 }
00914                 // see if the plane is allready present
00915                 for ( i = 0 ; i < facet->numBorders ; i++ ) {
00916                     if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped)) {
00917                             break;
00918                     }
00919                 }
00920 
00921                 if ( i == facet->numBorders ) {
00922                     if (facet->numBorders > 4 + 6 + 16) Com_Printf("ERROR: too many bevels\n");
00923                     facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped);
00924 
00925                     for ( k = 0 ; k < facet->numBorders ; k++ ) {
00926                         if (facet->borderPlanes[facet->numBorders] ==
00927                             facet->borderPlanes[k]) Com_Printf("WARNING: bevel plane already used\n");
00928                     }
00929 
00930                     facet->borderNoAdjust[facet->numBorders] = 0;
00931                     facet->borderInward[facet->numBorders] = flipped;
00932                     //
00933                     w2 = CopyWinding(w);
00934                     Vector4Copy(planes[facet->borderPlanes[facet->numBorders]].plane, newplane);
00935                     if (!facet->borderInward[facet->numBorders])
00936                     {
00937                         VectorNegate(newplane, newplane);
00938                         newplane[3] = -newplane[3];
00939                     } //end if
00940                     ChopWindingInPlace( &w2, newplane, newplane[3], 0.1f );
00941                     if (!w2) {
00942                         Com_DPrintf("WARNING: CM_AddFacetBevels... invalid bevel\n");
00943                         continue;
00944                     }
00945                     else {
00946                         FreeWinding(w2);
00947                     }
00948                     //
00949                     facet->numBorders++;
00950                     //already got a bevel
00951 //                  break;
00952                 }
00953             }
00954         }
00955     }
00956     FreeWinding( w );
00957 
00958 #ifndef BSPC
00959     //add opposite plane
00960     facet->borderPlanes[facet->numBorders] = facet->surfacePlane;
00961     facet->borderNoAdjust[facet->numBorders] = 0;
00962     facet->borderInward[facet->numBorders] = qtrue;
00963     facet->numBorders++;
00964 #endif //BSPC
00965 
00966 }

Here is the call graph for this function:

int CM_CheckFacetPlane float *  plane,
vec3_t  start,
vec3_t  end,
float *  enterFrac,
float *  leaveFrac,
int *  hit
 

Definition at line 1331 of file cm_patch.c.

References DotProduct, f, and SURFACE_CLIP_EPSILON.

Referenced by CM_TraceThroughPatchCollide().

01331                                                                                                              {
01332     float d1, d2, f;
01333 
01334     *hit = qfalse;
01335 
01336     d1 = DotProduct( start, plane ) - plane[3];
01337     d2 = DotProduct( end, plane ) - plane[3];
01338 
01339     // if completely in front of face, no intersection with the entire facet
01340     if (d1 > 0 && ( d2 >= SURFACE_CLIP_EPSILON || d2 >= d1 )  ) {
01341         return qfalse;
01342     }
01343 
01344     // if it doesn't cross the plane, the plane isn't relevent
01345     if (d1 <= 0 && d2 <= 0 ) {
01346         return qtrue;
01347     }
01348 
01349     // crosses face
01350     if (d1 > d2) {  // enter
01351         f = (d1-SURFACE_CLIP_EPSILON) / (d1-d2);
01352         if ( f < 0 ) {
01353             f = 0;
01354         }
01355         //always favor previous plane hits and thus also the surface plane hit
01356         if (f > *enterFrac) {
01357             *enterFrac = f;
01358             *hit = qtrue;
01359         }
01360     } else {    // leave
01361         f = (d1+SURFACE_CLIP_EPSILON) / (d1-d2);
01362         if ( f > 1 ) {
01363             f = 1;
01364         }
01365         if (f < *leaveFrac) {
01366             *leaveFrac = f;
01367         }
01368     }
01369     return qtrue;
01370 }

void CM_ClearLevelPatches void   ) 
 

Definition at line 97 of file cm_patch.c.

References debugFacet, and debugPatchCollide.

Referenced by CM_ClearMap(), and CM_LoadMap().

00097                                   {
00098     debugPatchCollide = NULL;
00099     debugFacet = NULL;
00100 }

qboolean CM_ComparePoints float *  a,
float *  b
[static]
 

Definition at line 357 of file cm_patch.c.

References a, b, d, POINT_EPSILON, and qboolean.

Referenced by CM_RemoveDegenerateColumns().

00357                                                        {
00358     float       d;
00359 
00360     d = a[0] - b[0];
00361     if ( d < -POINT_EPSILON || d > POINT_EPSILON ) {
00362         return qfalse;
00363     }
00364     d = a[1] - b[1];
00365     if ( d < -POINT_EPSILON || d > POINT_EPSILON ) {
00366         return qfalse;
00367     }
00368     d = a[2] - b[2];
00369     if ( d < -POINT_EPSILON || d > POINT_EPSILON ) {
00370         return qfalse;
00371     }
00372     return qtrue;
00373 }

void CM_DrawDebugSurface void(*)(int color, int numPoints, float *points drawPoly  ) 
 

Definition at line 1616 of file cm_patch.c.

References BaseWindingForPlane(), facet_t::borderInward, facet_t::borderPlanes, BotDrawDebugPolygons(), patchCollide_s::bounds, ChopWindingInPlace(), Com_Printf(), Cvar_Get(), cvar_t, debugBlockPoints, DotProduct, f, fabs(), patchCollide_s::facets, FreeWinding(), i, cvar_s::integer, j, k, n, facet_t::numBorders, patchCollide_s::numFacets, winding_t::numpoints, winding_t::p, patchCollide_t, patchPlane_t::plane, patchCollide_s::planes, facet_t::surfacePlane, v, v1, v2, cvar_s::value, vec3_origin, vec3_t, Vector4Copy, VectorCopy, VectorNegate, VectorSubtract, and w.

01616                                                                                       {
01617     static cvar_t   *cv;
01618 #ifndef BSPC
01619     static cvar_t   *cv2;
01620 #endif
01621     const patchCollide_t    *pc;
01622     facet_t         *facet;
01623     winding_t       *w;
01624     int             i, j, k, n;
01625     int             curplanenum, planenum, curinward, inward;
01626     float           plane[4];
01627     vec3_t mins = {-15, -15, -28}, maxs = {15, 15, 28};
01628     //vec3_t mins = {0, 0, 0}, maxs = {0, 0, 0};
01629     vec3_t v1, v2;
01630 
01631 #ifndef BSPC
01632     if ( !cv2 )
01633     {
01634         cv2 = Cvar_Get( "r_debugSurface", "0", 0 );
01635     }
01636 
01637     if (cv2->integer != 1)
01638     {
01639         BotDrawDebugPolygons(drawPoly, cv2->integer);
01640         return;
01641     }
01642 #endif
01643 
01644     if ( !debugPatchCollide ) {
01645         return;
01646     }
01647 
01648 #ifndef BSPC
01649     if ( !cv ) {
01650         cv = Cvar_Get( "cm_debugSize", "2", 0 );
01651     }
01652 #endif
01653     pc = debugPatchCollide;
01654 
01655     for ( i = 0, facet = pc->facets ; i < pc->numFacets ; i++, facet++ ) {
01656 
01657         for ( k = 0 ; k < facet->numBorders + 1; k++ ) {
01658             //
01659             if (k < facet->numBorders) {
01660                 planenum = facet->borderPlanes[k];
01661                 inward = facet->borderInward[k];
01662             }
01663             else {
01664                 planenum = facet->surfacePlane;
01665                 inward = qfalse;
01666                 //continue;
01667             }
01668 
01669             Vector4Copy( pc->planes[ planenum ].plane, plane );
01670 
01671             //planenum = facet->surfacePlane;
01672             if ( inward ) {
01673                 VectorSubtract( vec3_origin, plane, plane );
01674                 plane[3] = -plane[3];
01675             }
01676 
01677             plane[3] += cv->value;
01678             //*
01679             for (n = 0; n < 3; n++)
01680             {
01681                 if (plane[n] > 0) v1[n] = maxs[n];
01682                 else v1[n] = mins[n];
01683             } //end for
01684             VectorNegate(plane, v2);
01685             plane[3] += fabs(DotProduct(v1, v2));
01686             //*/
01687 
01688             w = BaseWindingForPlane( plane,  plane[3] );
01689             for ( j = 0 ; j < facet->numBorders + 1 && w; j++ ) {
01690                 //
01691                 if (j < facet->numBorders) {
01692                     curplanenum = facet->borderPlanes[j];
01693                     curinward = facet->borderInward[j];
01694                 }
01695                 else {
01696                     curplanenum = facet->surfacePlane;
01697                     curinward = qfalse;
01698                     //continue;
01699                 }
01700                 //
01701                 if (curplanenum == planenum) continue;
01702 
01703                 Vector4Copy( pc->planes[ curplanenum ].plane, plane );
01704                 if ( !curinward ) {
01705                     VectorSubtract( vec3_origin, plane, plane );
01706                     plane[3] = -plane[3];
01707                 }
01708         //          if ( !facet->borderNoAdjust[j] ) {
01709                     plane[3] -= cv->value;
01710         //          }
01711                 for (n = 0; n < 3; n++)
01712                 {
01713                     if (plane[n] > 0) v1[n] = maxs[n];
01714                     else v1[n] = mins[n];
01715                 } //end for
01716                 VectorNegate(plane, v2);
01717                 plane[3] -= fabs(DotProduct(v1, v2));
01718 
01719                 ChopWindingInPlace( &w, plane, plane[3], 0.1f );
01720             }
01721             if ( w ) {
01722                 if ( facet == debugFacet ) {
01723                     drawPoly( 4, w->numpoints, w->p[0] );
01724                     //Com_Printf("blue facet has %d border planes\n", facet->numBorders);
01725                 } else {
01726                     drawPoly( 1, w->numpoints, w->p[0] );
01727                 }
01728                 FreeWinding( w );
01729             }
01730             else
01731                 Com_Printf("winding chopped away by border planes\n");
01732         }
01733     }
01734 
01735     // draw the debug block
01736     {
01737         vec3_t          v[3];
01738 
01739         VectorCopy( debugBlockPoints[0], v[0] );
01740         VectorCopy( debugBlockPoints[1], v[1] );
01741         VectorCopy( debugBlockPoints[2], v[2] );
01742         drawPoly( 2, 3, v[0] );
01743 
01744         VectorCopy( debugBlockPoints[2], v[0] );
01745         VectorCopy( debugBlockPoints[3], v[1] );
01746         VectorCopy( debugBlockPoints[0], v[2] );
01747         drawPoly( 2, 3, v[0] );
01748     }
01749 
01750 #if 0
01751     vec3_t          v[4];
01752 
01753     v[0][0] = pc->bounds[1][0];
01754     v[0][1] = pc->bounds[1][1];
01755     v[0][2] = pc->bounds[1][2];
01756 
01757     v[1][0] = pc->bounds[1][0];
01758     v[1][1] = pc->bounds[0][1];
01759     v[1][2] = pc->bounds[1][2];
01760 
01761     v[2][0] = pc->bounds[0][0];
01762     v[2][1] = pc->bounds[0][1];
01763     v[2][2] = pc->bounds[1][2];
01764 
01765     v[3][0] = pc->bounds[0][0];
01766     v[3][1] = pc->bounds[1][1];
01767     v[3][2] = pc->bounds[1][2];
01768 
01769     drawPoly( 4, v[0] );
01770 #endif
01771 }

Here is the call graph for this function:

int CM_EdgePlaneNum cGrid_t grid,
int  gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2],
int  i,
int  j,
int  k
[static]
 

Definition at line 619 of file cm_patch.c.

References CM_FindPlane(), CM_GridPlane(), Com_Error(), ERR_DROP, i, j, p, p2, planes, cGrid_t::points, up, vec3_t, and VectorMA.

Referenced by CM_PatchCollideFromGrid().

00619                                                                                                                   {
00620     float   *p1, *p2;
00621     vec3_t      up;
00622     int         p;
00623 
00624     switch ( k ) {
00625     case 0: // top border
00626         p1 = grid->points[i][j];
00627         p2 = grid->points[i+1][j];
00628         p = CM_GridPlane( gridPlanes, i, j, 0 );
00629         VectorMA( p1, 4, planes[ p ].plane, up );
00630         return CM_FindPlane( p1, p2, up );
00631 
00632     case 2: // bottom border
00633         p1 = grid->points[i][j+1];
00634         p2 = grid->points[i+1][j+1];
00635         p = CM_GridPlane( gridPlanes, i, j, 1 );
00636         VectorMA( p1, 4, planes[ p ].plane, up );
00637         return CM_FindPlane( p2, p1, up );
00638 
00639     case 3: // left border
00640         p1 = grid->points[i][j];
00641         p2 = grid->points[i][j+1];
00642         p = CM_GridPlane( gridPlanes, i, j, 1 );
00643         VectorMA( p1, 4, planes[ p ].plane, up );
00644         return CM_FindPlane( p2, p1, up );
00645 
00646     case 1: // right border
00647         p1 = grid->points[i+1][j];
00648         p2 = grid->points[i+1][j+1];
00649         p = CM_GridPlane( gridPlanes, i, j, 0 );
00650         VectorMA( p1, 4, planes[ p ].plane, up );
00651         return CM_FindPlane( p1, p2, up );
00652 
00653     case 4: // diagonal out of triangle 0
00654         p1 = grid->points[i+1][j+1];
00655         p2 = grid->points[i][j];
00656         p = CM_GridPlane( gridPlanes, i, j, 0 );
00657         VectorMA( p1, 4, planes[ p ].plane, up );
00658         return CM_FindPlane( p1, p2, up );
00659 
00660     case 5: // diagonal out of triangle 1
00661         p1 = grid->points[i][j];
00662         p2 = grid->points[i+1][j+1];
00663         p = CM_GridPlane( gridPlanes, i, j, 1 );
00664         VectorMA( p1, 4, planes[ p ].plane, up );
00665         return CM_FindPlane( p1, p2, up );
00666 
00667     }
00668 
00669     Com_Error( ERR_DROP, "CM_EdgePlaneNum: bad k" );
00670     return -1;
00671 }

Here is the call graph for this function:

int CM_FindPlane float *  p1,
float *  p2,
float *  p3
[static]
 

Definition at line 518 of file cm_patch.c.

References CM_PlaneFromPoints(), CM_SignbitsForNormal(), Com_Error(), d, DotProduct, ERR_DROP, i, numPlanes, p2, patchPlane_t::plane, PLANE_TRI_EPSILON, planes, patchPlane_t::signbits, and Vector4Copy.

Referenced by CM_EdgePlaneNum(), and CM_PatchCollideFromGrid().

00518                                                            {
00519     float   plane[4];
00520     int     i;
00521     float   d;
00522 
00523     if ( !CM_PlaneFromPoints( plane, p1, p2, p3 ) ) {
00524         return -1;
00525     }
00526 
00527     // see if the points are close enough to an existing plane
00528     for ( i = 0 ; i < numPlanes ; i++ ) {
00529         if ( DotProduct( plane, planes[i].plane ) < 0 ) {
00530             continue;   // allow backwards planes?
00531         }
00532 
00533         d = DotProduct( p1, planes[i].plane ) - planes[i].plane[3];
00534         if ( d < -PLANE_TRI_EPSILON || d > PLANE_TRI_EPSILON ) {
00535             continue;
00536         }
00537 
00538         d = DotProduct( p2, planes[i].plane ) - planes[i].plane[3];
00539         if ( d < -PLANE_TRI_EPSILON || d > PLANE_TRI_EPSILON ) {
00540             continue;
00541         }
00542 
00543         d = DotProduct( p3, planes[i].plane ) - planes[i].plane[3];
00544         if ( d < -PLANE_TRI_EPSILON || d > PLANE_TRI_EPSILON ) {
00545             continue;
00546         }
00547 
00548         // found it
00549         return i;
00550     }
00551 
00552     // add a new plane
00553     if ( numPlanes == MAX_PATCH_PLANES ) {
00554         Com_Error( ERR_DROP, "MAX_PATCH_PLANES" );
00555     }
00556 
00557     Vector4Copy( plane, planes[numPlanes].plane );
00558     planes[numPlanes].signbits = CM_SignbitsForNormal( plane );
00559 
00560     numPlanes++;
00561 
00562     return numPlanes-1;
00563 }

Here is the call graph for this function:

int CM_FindPlane2 float  plane[4],
int *  flipped
 

Definition at line 490 of file cm_patch.c.

References CM_PlaneEqual(), CM_SignbitsForNormal(), Com_Error(), ERR_DROP, i, numPlanes, planes, patchPlane_t::signbits, and Vector4Copy.

Referenced by CM_AddFacetBevels().

00490                                                 {
00491     int i;
00492 
00493     // see if the points are close enough to an existing plane
00494     for ( i = 0 ; i < numPlanes ; i++ ) {
00495         if (CM_PlaneEqual(&planes[i], plane, flipped)) return i;
00496     }
00497 
00498     // add a new plane
00499     if ( numPlanes == MAX_PATCH_PLANES ) {
00500         Com_Error( ERR_DROP, "MAX_PATCH_PLANES" );
00501     }
00502 
00503     Vector4Copy( plane, planes[numPlanes].plane );
00504     planes[numPlanes].signbits = CM_SignbitsForNormal( plane );
00505 
00506     numPlanes++;
00507 
00508     *flipped = qfalse;
00509 
00510     return numPlanes-1;
00511 }

Here is the call graph for this function:

struct patchCollide_s* CM_GeneratePatchCollide int  width,
int  height,
vec3_t points
 

Definition at line 1148 of file cm_patch.c.

References AddPointToBounds(), c_totalPatchBlocks, ClearBounds(), CM_PatchCollideFromGrid(), CM_RemoveDegenerateColumns(), CM_SetGridWrapWidth(), CM_SubdivideGridColumns(), CM_TransposeGrid(), Com_Error(), ERR_DROP, h_high, height, Hunk_Alloc(), i, j, MAX_GRID_SIZE, patchCollide_t, pf, points, VectorCopy, and width.

Referenced by AAS_CreateCurveBrushes(), and CMod_LoadPatches().

01148                                                                                           {
01149     patchCollide_t  *pf;
01150     MAC_STATIC cGrid_t          grid;
01151     int             i, j;
01152 
01153     if ( width <= 2 || height <= 2 || !points ) {
01154         Com_Error( ERR_DROP, "CM_GeneratePatchFacets: bad parameters: (%i, %i, %p)",
01155             width, height, points );
01156     }
01157 
01158     if ( !(width & 1) || !(height & 1) ) {
01159         Com_Error( ERR_DROP, "CM_GeneratePatchFacets: even sizes are invalid for quadratic meshes" );
01160     }
01161 
01162     if ( width > MAX_GRID_SIZE || height > MAX_GRID_SIZE ) {
01163         Com_Error( ERR_DROP, "CM_GeneratePatchFacets: source is > MAX_GRID_SIZE" );
01164     }
01165 
01166     // build a grid
01167     grid.width = width;
01168     grid.height = height;
01169     grid.wrapWidth = qfalse;
01170     grid.wrapHeight = qfalse;
01171     for ( i = 0 ; i < width ; i++ ) {
01172         for ( j = 0 ; j < height ; j++ ) {
01173             VectorCopy( points[j*width + i], grid.points[i][j] );
01174         }
01175     }
01176 
01177     // subdivide the grid
01178     CM_SetGridWrapWidth( &grid );
01179     CM_SubdivideGridColumns( &grid );
01180     CM_RemoveDegenerateColumns( &grid );
01181 
01182     CM_TransposeGrid( &grid );
01183 
01184     CM_SetGridWrapWidth( &grid );
01185     CM_SubdivideGridColumns( &grid );
01186     CM_RemoveDegenerateColumns( &grid );
01187 
01188     // we now have a grid of points exactly on the curve
01189     // the aproximate surface defined by these points will be
01190     // collided against
01191     pf = Hunk_Alloc( sizeof( *pf ), h_high );
01192     ClearBounds( pf->bounds[0], pf->bounds[1] );
01193     for ( i = 0 ; i < grid.width ; i++ ) {
01194         for ( j = 0 ; j < grid.height ; j++ ) {
01195             AddPointToBounds( grid.points[i][j], pf->bounds[0], pf->bounds[1] );
01196         }
01197     }
01198 
01199     c_totalPatchBlocks += ( grid.width - 1 ) * ( grid.height - 1 );
01200 
01201     // generate a bsp tree for the surface
01202     CM_PatchCollideFromGrid( &grid, pf );
01203 
01204     // expand by one unit for epsilon purposes
01205     pf->bounds[0][0] -= 1;
01206     pf->bounds[0][1] -= 1;
01207     pf->bounds[0][2] -= 1;
01208 
01209     pf->bounds[1][0] += 1;
01210     pf->bounds[1][1] += 1;
01211     pf->bounds[1][2] += 1;
01212 
01213     return pf;
01214 }

Here is the call graph for this function:

int CM_GridPlane int  gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2],
int  i,
int  j,
int  tri
[static]
 

Definition at line 597 of file cm_patch.c.

References Com_Printf(), and p.

Referenced by CM_EdgePlaneNum().

00597                                                                                                    {
00598     int     p;
00599 
00600     p = gridPlanes[i][j][tri];
00601     if ( p != -1 ) {
00602         return p;
00603     }
00604     p = gridPlanes[i][j][!tri];
00605     if ( p != -1 ) {
00606         return p;
00607     }
00608 
00609     // should never happen
00610     Com_Printf( "WARNING: CM_GridPlane unresolvable\n" );
00611     return -1;
00612 }

Here is the call graph for this function:

qboolean CM_NeedsSubdivision vec3_t  a,
vec3_t  b,
vec3_t  c
[static]
 

Definition at line 158 of file cm_patch.c.

References a, b, c, i, qboolean, vec3_t, VectorLength(), and VectorSubtract.

Referenced by CM_SubdivideGridColumns().

00158                                                                     {
00159     vec3_t      cmid;
00160     vec3_t      lmid;
00161     vec3_t      delta;
00162     float       dist;
00163     int         i;
00164 
00165     // calculate the linear midpoint
00166     for ( i = 0 ; i < 3 ; i++ ) {
00167         lmid[i] = 0.5*(a[i] + c[i]);
00168     }
00169 
00170     // calculate the exact curve midpoint
00171     for ( i = 0 ; i < 3 ; i++ ) {
00172         cmid[i] = 0.5 * ( 0.5*(a[i] + b[i]) + 0.5*(b[i] + c[i]) );
00173     }
00174 
00175     // see if the curve is far enough away from the linear mid
00176     VectorSubtract( cmid, lmid, delta );
00177     dist = VectorLength( delta );
00178     
00179     return dist >= SUBDIVIDE_DISTANCE;
00180 }

Here is the call graph for this function:

void CM_PatchCollideFromGrid cGrid_t grid,
patchCollide_t pf
[static]
 

Definition at line 980 of file cm_patch.c.

References facet_t::borderNoAdjust, facet_t::borderPlanes, CM_AddFacetBevels(), CM_EdgePlaneNum(), CM_FindPlane(), CM_SetBorderInward(), CM_ValidateFacet(), Com_Error(), Com_Memcpy(), Com_Memset(), ERR_DROP, facets, h_high, cGrid_t::height, Hunk_Alloc(), i, j, facet_t::numBorders, numFacets, numPlanes, p2, patchCollide_t, pf, planes, cGrid_t::points, facet_t::surfacePlane, cGrid_t::width, cGrid_t::wrapHeight, and cGrid_t::wrapWidth.

Referenced by CM_GeneratePatchCollide().

00980                                                                          {
00981     int             i, j;
00982     float           *p1, *p2, *p3;
00983     MAC_STATIC int              gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2];
00984     facet_t         *facet;
00985     int             borders[4];
00986     int             noAdjust[4];
00987 
00988     numPlanes = 0;
00989     numFacets = 0;
00990 
00991     // find the planes for each triangle of the grid
00992     for ( i = 0 ; i < grid->width - 1 ; i++ ) {
00993         for ( j = 0 ; j < grid->height - 1 ; j++ ) {
00994             p1 = grid->points[i][j];
00995             p2 = grid->points[i+1][j];
00996             p3 = grid->points[i+1][j+1];
00997             gridPlanes[i][j][0] = CM_FindPlane( p1, p2, p3 );
00998 
00999             p1 = grid->points[i+1][j+1];
01000             p2 = grid->points[i][j+1];
01001             p3 = grid->points[i][j];
01002             gridPlanes[i][j][1] = CM_FindPlane( p1, p2, p3 );
01003         }
01004     }
01005 
01006     // create the borders for each facet
01007     for ( i = 0 ; i < grid->width - 1 ; i++ ) {
01008         for ( j = 0 ; j < grid->height - 1 ; j++ ) {
01009              
01010             borders[EN_TOP] = -1;
01011             if ( j > 0 ) {
01012                 borders