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

Winding.h File Reference

Go to the source code of this file.

Functions

int Plane_Equal (plane_t *a, plane_t *b, int flip)
int Plane_FromPoints (vec3_t p1, vec3_t p2, vec3_t p3, plane_t *plane)
int Point_Equal (vec3_t p1, vec3_t p2, float epsilon)
winding_tWinding_Alloc (int points)
float Winding_Area (winding_t *w)
winding_tWinding_BaseForPlane (plane_t *p)
void Winding_Bounds (winding_t *w, vec3_t mins, vec3_t maxs)
winding_tWinding_Clip (winding_t *in, plane_t *split, qboolean keepon)
winding_tWinding_Clone (winding_t *w)
void Winding_Free (winding_t *w)
winding_tWinding_InsertPoint (winding_t *w, vec3_t point, int spot)
int Winding_IsHuge (winding_t *w)
int Winding_IsTiny (winding_t *w)
void Winding_Plane (winding_t *w, vec3_t normal, double *dist)
int Winding_PlanesConcave (winding_t *w1, winding_t *w2, vec3_t normal1, vec3_t normal2, float dist1, float dist2)
int Winding_PointInside (winding_t *w, plane_t *plane, vec3_t point, float epsilon)
void Winding_RemovePoint (winding_t *w, int point)
winding_tWinding_Reverse (winding_t *w)
void Winding_SplitEpsilon (winding_t *in, vec3_t normal, double dist, vec_t epsilon, winding_t **front, winding_t **back)
winding_tWinding_TryMerge (winding_t *f1, winding_t *f2, vec3_t planenormal, int keep)
int Winding_VectorIntersect (winding_t *w, plane_t *plane, vec3_t p1, vec3_t p2, float epsilon)


Function Documentation

int Plane_Equal plane_t a,
plane_t b,
int  flip
 

Definition at line 1139 of file lightv.c.

References a, b, plane_t::dist, fabs(), plane_t::normal, NORMAL_EPSILON, and vec3_t.

Referenced by Brush_Merge(), Brush_MergeList(), VL_GenerateFacetFor4Points(), and VS_GenerateFacetFor4Points().

01140 {
01141     vec3_t normal;
01142     float dist;
01143 
01144     if (flip) {
01145         normal[0] = - b->normal[0];
01146         normal[1] = - b->normal[1];
01147         normal[2] = - b->normal[2];
01148         dist = - b->dist;
01149     }
01150     else {
01151         normal[0] = b->normal[0];
01152         normal[1] = b->normal[1];
01153         normal[2] = b->normal[2];
01154         dist = b->dist;
01155     }
01156     if (
01157        fabs(a->normal[0] - normal[0]) < NORMAL_EPSILON
01158     && fabs(a->normal[1] - normal[1]) < NORMAL_EPSILON
01159     && fabs(a->normal[2] - normal[2]) < NORMAL_EPSILON
01160     && fabs(a->dist - dist) < DIST_EPSILON )
01161         return qtrue;
01162     return qfalse;
01163 }

Here is the call graph for this function:

int Plane_FromPoints vec3_t  p1,
vec3_t  p2,
vec3_t  p3,
plane_t plane
 

Definition at line 70 of file Winding.cpp.

References CrossProduct(), plane_t::dist, DotProduct, plane_t::normal, p2, v1, v2, vec3_t, VectorNormalize(), and VectorSubtract.

00071 {
00072     vec3_t v1, v2;
00073 
00074     VectorSubtract(p2, p1, v1);
00075     VectorSubtract(p3, p1, v2);
00076     //CrossProduct(v2, v1, plane->normal);
00077     CrossProduct(v1, v2, plane->normal);
00078     if (VectorNormalize(plane->normal) < 0.1) return false;
00079     plane->dist = DotProduct(p1, plane->normal);
00080     return true;
00081 }

Here is the call graph for this function:

int Point_Equal vec3_t  p1,
vec3_t  p2,
float  epsilon
 

Definition at line 88 of file Winding.cpp.

References fabs(), i, and p2.

Referenced by Brush_MoveVertex_old1().

00089 {
00090     int i;
00091 
00092     for (i = 0; i < 3; i++)
00093     {
00094         if (fabs(p1[i] - p2[i]) > epsilon) return false;
00095     }
00096     return true;
00097 }

Here is the call graph for this function:

winding_t* Winding_Alloc int  points  ) 
 

Definition at line 177 of file Winding.cpp.

References Error(), malloc(), winding_t::maxpoints, memset(), winding_t::points, points, and w.

Referenced by Winding_BaseForPlane(), Winding_Clip(), Winding_InsertPoint(), Winding_Reverse(), Winding_SplitEpsilon(), and Winding_TryMerge().

00178 {
00179     winding_t   *w;
00180     int         size;
00181     
00182     if (points > MAX_POINTS_ON_WINDING)
00183         Error ("Winding_Alloc: %i points", points);
00184     
00185     size = (int)((winding_t *)0)->points[points];
00186     w = (winding_t*) malloc (size);
00187     memset (w, 0, size);
00188     w->maxpoints = points;
00189     
00190     return w;
00191 }

Here is the call graph for this function:

float Winding_Area winding_t w  ) 
 

Definition at line 722 of file Winding.cpp.

References CrossProduct(), i, winding_t::numpoints, winding_t::points, vec3_t, VectorLength(), VectorSubtract, and w.

00723 {
00724     int     i;
00725     vec3_t  d1, d2, cross;
00726     float   total;
00727 
00728     total = 0;
00729     for (i=2 ; i<w->numpoints ; i++)
00730     {
00731         VectorSubtract (w->points[i-1], w->points[0], d1);
00732         VectorSubtract (w->points[i], w->points[0], d2);
00733         CrossProduct (d1, d2, cross);
00734         total += 0.5 * VectorLength ( cross );
00735     }
00736     return total;
00737 }

Here is the call graph for this function:

winding_t* Winding_BaseForPlane plane_t p  ) 
 

Definition at line 105 of file Winding.cpp.

References BOGUS_RANGE, CrossProduct(), plane_t::dist, DotProduct, Error(), fabs(), i, max, plane_t::normal, winding_t::numpoints, p, winding_t::points, v, vec3_origin, vec3_t, vec_t, VectorAdd, VectorCopy, VectorMA, VectorNormalize(), VectorScale, VectorSubtract, vright, vup, w, Winding_Alloc(), and x.

Referenced by Brush_MakeFaceWinding().

00106 {
00107     int     i, x;
00108     vec_t   max, v;
00109     vec3_t  org, vright, vup;
00110     winding_t   *w;
00111     
00112     // find the major axis
00113 
00114     max = -BOGUS_RANGE;
00115     x = -1;
00116     for (i=0 ; i<3; i++)
00117     {
00118         v = fabs(p->normal[i]);
00119         if (v > max)
00120         {
00121             x = i;
00122             max = v;
00123         }
00124     }
00125     if (x==-1)
00126         Error ("Winding_BaseForPlane: no axis found");
00127         
00128     VectorCopy (vec3_origin, vup);  
00129     switch (x)
00130     {
00131     case 0:
00132     case 1:
00133         vup[2] = 1;
00134         break;      
00135     case 2:
00136         vup[0] = 1;
00137         break;      
00138     }
00139 
00140 
00141     v = DotProduct (vup, p->normal);
00142     VectorMA (vup, -v, p->normal, vup);
00143     VectorNormalize (vup);
00144         
00145     VectorScale (p->normal, p->dist, org);
00146     
00147     CrossProduct (vup, p->normal, vright);
00148     
00149     VectorScale (vup, BOGUS_RANGE, vup);
00150     VectorScale (vright, BOGUS_RANGE, vright);
00151 
00152     // project a really big axis aligned box onto the plane
00153     w = Winding_Alloc (4);
00154     
00155     VectorSubtract (org, vright, w->points[0]);
00156     VectorAdd (w->points[0], vup, w->points[0]);
00157     
00158     VectorAdd (org, vright, w->points[1]);
00159     VectorAdd (w->points[1], vup, w->points[1]);
00160     
00161     VectorAdd (org, vright, w->points[2]);
00162     VectorSubtract (w->points[2], vup, w->points[2]);
00163     
00164     VectorSubtract (org, vright, w->points[3]);
00165     VectorSubtract (w->points[3], vup, w->points[3]);
00166     
00167     w->numpoints = 4;
00168     
00169     return w;   
00170 }

Here is the call graph for this function:

void Winding_Bounds winding_t w,
vec3_t  mins,
vec3_t  maxs
 

Definition at line 744 of file Winding.cpp.

References i, j, winding_t::numpoints, winding_t::points, v, vec_t, and w.

00745 {
00746     vec_t   v;
00747     int     i,j;
00748 
00749     mins[0] = mins[1] = mins[2] = 99999;
00750     maxs[0] = maxs[1] = maxs[2] = -99999;
00751 
00752     for (i=0 ; i<w->numpoints ; i++)
00753     {
00754         for (j=0 ; j<3 ; j++)
00755         {
00756             v = w->points[i][j];
00757             if (v < mins[j])
00758                 mins[j] = v;
00759             if (v > maxs[j])
00760                 maxs[j] = v;
00761         }
00762     }
00763 }

winding_t* Winding_Clip winding_t in,
plane_t split,
qboolean  keepon
 

Definition at line 374 of file Winding.cpp.

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

Referenced by Brush_MakeFaceWinding().

00375 {
00376     vec_t   dists[MAX_POINTS_ON_WINDING];
00377     int     sides[MAX_POINTS_ON_WINDING];
00378     int     counts[3];
00379     vec_t   dot;
00380     int     i, j;
00381     vec_t   *p1, *p2;
00382     vec3_t  mid;
00383     winding_t   *neww;
00384     int     maxpts;
00385     
00386     counts[0] = counts[1] = counts[2] = 0;
00387 
00388     // determine sides for each point
00389     for (i=0 ; i<in->numpoints ; i++)
00390     {
00391         dot = DotProduct (in->points[i], split->normal);
00392         dot -= split->dist;
00393         dists[i] = dot;
00394         if (dot > ON_EPSILON)
00395             sides[i] = SIDE_FRONT;
00396         else if (dot < -ON_EPSILON)
00397             sides[i] = SIDE_BACK;
00398         else
00399         {
00400             sides[i] = SIDE_ON;
00401         }
00402         counts[sides[i]]++;
00403     }
00404     sides[i] = sides[0];
00405     dists[i] = dists[0];
00406     
00407     if (keepon && !counts[0] && !counts[1])
00408         return in;
00409         
00410     if (!counts[0])
00411     {
00412         Winding_Free (in);
00413         return NULL;
00414     }
00415     if (!counts[1])
00416         return in;
00417     
00418     maxpts = in->numpoints+4;   // can't use counts[0]+2 because
00419                                 // of fp grouping errors
00420     neww = Winding_Alloc (maxpts);
00421         
00422     for (i=0 ; i<in->numpoints ; i++)
00423     {
00424         p1 = in->points[i];
00425         
00426         if (sides[i] == SIDE_ON)
00427         {
00428             VectorCopy (p1, neww->points[neww->numpoints]);
00429             neww->numpoints++;
00430             continue;
00431         }
00432     
00433         if (sides[i] == SIDE_FRONT)
00434         {
00435             VectorCopy (p1, neww->points[neww->numpoints]);
00436             neww->numpoints++;
00437         }
00438         
00439         if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
00440             continue;
00441             
00442         // generate a split point
00443         p2 = in->points[(i+1)%in->numpoints];
00444         
00445         dot = dists[i] / (dists[i]-dists[i+1]);
00446         for (j=0 ; j<3 ; j++)
00447         {   // avoid round off error when possible
00448             if (split->normal[j] == 1)
00449                 mid[j] = split->dist;
00450             else if (split->normal[j] == -1)
00451                 mid[j] = -split->dist;
00452             else
00453                 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
00454         }
00455             
00456         VectorCopy (mid, neww->points[neww->numpoints]);
00457         neww->numpoints++;
00458     }
00459     
00460     if (neww->numpoints > maxpts)
00461         Error ("Winding_Clip: points exceeded estimate");
00462         
00463     // free the original winding
00464     Winding_Free (in);
00465     
00466     return neww;
00467 }

Here is the call graph for this function:

winding_t* Winding_Clone winding_t w  ) 
 

Definition at line 205 of file Winding.cpp.

References c, memcpy(), winding_t::numpoints, winding_t::points, qmalloc(), and w.

Referenced by Face_FullClone(), and Winding_SplitEpsilon().

00206 {
00207     int         size;
00208     winding_t   *c;
00209     
00210     size = (int)((winding_t *)0)->points[w->numpoints];
00211     c = (winding_t*)qmalloc (size);
00212     memcpy (c, w, size);
00213     return c;
00214 }

Here is the call graph for this function:

void Winding_Free winding_t w  ) 
 

Definition at line 194 of file Winding.cpp.

References free(), and w.

Referenced by Brush_BestSplitFace(), and Winding_Clip().

00195 {
00196     free(w);
00197 }

Here is the call graph for this function:

winding_t* Winding_InsertPoint winding_t w,
vec3_t  point,
int  spot
 

Definition at line 258 of file Winding.cpp.

References Error(), i, j, winding_t::numpoints, point, winding_t::points, VectorCopy, w, and Winding_Alloc().

Referenced by Brush_InsertVertexBetween().

00259 {
00260     int i, j;
00261     winding_t *neww;
00262 
00263     if (spot > w->numpoints)
00264     {
00265         Error("Winding_InsertPoint: spot > w->numpoints");
00266     } //end if
00267     if (spot < 0)
00268     {
00269         Error("Winding_InsertPoint: spot < 0");
00270     } //end if
00271     neww = Winding_Alloc(w->numpoints + 1);
00272     neww->numpoints = w->numpoints + 1;
00273     for (i = 0, j = 0; i < neww->numpoints; i++)
00274     {
00275         if (i == spot)
00276         {
00277             VectorCopy(point, neww->points[i]);
00278         }
00279         else
00280         {
00281             VectorCopy(w->points[j], neww->points[i]);
00282             j++;
00283         }
00284     }
00285     return neww;
00286 }

Here is the call graph for this function:

int Winding_IsHuge winding_t w  ) 
 

Definition at line 322 of file Winding.cpp.

References BOGUS_RANGE, i, j, winding_t::numpoints, winding_t::points, and w.

00323 {
00324     int     i, j;
00325 
00326     for (i=0 ; i<w->numpoints ; i++)
00327     {
00328         for (j=0 ; j<3 ; j++)
00329             if (w->points[i][j] < -BOGUS_RANGE+1 || w->points[i][j] > BOGUS_RANGE-1)
00330                 return true;
00331     }
00332     return false;
00333 }

int Winding_IsTiny winding_t w  ) 
 

Definition at line 295 of file Winding.cpp.

References i, j, winding_t::numpoints, winding_t::points, vec3_t, vec_t, VectorLength(), VectorSubtract, and w.

Referenced by Brush_BestSplitFace().

00296 {
00297     int     i, j;
00298     vec_t   len;
00299     vec3_t  delta;
00300     int     edges;
00301 
00302     edges = 0;
00303     for (i=0 ; i<w->numpoints ; i++)
00304     {
00305         j = i == w->numpoints - 1 ? 0 : i+1;
00306         VectorSubtract (w->points[j], w->points[i], delta);
00307         len = VectorLength (delta);
00308         if (len > EDGE_LENGTH)
00309         {
00310             if (++edges == 3)
00311                 return false;
00312         }
00313     }
00314     return true;
00315 }

Here is the call graph for this function:

void Winding_Plane winding_t w,
vec3_t  normal,
double *  dist
 

Definition at line 700 of file Winding.cpp.

References CrossProduct(), DotProduct, i, winding_t::numpoints, winding_t::points, v1, v2, vec3_t, VectorLength(), VectorNormalize(), VectorSubtract, and w.

00701 {
00702     vec3_t v1, v2;
00703     int i;
00704 
00705     //find two vectors each longer than 0.5 units
00706     for (i = 0; i < w->numpoints; i++)
00707     {
00708         VectorSubtract(w->points[(i+1) % w->numpoints], w->points[i], v1);
00709         VectorSubtract(w->points[(i+2) % w->numpoints], w->points[i], v2);
00710         if (VectorLength(v1) > 0.5 && VectorLength(v2) > 0.5) break;
00711     }
00712     CrossProduct(v2, v1, normal);
00713     VectorNormalize(normal);
00714     *dist = DotProduct(w->points[0], normal);
00715 }

Here is the call graph for this function:

int Winding_PlanesConcave winding_t w1,
winding_t w2,
vec3_t  normal1,
vec3_t  normal2,
float  dist1,
float  dist2
 

Definition at line 409 of file vis.c.

References DotProduct, i, winding_t::numpoints, and winding_t::points.

Referenced by Brush_Convex(), Brush_Merge(), Brush_MergeList(), and TryMergeLeaves().

00412 {
00413     int i;
00414 
00415     if (!w1 || !w2) return qfalse;
00416 
00417     // check if one of the points of winding 1 is at the front of the plane of winding 2
00418     for (i = 0; i < w1->numpoints; i++)
00419     {
00420         if (DotProduct(normal2, w1->points[i]) - dist2 > WCONVEX_EPSILON) return qtrue;
00421     }
00422     // check if one of the points of winding 2 is at the front of the plane of winding 1
00423     for (i = 0; i < w2->numpoints; i++)
00424     {
00425         if (DotProduct(normal1, w2->points[i]) - dist1 > WCONVEX_EPSILON) return qtrue;
00426     }
00427 
00428     return qfalse;
00429 }

int Winding_PointInside winding_t w,
plane_t plane,
vec3_t  point,
float  epsilon
 

Definition at line 771 of file Winding.cpp.

References CrossProduct(), DotProduct, i, plane_t::normal, winding_t::numpoints, point, winding_t::points, vec3_t, VectorSubtract, and w.

Referenced by Winding_VectorIntersect().

00772 {
00773     int i;
00774     vec3_t dir, normal, pointvec;
00775 
00776     for (i = 0; i < w->numpoints; i++)
00777     {
00778         VectorSubtract(w->points[(i+1) % w->numpoints], w->points[i], dir);
00779         VectorSubtract(point, w->points[i], pointvec);
00780         //
00781         CrossProduct(dir, plane->normal, normal);
00782         //
00783         if (DotProduct(pointvec, normal) < -epsilon) return false;
00784     }
00785     return true;
00786 }

Here is the call graph for this function:

void Winding_RemovePoint winding_t w,
int  point
 

Definition at line 241 of file Winding.cpp.

References Error(), memmove(), winding_t::numpoints, point, winding_t::points, and w.

00242 {
00243     if (point < 0 || point >= w->numpoints)
00244         Error("Winding_RemovePoint: point out of range");
00245 
00246     if (point < w->numpoints-1)
00247     {
00248         memmove(&w->points[point], &w->points[point+1], (int)((winding_t *)0)->points[w->numpoints - point - 1]);
00249     }
00250     w->numpoints--;
00251 }

Here is the call graph for this function:

winding_t* Winding_Reverse winding_t w  ) 
 

Definition at line 221 of file Winding.cpp.

References c, i, winding_t::numpoints, winding_t::points, VectorCopy, w, and Winding_Alloc().

00222 {
00223     int         i;
00224     winding_t   *c;
00225 
00226     c = Winding_Alloc(w->numpoints);
00227     for (i = 0; i < w->numpoints; i++)
00228     {
00229         VectorCopy (w->points[w->numpoints-1-i], c->points[i]);
00230     }
00231     c->numpoints = w->numpoints;
00232     return c;
00233 }

Here is the call graph for this function:

void Winding_SplitEpsilon winding_t in,
vec3_t  normal,
double  dist,
vec_t  epsilon,
winding_t **  front,
winding_t **  back
 

Definition at line 477 of file Winding.cpp.

References b, DotProduct, Error(), f, i, in, j, MAX_POINTS_ON_WINDING, winding_t::numpoints, p2, winding_t::points, SIDE_ON, vec3_t, vec_t, VectorCopy, Winding_Alloc(), and Winding_Clone().

Referenced by Brush_BestSplitFace().

00479 {
00480     vec_t   dists[MAX_POINTS_ON_WINDING+4];
00481     int     sides[MAX_POINTS_ON_WINDING+4];
00482     int     counts[3];
00483     vec_t   dot;
00484     int     i, j;
00485     vec_t   *p1, *p2;
00486     vec3_t  mid;
00487     winding_t   *f, *b;
00488     int     maxpts;
00489     
00490     counts[0] = counts[1] = counts[2] = 0;
00491 
00492     // determine sides for each point
00493     for (i = 0; i < in->numpoints; i++)
00494     {
00495         dot = DotProduct (in->points[i], normal);
00496         dot -= dist;
00497         dists[i] = dot;
00498         if (dot > epsilon)
00499             sides[i] = SIDE_FRONT;
00500         else if (dot < -epsilon)
00501             sides[i] = SIDE_BACK;
00502         else
00503         {
00504             sides[i] = SIDE_ON;
00505         }
00506         counts[sides[i]]++;
00507     }
00508     sides[i] = sides[0];
00509     dists[i] = dists[0];
00510     
00511     *front = *back = NULL;
00512 
00513     if (!counts[0])
00514     {
00515         *back = Winding_Clone(in);
00516         return;
00517     }
00518     if (!counts[1])
00519     {
00520         *front = Winding_Clone(in);
00521         return;
00522     }
00523 
00524     maxpts = in->numpoints+4;   // cant use counts[0]+2 because
00525                                 // of fp grouping errors
00526 
00527     *front = f = Winding_Alloc (maxpts);
00528     *back = b = Winding_Alloc (maxpts);
00529         
00530     for (i = 0; i < in->numpoints; i++)
00531     {
00532         p1 = in->points[i];
00533         
00534         if (sides[i] == SIDE_ON)
00535         {
00536             VectorCopy (p1, f->points[f->numpoints]);
00537             f->numpoints++;
00538             VectorCopy (p1, b->points[b->numpoints]);
00539             b->numpoints++;
00540             continue;
00541         }
00542     
00543         if (sides[i] == SIDE_FRONT)
00544         {
00545             VectorCopy (p1, f->points[f->numpoints]);
00546             f->numpoints++;
00547         }
00548         if (sides[i] == SIDE_BACK)
00549         {
00550             VectorCopy (p1, b->points[b->numpoints]);
00551             b->numpoints++;
00552         }
00553 
00554         if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
00555             continue;
00556             
00557         // generate a split point
00558         p2 = in->points[(i+1)%in->numpoints];
00559         
00560         dot = dists[i] / (dists[i]-dists[i+1]);
00561         for (j = 0; j < 3; j++)
00562         {
00563             // avoid round off error when possible
00564             if (normal[j] == 1)
00565                 mid[j] = dist;
00566             else if (normal[j] == -1)
00567                 mid[j] = -dist;
00568             else
00569                 mid[j] = p1[j] + dot*(p2[j]-p1[j]);
00570         }
00571             
00572         VectorCopy (mid, f->points[f->numpoints]);
00573         f->numpoints++;
00574         VectorCopy (mid, b->points[b->numpoints]);
00575         b->numpoints++;
00576     }
00577     
00578     if (f->numpoints > maxpts || b->numpoints > maxpts)
00579         Error ("Winding_Clip: points exceeded estimate");
00580     if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING)
00581         Error ("Winding_Clip: MAX_POINTS_ON_WINDING");
00582 }

Here is the call graph for this function:

winding_t* Winding_TryMerge winding_t f1,
winding_t f2,
vec3_t  planenormal,
int  keep
 

Definition at line 599 of file Winding.cpp.

References CrossProduct(), DotProduct, f1(), f2(), fabs(), i, j, k, l, winding_t::numpoints, p2, winding_t::points, qboolean, vec3_t, vec_t, VectorCopy, VectorNormalize(), VectorSubtract, and Winding_Alloc().

00600 {
00601     vec_t       *p1, *p2, *p3, *p4, *back;
00602     winding_t   *newf;
00603     int         i, j, k, l;
00604     vec3_t      normal, delta;
00605     vec_t       dot;
00606     qboolean    keep1, keep2;
00607     
00608 
00609     //
00610     // find a common edge
00611     //  
00612     p1 = p2 = NULL; // stop compiler warning
00613     j = 0;          // 
00614     
00615     for (i = 0; i < f1->numpoints; i++)
00616     {
00617         p1 = f1->points[i];
00618         p2 = f1->points[(i+1) % f1->numpoints];
00619         for (j = 0; j < f2->numpoints; j++)
00620         {
00621             p3 = f2->points[j];
00622             p4 = f2->points[(j+1) % f2->numpoints];
00623             for (k = 0; k < 3; k++)
00624             {
00625                 if (fabs(p1[k] - p4[k]) > 0.1)//EQUAL_EPSILON) //ME
00626                     break;
00627                 if (fabs(p2[k] - p3[k]) > 0.1)//EQUAL_EPSILON) //ME
00628                     break;
00629             } //end for
00630             if (k==3)
00631                 break;
00632         } //end for
00633         if (j < f2->numpoints)
00634             break;
00635     } //end for
00636     
00637     if (i == f1->numpoints)
00638         return NULL;            // no matching edges
00639 
00640     //
00641     // check slope of connected lines
00642     // if the slopes are colinear, the point can be removed
00643     //
00644     back = f1->points[(i+f1->numpoints-1)%f1->numpoints];
00645     VectorSubtract (p1, back, delta);
00646     CrossProduct (planenormal, delta, normal);
00647     VectorNormalize (normal);
00648     
00649     back = f2->points[(j+2)%f2->numpoints];
00650     VectorSubtract (back, p1, delta);
00651     dot = DotProduct (delta, normal);
00652     if (dot > CONTINUOUS_EPSILON)
00653         return NULL;            // not a convex polygon
00654     keep1 = (qboolean)(dot < -CONTINUOUS_EPSILON);
00655     
00656     back = f1->points[(i+2)%f1->numpoints];
00657     VectorSubtract (back, p2, delta);
00658     CrossProduct (planenormal, delta, normal);
00659     VectorNormalize (normal);
00660 
00661     back = f2->points[(j+f2->numpoints-1)%f2->numpoints];
00662     VectorSubtract (back, p2, delta);
00663     dot = DotProduct (delta, normal);
00664     if (dot > CONTINUOUS_EPSILON)
00665         return NULL;            // not a convex polygon
00666     keep2 = (qboolean)(dot < -CONTINUOUS_EPSILON);
00667 
00668     //
00669     // build the new polygon
00670     //
00671     newf = Winding_Alloc (f1->numpoints + f2->numpoints);
00672     
00673     // copy first polygon
00674     for (k=(i+1)%f1->numpoints ; k != i ; k=(k+1)%f1->numpoints)
00675     {
00676         if (!keep && k==(i+1)%f1->numpoints && !keep2)
00677             continue;
00678         
00679         VectorCopy (f1->points[k], newf->points[newf->numpoints]);
00680         newf->numpoints++;
00681     }
00682     
00683     // copy second polygon
00684     for (l= (j+1)%f2->numpoints ; l != j ; l=(l+1)%f2->numpoints)
00685     {
00686         if (!keep && l==(j+1)%f2->numpoints && !keep1)
00687             continue;
00688         VectorCopy (f2->points[l], newf->points[newf->numpoints]);
00689         newf->numpoints++;
00690     }
00691 
00692     return newf;
00693 }

Here is the call graph for this function:

int Winding_VectorIntersect winding_t w,
plane_t plane,
vec3_t  p1,
vec3_t  p2,
float  epsilon
 

Definition at line 793 of file Winding.cpp.

References plane_t::dist, DotProduct, fabs(), plane_t::normal, p2, vec3_t, VectorCopy, w, and Winding_PointInside().

00794 {
00795     float front, back, frac;
00796     vec3_t mid;
00797 
00798     front = DotProduct(p1, plane->normal) - plane->dist;
00799     back = DotProduct(p2, plane->normal) - plane->dist;
00800     //if both points at the same side of the plane
00801     if (front < -epsilon && back < -epsilon) return false;
00802     if (front > epsilon && back > epsilon) return false;
00803     //get point of intersection with winding plane
00804     if (fabs(front-back) < 0.001)
00805     {
00806         VectorCopy(p2, mid);
00807     }
00808     else
00809     {
00810         frac = front/(front-back);
00811         mid[0] = p1[0] + (p2[0] - p1[0]) * frac;
00812         mid[1] = p1[1] + (p2[1] - p1[1]) * frac;
00813         mid[2] = p1[2] + (p2[2] - p1[2]) * frac;
00814     }
00815     return Winding_PointInside(w, plane, mid, epsilon);
00816 }

Here is the call graph for this function:


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