diff --git a/tools/qfbsp/include/bsp5.h b/tools/qfbsp/include/bsp5.h index ca15279a7..832602142 100644 --- a/tools/qfbsp/include/bsp5.h +++ b/tools/qfbsp/include/bsp5.h @@ -61,6 +61,7 @@ void CheckWinding (winding_t *w); winding_t *NewWinding (int points); void FreeWinding (winding_t *w); winding_t *CopyWinding (winding_t *w); +winding_t *CopyWindingReverse (winding_t *w); winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon); void DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t **back); @@ -84,9 +85,8 @@ typedef struct visfacet_s // write surfaces qboolean detail; // is a detail face - int numpoints; - vec3_t pts[MAXEDGES]; // FIXME: change to use winding_t - int edges[MAXEDGES]; + winding_t *points; + int *edges; } face_t; typedef struct surface_s diff --git a/tools/qfbsp/source/brush.c b/tools/qfbsp/source/brush.c index c8c3ac6af..f5145f434 100644 --- a/tools/qfbsp/source/brush.c +++ b/tools/qfbsp/source/brush.c @@ -53,21 +53,21 @@ CheckFace (face_t *f) vec_t d, edgedist; vec3_t dir, edgenormal, facenormal; - if (f->numpoints < 3) - Sys_Error ("CheckFace: %i points", f->numpoints); + if (f->points->numpoints < 3) + Sys_Error ("CheckFace: %i points", f->points->numpoints); VectorCopy (planes[f->planenum].normal, facenormal); if (f->planeside) VectorNegate (facenormal, facenormal); - for (i = 0; i < f->numpoints; i++) { - p1 = f->pts[i]; + for (i = 0; i < f->points->numpoints; i++) { + p1 = f->points->points[i]; for (j = 0; j < 3; j++) if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE) Sys_Error ("CheckFace: BUGUS_RANGE: %f", p1[j]); - j = i + 1 == f->numpoints ? 0 : i + 1; + j = i + 1 == f->points->numpoints ? 0 : i + 1; // check the point is on the face plane d = DotProduct (p1, planes[f->planenum].normal) @@ -80,7 +80,7 @@ CheckFace (face_t *f) #endif // check the edge isn't degenerate - p2 = f->pts[j]; + p2 = f->points->points[j]; VectorSubtract (p2, p1, dir); if (VectorLength (dir) < ON_EPSILON) @@ -92,10 +92,10 @@ CheckFace (face_t *f) edgedist += ON_EPSILON; // all other points must be on front side - for (j = 0; j < f->numpoints; j++) { + for (j = 0; j < f->points->numpoints; j++) { if (j == i) continue; - d = DotProduct (f->pts[j], edgenormal); + d = DotProduct (f->points->points[j], edgenormal); if (d > edgedist) Sys_Error ("CheckFace: non-convex"); } @@ -318,27 +318,24 @@ CreateBrushFaces (void) } if (!w) - continue; // overcontrained plane + continue; // overconstrained plane // this face is a keeper f = AllocFace (); - f->numpoints = w->numpoints; - if (f->numpoints > MAXEDGES) - Sys_Error ("f->numpoints > MAXEDGES"); + f->points = w; for (j = 0; j < w->numpoints; j++) { + vec_t *v = f->points->points[j]; + VectorSubtract (v, offset, v); for (k = 0; k < 3; k++) { - point[k] = w->points[j][k] - offset[k]; - r = RINT (point[k]); - if (fabs (point[k] - r) < ZERO_EPSILON) - f->pts[j][k] = r; - else - f->pts[j][k] = point[k]; + r = RINT (v[k]); + if (fabs (v[k] - r) < ZERO_EPSILON) + v[k] = r; - if (f->pts[j][k] < brush_mins[k]) - brush_mins[k] = f->pts[j][k]; - if (f->pts[j][k] > brush_maxs[k]) - brush_maxs[k] = f->pts[j][k]; + if (v[k] < brush_mins[k]) + brush_mins[k] = v[k]; + if (v[k] > brush_maxs[k]) + brush_maxs[k] = v[k]; } } @@ -347,7 +344,6 @@ CreateBrushFaces (void) VectorSubtract (point, offset, point); plane.dist = DotProduct (plane.normal, point); - FreeWinding (w); f->texturenum = mf->texinfo; f->planenum = FindPlane (&plane, &f->planeside); f->next = brush_faces; @@ -588,8 +584,8 @@ ExpandBrush (int hullnum) // create all the hull points for (f = brush_faces; f; f = f->next) - for (i = 0; i < f->numpoints; i++) - AddHullPoint (f->pts[i], hullnum); + for (i = 0; i < f->points->numpoints; i++) + AddHullPoint (f->points->points[i], hullnum); // expand all of the planes for (i = 0; i < numbrushfaces; i++) { @@ -619,8 +615,10 @@ ExpandBrush (int hullnum) // add all of the edge bevels for (f = brush_faces; f; f = f->next) - for (i = 0; i < f->numpoints; i++) - AddHullEdge (f->pts[i], f->pts[(i + 1) % f->numpoints], hullnum); + for (i = 0; i < f->points->numpoints; i++) + AddHullEdge (f->points->points[i], + f->points->points[(i + 1) % f->points->numpoints], + hullnum); } /* diff --git a/tools/qfbsp/source/csg4.c b/tools/qfbsp/source/csg4.c index 5b29408c3..ac24a3d9d 100644 --- a/tools/qfbsp/source/csg4.c +++ b/tools/qfbsp/source/csg4.c @@ -73,98 +73,47 @@ NewFaceFromFace (face_t *in) void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back) { - face_t *newf, *new2; - int i, j; - int sides[MAXEDGES + 1]; + int i; int counts[3]; + plane_t plane; vec_t dot; - vec_t dists[MAXEDGES + 1]; - vec_t *p1, *p2; - vec3_t mid; + winding_t *tmp; - if (in->numpoints < 0) + if (in->points->numpoints < 0) Sys_Error ("SplitFace: freed face"); counts[0] = counts[1] = counts[2] = 0; // determine sides for each point - for (i = 0; i < in->numpoints; i++) { - dot = DotProduct (in->pts[i], split->normal); - dot -= split->dist; - dists[i] = dot; + for (i = 0; i < in->points->numpoints; i++) { + dot = DotProduct (in->points->points[i], split->normal) - split->dist; if (dot > ON_EPSILON) - sides[i] = SIDE_FRONT; + counts[SIDE_FRONT]++; else if (dot < -ON_EPSILON) - sides[i] = SIDE_BACK; - else - sides[i] = SIDE_ON; - counts[sides[i]]++; + counts[SIDE_BACK]++; } - sides[i] = sides[0]; - dists[i] = dists[0]; - if (!counts[0]) { + if (!counts[SIDE_FRONT]) { *front = NULL; *back = in; return; } - if (!counts[1]) { + if (!counts[SIDE_BACK]) { *front = in; *back = NULL; return; } - *back = newf = NewFaceFromFace (in); - *front = new2 = NewFaceFromFace (in); + *back = NewFaceFromFace (in); + *front = NewFaceFromFace (in); - // distribute the points and generate splits - for (i = 0; i < in->numpoints; i++) { - if (newf->numpoints > MAXEDGES || new2->numpoints > MAXEDGES) - Sys_Error ("SplitFace: numpoints > MAXEDGES"); + tmp = CopyWinding (in->points); + (*front)->points = ClipWinding (tmp, split, 0); - p1 = in->pts[i]; + plane.dist = -split->dist; + VectorNegate (split->normal, plane.normal); + (*back)->points = ClipWinding (in->points, &plane, 0); - if (sides[i] == SIDE_ON) { - VectorCopy (p1, newf->pts[newf->numpoints]); - newf->numpoints++; - VectorCopy (p1, new2->pts[new2->numpoints]); - new2->numpoints++; - continue; - } - - if (sides[i] == SIDE_FRONT) { - VectorCopy (p1, new2->pts[new2->numpoints]); - new2->numpoints++; - } else { - VectorCopy (p1, newf->pts[newf->numpoints]); - newf->numpoints++; - } - - if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i]) - continue; - - // generate a split point - p2 = in->pts[(i + 1) % in->numpoints]; - - dot = dists[i] / (dists[i] - dists[i + 1]); - for (j = 0; j < 3; j++) { // avoid round off error when possible - if (split->normal[j] == 1) - mid[j] = split->dist; - else if (split->normal[j] == -1) - mid[j] = -split->dist; - else - mid[j] = p1[j] + dot * (p2[j] - p1[j]); - } - - VectorCopy (mid, newf->pts[newf->numpoints]); - newf->numpoints++; - VectorCopy (mid, new2->pts[new2->numpoints]); - new2->numpoints++; - } - - if (newf->numpoints > MAXEDGES || new2->numpoints > MAXEDGES) - Sys_Error ("SplitFace: numpoints > MAXEDGES"); - - // free the original face now that is is represented by the fragments + in->points = 0; // freed by ClipWinding FreeFace (in); } @@ -226,7 +175,7 @@ static void SaveOutside (qboolean mirror) { face_t *f, *next, *newf; - int planenum, i; + int planenum; for (f = outside; f; f = next) { next = f->next; @@ -237,15 +186,11 @@ SaveOutside (qboolean mirror) if (mirror) { newf = NewFaceFromFace (f); - newf->numpoints = f->numpoints; + newf->points = CopyWindingReverse (f->points); newf->planeside = f->planeside ^ 1; // reverse side newf->contents[0] = f->contents[1]; newf->contents[1] = f->contents[0]; - for (i = 0; i < f->numpoints; i++) // add points backwards - { - VectorCopy (f->pts[f->numpoints - 1 - i], newf->pts[i]); - } validfaces[planenum] = MergeFaceToList (newf, validfaces[planenum]); } @@ -331,6 +276,7 @@ CopyFacesToOutside (brush_t *b) brushfaces++; newf = AllocFace (); *newf = *f; + newf->points = CopyWinding (f->points); newf->next = outside; newf->contents[0] = CONTENTS_EMPTY; newf->contents[1] = b->contents; diff --git a/tools/qfbsp/source/map.c b/tools/qfbsp/source/map.c index 6bf077597..dc379fae3 100644 --- a/tools/qfbsp/source/map.c +++ b/tools/qfbsp/source/map.c @@ -502,7 +502,7 @@ ParseBrush (void) tx.vecs[i][3] = vecs[i][3]; } - f = malloc (sizeof (mface_t)); + f = calloc (1, sizeof (mface_t)); f->next = b->faces; b->faces = f; f->plane = plane; diff --git a/tools/qfbsp/source/merge.c b/tools/qfbsp/source/merge.c index d994636ea..29a74c779 100644 --- a/tools/qfbsp/source/merge.c +++ b/tools/qfbsp/source/merge.c @@ -50,8 +50,9 @@ TryMerge (face_t *f1, face_t *f2) vec3_t normal, delta, planenormal; vec_t dot; vec_t *p1, *p2, *p3, *p4, *back; + winding_t *f1p, *f2p, *newfp; - if (f1->numpoints == -1 || f2->numpoints == -1) + if (!(f1p = f1->points) || !(f2p = f2->points)) return NULL; if (f1->planeside != f2->planeside) return NULL; @@ -66,12 +67,12 @@ TryMerge (face_t *f1, face_t *f2) p1 = p2 = NULL; // stop compiler warning j = 0; - for (i = 0; i < f1->numpoints; i++) { - p1 = f1->pts[i]; - p2 = f1->pts[(i + 1) % f1->numpoints]; - for (j = 0; j < f2->numpoints; j++) { - p3 = f2->pts[j]; - p4 = f2->pts[(j + 1) % f2->numpoints]; + for (i = 0; i < f1p->numpoints; i++) { + p1 = f1p->points[i]; + p2 = f1p->points[(i + 1) % f1p->numpoints]; + for (j = 0; j < f2p->numpoints; j++) { + p3 = f2p->points[j]; + p4 = f2p->points[(j + 1) % f2p->numpoints]; for (k = 0; k < 3; k++) { if (fabs (p1[k] - p4[k]) > EQUAL_EPSILON) break; @@ -79,15 +80,11 @@ TryMerge (face_t *f1, face_t *f2) break; } if (k == 3) - break; + goto found_edge; } - if (j < f2->numpoints) - break; } - - if (i == f1->numpoints) - return NULL; // no matching edges - + return NULL; // no matching edges +found_edge: // check slope of connected lines // if the slopes are colinear, the point can be removed plane = &planes[f1->planenum]; @@ -95,24 +92,24 @@ TryMerge (face_t *f1, face_t *f2) if (f1->planeside) VectorNegate (planenormal, planenormal); - back = f1->pts[(i + f1->numpoints - 1) % f1->numpoints]; + back = f1p->points[(i + f1p->numpoints - 1) % f1p->numpoints]; VectorSubtract (p1, back, delta); CrossProduct (planenormal, delta, normal); _VectorNormalize (normal); - back = f2->pts[(j + 2) % f2->numpoints]; + back = f2p->points[(j + 2) % f2p->numpoints]; VectorSubtract (back, p1, delta); dot = DotProduct (delta, normal); if (dot > CONTINUOUS_EPSILON) return NULL; // not a convex polygon keep1 = dot < -CONTINUOUS_EPSILON; - back = f1->pts[(i + 2) % f1->numpoints]; + back = f1p->points[(i + 2) % f1p->numpoints]; VectorSubtract (back, p2, delta); CrossProduct (planenormal, delta, normal); _VectorNormalize (normal); - back = f2->pts[(j + f2->numpoints - 1) % f2->numpoints]; + back = f2p->points[(j + f2p->numpoints - 1) % f2p->numpoints]; VectorSubtract (back, p2, delta); dot = DotProduct (delta, normal); if (dot > CONTINUOUS_EPSILON) @@ -120,28 +117,26 @@ TryMerge (face_t *f1, face_t *f2) keep2 = dot < -CONTINUOUS_EPSILON; // build the new polygon - if (f1->numpoints + f2->numpoints > MAXEDGES) { -// Sys_Error ("TryMerge: too many edges!"); - return NULL; - } + k = f1p->numpoints + f2p->numpoints - 4 + keep1 + keep2; newf = NewFaceFromFace (f1); + newfp = newf->points = NewWinding (k); // copy first polygon - for (k = (i + 1) % f1->numpoints; k != i; k = (k + 1) % f1->numpoints) { - if (k == (i + 1) % f1->numpoints && !keep2) + for (k = (i + 1) % f1p->numpoints; k != i; k = (k + 1) % f1p->numpoints) { + if (k == (i + 1) % f1p->numpoints && !keep2) continue; - VectorCopy (f1->pts[k], newf->pts[newf->numpoints]); - newf->numpoints++; + VectorCopy (f1p->points[k], newfp->points[newfp->numpoints]); + newfp->numpoints++; } // copy second polygon - for (l = (j + 1) % f2->numpoints; l != j; l = (l + 1) % f2->numpoints) { - if (l == (j + 1) % f2->numpoints && !keep1) + for (l = (j + 1) % f2p->numpoints; l != j; l = (l + 1) % f2p->numpoints) { + if (l == (j + 1) % f2p->numpoints && !keep1) continue; - VectorCopy (f2->pts[l], newf->pts[newf->numpoints]); - newf->numpoints++; + VectorCopy (f2p->points[l], newfp->points[newfp->numpoints]); + newfp->numpoints++; } return newf; @@ -165,7 +160,8 @@ MergeFaceToList (face_t *face, face_t *list) if (!newf) continue; FreeFace (face); - f->numpoints = -1; // merged out + FreeWinding (f->points); // merged out + f->points = 0; return MergeFaceToList (newf, list); } @@ -182,7 +178,7 @@ FreeMergeListScraps (face_t *merged) head = NULL; for (; merged; merged = next) { next = merged->next; - if (merged->numpoints == -1) + if (!merged->points) FreeFace (merged); else { merged->next = head; diff --git a/tools/qfbsp/source/outside.c b/tools/qfbsp/source/outside.c index 62447fea9..23ea0c1fa 100644 --- a/tools/qfbsp/source/outside.c +++ b/tools/qfbsp/source/outside.c @@ -203,7 +203,8 @@ ClearOutFaces (node_t *node) for (fp = node->markfaces; *fp; fp++) { // mark all the original faces that are removed - (*fp)->numpoints = 0; + FreeWinding ((*fp)->points); + (*fp)->points = 0; } node->faces = NULL; } diff --git a/tools/qfbsp/source/qfbsp.c b/tools/qfbsp/source/qfbsp.c index 72ddd097e..0c254da72 100644 --- a/tools/qfbsp/source/qfbsp.c +++ b/tools/qfbsp/source/qfbsp.c @@ -141,6 +141,22 @@ CopyWinding (winding_t *w) return c; } +winding_t * +CopyWindingReverse (winding_t *w) +{ + int i, size; + winding_t *c; + + size = (long) ((winding_t *) 0)->points[w->numpoints]; + c = malloc (size); + c->numpoints = w->numpoints; + for (i = 0; i < w->numpoints; i++) { + // add points backwards + VectorCopy (w->points[w->numpoints - 1 - i], c->points[i]); + } + return c; +} + void CheckWinding (winding_t * w) { @@ -355,7 +371,7 @@ NewWinding (int points) int size; winding_t *w; - if (points > MAX_POINTS_ON_WINDING) + if (points < 3 || points > MAX_POINTS_ON_WINDING) Sys_Error ("NewWinding: %i points", points); c_activewindings++; diff --git a/tools/qfbsp/source/region.c b/tools/qfbsp/source/region.c index 80b9a3670..90060e780 100644 --- a/tools/qfbsp/source/region.c +++ b/tools/qfbsp/source/region.c @@ -74,8 +74,8 @@ AddFaceToRegionSize (face_t *f) { int i; - for (i = 0; i < f->numpoints; i++) - AddPointToRegion (f->pts[i]); + for (i = 0; i < f->points->numpoints; i++) + AddPointToRegion (f->points->points[i]); } static qboolean @@ -107,7 +107,7 @@ CanJoinFaces (face_t *f, face_t *f2) } } } else { - if (bsp->numsurfedges - firstedge + f2->numpoints + if (bsp->numsurfedges - firstedge + f2->points->numpoints > MAX_EDGES_IN_REGION) return false; // a huge water or sky polygon } @@ -130,7 +130,7 @@ RecursiveGrowRegion (dface_t *r, face_t *f) f->outputnumber = bsp->numfaces; // add edges - for (i = 0; i < f->numpoints; i++) { + for (i = 0; i < f->points->numpoints; i++) { e = f->edges[i]; if (!edgefaces[abs (e)][0]) continue; // edge has allready been removed @@ -225,7 +225,7 @@ GrowNodeRegion_r (node_t * node) RecursiveGrowRegion (r, f); #endif r.firstedge = firstedge = bsp->numsurfedges; - for (i = 0; i < f->numpoints; i++) { + for (i = 0; i < f->points->numpoints; i++) { if (bsp->numsurfedges == MAX_MAP_SURFEDGES) Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES"); BSP_AddSurfEdge (bsp, f->edges[i]); diff --git a/tools/qfbsp/source/solidbsp.c b/tools/qfbsp/source/solidbsp.c index a107d42bb..b45c6ce33 100644 --- a/tools/qfbsp/source/solidbsp.c +++ b/tools/qfbsp/source/solidbsp.c @@ -53,12 +53,13 @@ FaceSide (face_t *in, plane_t *split) int frontcount, backcount, i; vec_t dot; vec_t *p; + winding_t *inp = in->points; frontcount = backcount = 0; // axial planes are fast if (split->type < 3) - for (i = 0, p = in->pts[0] + split->type; i < in->numpoints; + for (i = 0, p = inp->points[0] + split->type; i < inp->numpoints; i++, p += 3) { if (*p > split->dist + ON_EPSILON) { if (backcount) @@ -71,7 +72,7 @@ FaceSide (face_t *in, plane_t *split) } } else // sloping planes take longer - for (i = 0, p = in->pts[0]; i < in->numpoints; i++, p += 3) { + for (i = 0, p = inp->points[0]; i < inp->numpoints; i++, p += 3) { dot = DotProduct (p, split->normal); dot -= split->dist; if (dot > ON_EPSILON) { @@ -334,14 +335,15 @@ CalcSurfaceInfo (surface_t * surf) } for (f = surf->faces; f; f = f->next) { + winding_t *fp = f->points; if (f->contents[0] >= 0 || f->contents[1] >= 0) Sys_Error ("Bad contents"); - for (i = 0; i < f->numpoints; i++) + for (i = 0; i < fp->numpoints; i++) for (j = 0; j < 3; j++) { - if (f->pts[i][j] < surf->mins[j]) - surf->mins[j] = f->pts[i][j]; - if (f->pts[i][j] > surf->maxs[j]) - surf->maxs[j] = f->pts[i][j]; + if (fp->points[i][j] < surf->mins[j]) + surf->mins[j] = fp->points[i][j]; + if (fp->points[i][j] > surf->maxs[j]) + surf->maxs[j] = fp->points[i][j]; } } } @@ -583,6 +585,7 @@ LinkNodeFaces (surface_t *surface) nodefaces++; new = AllocFace (); *new = *f; + new->points = CopyWinding (f->points); f->original = new; new->next = list; list = new; diff --git a/tools/qfbsp/source/surfaces.c b/tools/qfbsp/source/surfaces.c index 85d9856f0..18742565c 100644 --- a/tools/qfbsp/source/surfaces.c +++ b/tools/qfbsp/source/surfaces.c @@ -75,8 +75,8 @@ SubdivideFace (face_t *f, face_t **prevptr) mins = BOGUS_RANGE; maxs = -BOGUS_RANGE; - for (i = 0; i < f->numpoints; i++) { - v = DotProduct (f->pts[i], tex->vecs[axis]); + for (i = 0; i < f->points->numpoints; i++) { + v = DotProduct (f->points->points[i], tex->vecs[axis]); if (v < mins) mins = v; if (v > maxs) @@ -146,7 +146,7 @@ GatherNodeFaces_r (node_t *node) // decision node for (f = node->faces; f; f = next) { next = f->next; - if (!f->numpoints) { // face was removed outside + if (!f->points) { // face was removed outside FreeFace (f); } else { f->next = validfaces[f->planenum]; @@ -349,14 +349,15 @@ static void FindFaceEdges (face_t *face) { int i; + winding_t *facep = face->points; face->outputnumber = -1; - if (face->numpoints > MAXEDGES) - Sys_Error ("WriteFace: %i points", face->numpoints); + face->edges = malloc (sizeof (int) * facep->numpoints); - for (i = 0; i < face->numpoints; i++) - face->edges[i] = GetEdge - (face->pts[i], face->pts[(i + 1) % face->numpoints], face); + for (i = 0; i < facep->numpoints; i++) + face->edges[i] = GetEdge (facep->points[i], + facep->points[(i + 1) % facep->numpoints], + face); } static void diff --git a/tools/qfbsp/source/tjunc.c b/tools/qfbsp/source/tjunc.c index 80082048a..5636f391d 100644 --- a/tools/qfbsp/source/tjunc.c +++ b/tools/qfbsp/source/tjunc.c @@ -30,6 +30,8 @@ static __attribute__ ((unused)) const char rcsid[] = #include "QF/sys.h" +#include "compat.h" + #include "bsp5.h" #include "options.h" @@ -236,118 +238,28 @@ AddFaceEdges (face_t *f) { int i, j; - for (i = 0; i < f->numpoints; i++) { - j = (i + 1) % f->numpoints; - AddEdge (f->pts[i], f->pts[j]); + for (i = 0; i < f->points->numpoints; i++) { + j = (i + 1) % f->points->numpoints; + AddEdge (f->points->points[i], f->points->points[j]); } } -// a specially allocated face that can hold hundreds of edges if needed -byte superfacebuf[8192]; -face_t *superface = (face_t *) superfacebuf; - -void FixFaceEdges (face_t * f); - face_t *newlist; static void -SplitFaceForTjunc (face_t *f, face_t *original) -{ - face_t *new, *chain; - int firstcorner, lastcorner, i; - vec3_t dir, test; - vec_t v; - - chain = NULL; - do { - if (f->numpoints <= MAXPOINTS) { - // the face is now small enough without more cutting so copy it - // back to the original - *original = *f; - original->original = chain; - original->next = newlist; - newlist = original; - return; - } - - tjuncfaces++; - - restart: - // find the last corner - VectorSubtract (f->pts[f->numpoints - 1], f->pts[0], dir); - _VectorNormalize (dir); - for (lastcorner = f->numpoints - 1; lastcorner > 0; lastcorner--) { - VectorSubtract (f->pts[lastcorner - 1], f->pts[lastcorner], test); - _VectorNormalize (test); - v = DotProduct (test, dir); - if (v < 0.9999 || v > 1.00001) - break; - } - - // find the first corner - VectorSubtract (f->pts[1], f->pts[0], dir); - _VectorNormalize (dir); - for (firstcorner = 1; firstcorner < f->numpoints - 1; firstcorner++) { - VectorSubtract (f->pts[firstcorner + 1], f->pts[firstcorner], - test); - _VectorNormalize (test); - v = DotProduct (test, dir); - if (v < 0.9999 || v > 1.00001) - break; - } - - if (firstcorner + 2 >= MAXPOINTS) { - // rotate the point winding - VectorCopy (f->pts[0], test); - for (i = 1; i < f->numpoints; i++) - VectorCopy (f->pts[i], f->pts[i - 1]); - VectorCopy (test, f->pts[f->numpoints - 1]); - goto restart; - } - - // cut off as big a piece as possible, less than MAXPOINTS, and not - // past lastcorner - - new = NewFaceFromFace (f); - if (f->original) - Sys_Error ("SplitFaceForTjunc: f->original"); - - new->original = chain; - chain = new; - new->next = newlist; - newlist = new; - if (f->numpoints - firstcorner <= MAXPOINTS) - new->numpoints = firstcorner + 2; - else if (lastcorner + 2 < MAXPOINTS && - f->numpoints - lastcorner <= MAXPOINTS) - new->numpoints = lastcorner + 2; - else - new->numpoints = MAXPOINTS; - - for (i = 0; i < new->numpoints; i++) - VectorCopy (f->pts[i], new->pts[i]); - for (i = new->numpoints - 1; i < f->numpoints; i++) - VectorCopy (f->pts[i], f->pts[i - (new->numpoints - 2)]); - f->numpoints -= (new->numpoints - 2); - } while (1); - -} - -void FixFaceEdges (face_t *f) { int i, j, k; vec_t t1, t2; wedge_t *w; + winding_t *fp = f->points; wvert_t *v; - *superface = *f; - restart: - for (i = 0; i < superface->numpoints; i++) { - j = (i + 1) % superface->numpoints; + for (i = 0; i < fp->numpoints; i++) { + j = (i + 1) % fp->numpoints; - w = FindEdge (superface->pts[i], superface->pts[j], &t1, &t2); + w = FindEdge (fp->points[i], fp->points[j], &t1, &t2); for (v = w->head.next; v->t < t1 + T_EPSILON; v = v->next) { } @@ -355,25 +267,20 @@ FixFaceEdges (face_t *f) if (v->t < t2 - T_EPSILON) { tjuncs++; // insert a new vertex here - for (k = superface->numpoints; k > j; k--) { - VectorCopy (superface->pts[k - 1], superface->pts[k]); + fp = realloc (fp, field_offset (winding_t, + points[fp->numpoints + 1])); + for (k = fp->numpoints; k > j; k--) { + VectorCopy (fp->points[k - 1], fp->points[k]); } - VectorMultAdd (w->origin, v->t, w->dir, superface->pts[j]); - superface->numpoints++; + VectorMultAdd (w->origin, v->t, w->dir, fp->points[j]); + fp->numpoints++; goto restart; } } + f->points = fp; - - if (superface->numpoints <= MAXPOINTS) { - *f = *superface; - f->next = newlist; - newlist = f; - return; - } - // the face needs to be split into multiple faces because of too many edges - - SplitFaceForTjunc (superface, f); + f->next = newlist; + newlist = f; } //============================================================================