mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-20 01:11:18 +00:00
MAXEDGES? What MAXEDGES? :)
This commit is contained in:
parent
89586e0181
commit
ca91f7b727
11 changed files with 139 additions and 271 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
Loading…
Reference in a new issue