enough whitespace to crush a shambler

This commit is contained in:
Bill Currie 2002-09-19 17:14:23 +00:00
parent afa0b21336
commit 4d520d588d
13 changed files with 2351 additions and 2552 deletions

File diff suppressed because it is too large Load diff

View file

@ -35,17 +35,18 @@ Brushes that touch still need to be split at the cut point to make a tjunction
*/
face_t *validfaces[MAX_MAP_PLANES];
face_t *validfaces[MAX_MAP_PLANES];
face_t *inside, *outside;
int brushfaces;
int csgfaces;
int csgmergefaces;
face_t *inside, *outside;
int brushfaces;
int csgfaces;
int csgmergefaces;
void DrawList (face_t *list)
void
DrawList (face_t * list)
{
for ( ; list ; list=list->next)
for (; list; list = list->next)
Draw_DrawFace (list);
}
@ -58,19 +59,20 @@ Duplicates the non point information of a face, used by SplitFace and
MergeFace.
==================
*/
face_t *NewFaceFromFace (face_t *in)
face_t *
NewFaceFromFace (face_t * in)
{
face_t *newf;
face_t *newf;
newf = AllocFace ();
newf->planenum = in->planenum;
newf->texturenum = in->texturenum;
newf->texturenum = in->texturenum;
newf->planeside = in->planeside;
newf->original = in->original;
newf->contents[0] = in->contents[0];
newf->contents[1] = in->contents[1];
return newf;
}
@ -81,24 +83,24 @@ SplitFace
==================
*/
void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
void
SplitFace (face_t * in, plane_t *split, face_t ** front, face_t ** back)
{
vec_t dists[MAXEDGES+1];
int sides[MAXEDGES+1];
int counts[3];
vec_t dot;
int i, j;
face_t *newf, *new2;
vec_t *p1, *p2;
vec3_t mid;
vec_t dists[MAXEDGES + 1];
int sides[MAXEDGES + 1];
int counts[3];
vec_t dot;
int i, j;
face_t *newf, *new2;
vec_t *p1, *p2;
vec3_t mid;
if (in->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++)
{
for (i = 0; i < in->numpoints; i++) {
dot = DotProduct (in->pts[i], split->normal);
dot -= split->dist;
dists[i] = dot;
@ -112,69 +114,62 @@ void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
}
sides[i] = sides[0];
dists[i] = dists[0];
if (!counts[0])
{
if (!counts[0]) {
*front = NULL;
*back = in;
return;
}
if (!counts[1])
{
if (!counts[1]) {
*front = in;
*back = NULL;
return;
}
*back = newf = NewFaceFromFace (in);
*front = new2 = NewFaceFromFace (in);
// distribute the points and generate splits
for (i=0 ; i<in->numpoints ; i++)
{
for (i = 0; i < in->numpoints; i++) {
if (newf->numpoints > MAXEDGES || new2->numpoints > MAXEDGES)
Sys_Error ("SplitFace: numpoints > MAXEDGES");
p1 = in->pts[i];
if (sides[i] == SIDE_ON)
{
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)
{
if (sides[i] == SIDE_FRONT) {
VectorCopy (p1, new2->pts[new2->numpoints]);
new2->numpoints++;
}
else
{
} else {
VectorCopy (p1, newf->pts[newf->numpoints]);
newf->numpoints++;
}
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
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
// 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]);
mid[j] = p1[j] + dot * (p2[j] - p1[j]);
}
VectorCopy (mid, newf->pts[newf->numpoints]);
newf->numpoints++;
VectorCopy (mid, new2->pts[new2->numpoints]);
@ -184,9 +179,9 @@ void SplitFace (face_t *in, plane_t *split, face_t **front, face_t **back)
if (newf->numpoints > MAXEDGES || new2->numpoints > MAXEDGES)
Sys_Error ("SplitFace: numpoints > MAXEDGES");
#if 0
CheckFace (newf);
CheckFace (new2);
#if 0
CheckFace (newf);
CheckFace (new2);
#endif
// free the original face now that is is represented by the fragments
@ -205,50 +200,44 @@ Faces exactly on the plane will stay inside unless overdrawn by later brush
frontside is the side of the plane that holds the outside list
=================
*/
void ClipInside (int splitplane, int frontside, qboolean precedence)
void
ClipInside (int splitplane, int frontside, qboolean precedence)
{
face_t *f, *next;
face_t *frags[2];
face_t *insidelist;
plane_t *split;
face_t *f, *next;
face_t *frags[2];
face_t *insidelist;
plane_t *split;
split = &planes[splitplane];
insidelist = NULL;
for (f=inside ; f ; f=next)
{
for (f = inside; f; f = next) {
next = f->next;
if (f->planenum == splitplane)
{ // exactly on, handle special
if ( frontside != f->planeside || precedence )
{ // allways clip off opposite faceing
if (f->planenum == splitplane) { // exactly on, handle special
if (frontside != f->planeside || precedence) { // allways clip
// off opposite
// faceing
frags[frontside] = NULL;
frags[!frontside] = f;
}
else
{ // leave it on the outside
} else { // leave it on the outside
frags[frontside] = f;
frags[!frontside] = NULL;
}
}
else
{ // proper split
} else { // proper split
SplitFace (f, split, &frags[0], &frags[1]);
}
if (frags[frontside])
{
if (frags[frontside]) {
frags[frontside]->next = outside;
outside = frags[frontside];
}
if (frags[!frontside])
{
if (frags[!frontside]) {
frags[!frontside]->next = insidelist;
insidelist = frags[!frontside];
}
}
inside = insidelist;
}
@ -260,39 +249,37 @@ SaveOutside
Saves all of the faces in the outside list to the bsp plane list
==================
*/
void SaveOutside (qboolean mirror)
void
SaveOutside (qboolean mirror)
{
face_t *f , *next, *newf;
int i;
int planenum;
for (f=outside ; f ; f=next)
{
face_t *f, *next, *newf;
int i;
int planenum;
for (f = outside; f; f = next) {
next = f->next;
csgfaces++;
Draw_DrawFace (f);
planenum = f->planenum;
if (mirror)
{
if (mirror) {
newf = NewFaceFromFace (f);
newf->numpoints = f->numpoints;
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
for (i = 0; i < f->numpoints; i++) // add points backwards
{
VectorCopy (f->pts[f->numpoints-1-i], newf->pts[i]);
VectorCopy (f->pts[f->numpoints - 1 - i], newf->pts[i]);
}
}
else
} else
newf = NULL;
validfaces[planenum] = MergeFaceToList(f, validfaces[planenum]);
validfaces[planenum] = MergeFaceToList (f, validfaces[planenum]);
if (newf)
validfaces[planenum] = MergeFaceToList(newf, validfaces[planenum]);
validfaces[planenum] = MergeFaceToList (newf, validfaces[planenum]);
validfaces[planenum] = FreeMergeListScraps (validfaces[planenum]);
}
@ -305,21 +292,19 @@ FreeInside
Free all the faces that got clipped out
==================
*/
void FreeInside (int contents)
void
FreeInside (int contents)
{
face_t *f, *next;
for (f=inside ; f ; f=next)
{
face_t *f, *next;
for (f = inside; f; f = next) {
next = f->next;
if (contents != CONTENTS_SOLID)
{
if (contents != CONTENTS_SOLID) {
f->contents[0] = contents;
f->next = outside;
outside = f;
}
else
} else
FreeFace (f);
}
}
@ -335,21 +320,21 @@ Returns a chain of all the external surfaces with one or more visible
faces.
==================
*/
surface_t *BuildSurfaces (void)
surface_t *
BuildSurfaces (void)
{
face_t **f;
face_t *count;
int i;
surface_t *s;
surface_t *surfhead;
face_t **f;
face_t *count;
int i;
surface_t *s;
surface_t *surfhead;
surfhead = NULL;
f = validfaces;
for (i=0 ; i<numbrushplanes ; i++, f++)
{
for (i = 0; i < numbrushplanes; i++, f++) {
if (!*f)
continue; // nothing left on this plane
continue; // nothing left on this plane
// create a new surface to hold the faces on this plane
s = AllocSurface ();
@ -357,11 +342,11 @@ surface_t *BuildSurfaces (void)
s->next = surfhead;
surfhead = s;
s->faces = *f;
for (count = s->faces ; count ; count=count->next)
for (count = s->faces; count; count = count->next)
csgmergefaces++;
CalcSurfaceInfo (s); // bounding box and flags
}
CalcSurfaceInfo (s); // bounding box and flags
}
return surfhead;
}
@ -372,23 +357,24 @@ surface_t *BuildSurfaces (void)
CopyFacesToOutside
==================
*/
void CopyFacesToOutside (brush_t *b)
void
CopyFacesToOutside (brush_t * b)
{
face_t *f, *newf;
face_t *f, *newf;
outside = NULL;
for (f=b->faces ; f ; f=f->next)
{
for (f = b->faces; f; f = f->next) {
brushfaces++;
#if 0
{
int i;
for (i=0 ; i<f->numpoints ; i++)
printf ("(%f,%f,%f) ",f->pts[i][0], f->pts[i][1], f->pts[i][2]);
printf ("\n");
}
{
int i;
for (i = 0; i < f->numpoints; i++)
printf ("(%f,%f,%f) ", f->pts[i][0], f->pts[i][1],
f->pts[i][2]);
printf ("\n");
}
#endif
newf = AllocFace ();
*newf = *f;
@ -407,67 +393,64 @@ CSGFaces
Returns a list of surfaces containing aall of the faces
==================
*/
surface_t *CSGFaces (brushset_t *bs)
surface_t *
CSGFaces (brushset_t * bs)
{
brush_t *b1, *b2;
int i;
qboolean overwrite;
face_t *f;
surface_t *surfhead;
brush_t *b1, *b2;
int i;
qboolean overwrite;
face_t *f;
surface_t *surfhead;
qprintf ("---- CSGFaces ----\n");
memset (validfaces, 0, sizeof(validfaces));
memset (validfaces, 0, sizeof (validfaces));
csgfaces = brushfaces = csgmergefaces = 0;
Draw_ClearWindow ();
//
// do the solid faces
//
for (b1=bs->brushes ; b1 ; b1 = b1->next)
{
// set outside to a copy of the brush's faces
for (b1 = bs->brushes; b1; b1 = b1->next) {
// set outside to a copy of the brush's faces
CopyFacesToOutside (b1);
overwrite = false;
for (b2=bs->brushes ; b2 ; b2 = b2->next)
{
// see if b2 needs to clip a chunk out of b1
if (b1==b2)
{
overwrite = true; // later brushes now overwrite
for (b2 = bs->brushes; b2; b2 = b2->next) {
// see if b2 needs to clip a chunk out of b1
if (b1 == b2) {
overwrite = true; // later brushes now overwrite
continue;
}
// check bounding box first
for (i=0 ; i<3 ; i++)
// check bounding box first
for (i = 0; i < 3; i++)
if (b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i])
break;
if (i<3)
if (i < 3)
continue;
// divide faces by the planes of the new brush
// divide faces by the planes of the new brush
inside = outside;
outside = NULL;
for (f=b2->faces ; f ; f=f->next)
for (f = b2->faces; f; f = f->next)
ClipInside (f->planenum, f->planeside, overwrite);
// these faces are continued in another brush, so get rid of them
if (b1->contents == CONTENTS_SOLID && b2->contents <= CONTENTS_WATER)
FreeInside (b2->contents);
// these faces are continued in another brush, so get rid of them
if (b1->contents == CONTENTS_SOLID
&& b2->contents <= CONTENTS_WATER) FreeInside (b2->contents);
else
FreeInside (CONTENTS_SOLID);
}
// all of the faces left in outside are real surface faces
// all of the faces left in outside are real surface faces
if (b1->contents != CONTENTS_SOLID)
SaveOutside (true); // mirror faces for inside view
SaveOutside (true); // mirror faces for inside view
else
SaveOutside (false);
}
@ -478,12 +461,10 @@ surface_t *CSGFaces (brushset_t *bs)
#endif
surfhead = BuildSurfaces ();
qprintf ("%5i brushfaces\n", brushfaces);
qprintf ("%5i csgfaces\n", csgfaces);
qprintf ("%5i mergedfaces\n", csgmergefaces);
return surfhead;
}

View file

@ -35,14 +35,14 @@
#include "bsp5.h"
int nummapbrushes;
mbrush_t mapbrushes[MAX_MAP_BRUSHES];
int nummapbrushes;
mbrush_t mapbrushes[MAX_MAP_BRUSHES];
int num_entities;
entity_t entities[MAX_MAP_ENTITIES];
int num_entities;
entity_t entities[MAX_MAP_ENTITIES];
int nummiptex;
char miptex[MAX_MAP_TEXINFO][16];
int nummiptex;
char miptex[MAX_MAP_TEXINFO][16];
//============================================================================
@ -52,12 +52,12 @@ FindMiptex
===============
*/
int FindMiptex (char *name)
int
FindMiptex (char *name)
{
int i;
for (i=0 ; i<nummiptex ; i++)
{
int i;
for (i = 0; i < nummiptex; i++) {
if (!strcmp (name, miptex[i]))
return i;
}
@ -75,34 +75,33 @@ FindTexinfo
Returns a global texinfo number
===============
*/
int FindTexinfo (texinfo_t *t)
int
FindTexinfo (texinfo_t *t)
{
int i, j;
texinfo_t *tex;
int i, j;
texinfo_t *tex;
// set the special flag
if (miptex[t->miptex][0] == '*'
|| !strncasecmp (miptex[t->miptex], "sky",3) )
t->flags |= TEX_SPECIAL;
if (miptex[t->miptex][0] == '*'
|| !strncasecmp (miptex[t->miptex], "sky", 3)) t->flags |= TEX_SPECIAL;
tex = bsp->texinfo;
for (i=0 ; i<bsp->numtexinfo;i++, tex++)
{
tex = bsp->texinfo;
for (i = 0; i < bsp->numtexinfo; i++, tex++) {
if (t->miptex != tex->miptex)
continue;
if (t->flags != tex->flags)
continue;
for (j=0 ; j<8 ; j++)
for (j = 0; j < 8; j++)
if (t->vecs[0][j] != tex->vecs[0][j])
break;
if (j != 8)
continue;
return i;
}
// allocate a new texture
if (bsp->numtexinfo == MAX_MAP_TEXINFO)
Sys_Error ("numtexinfo == MAX_MAP_TEXINFO");
@ -117,41 +116,40 @@ int FindTexinfo (texinfo_t *t)
#define MAXTOKEN 128
char token[MAXTOKEN];
qboolean unget;
char *script_p;
int scriptline;
char token[MAXTOKEN];
qboolean unget;
char *script_p;
int scriptline;
void StartTokenParsing (char *data)
void
StartTokenParsing (char *data)
{
scriptline = 1;
script_p = data;
unget = false;
}
qboolean GetToken (qboolean crossline)
qboolean
GetToken (qboolean crossline)
{
char *token_p;
char *token_p;
if (unget) // is a token allready waiting?
if (unget) // is a token allready waiting?
return true;
//
// skip space
//
skipspace:
while (*script_p <= 32)
{
if (!*script_p)
{
skipspace:
while (*script_p <= 32) {
if (!*script_p) {
if (!crossline)
Sys_Error ("Line %i is incomplete",scriptline);
Sys_Error ("Line %i is incomplete", scriptline);
return false;
}
if (*script_p++ == '\n')
{
if (*script_p++ == '\n') {
if (!crossline)
Sys_Error ("Line %i is incomplete",scriptline);
Sys_Error ("Line %i is incomplete", scriptline);
scriptline++;
}
}
@ -159,48 +157,44 @@ skipspace:
if (script_p[0] == '/' && script_p[1] == '/') // comment field
{
if (!crossline)
Sys_Error ("Line %i is incomplete\n",scriptline);
Sys_Error ("Line %i is incomplete\n", scriptline);
while (*script_p++ != '\n')
if (!*script_p)
{
if (!*script_p) {
if (!crossline)
Sys_Error ("Line %i is incomplete",scriptline);
Sys_Error ("Line %i is incomplete", scriptline);
return false;
}
goto skipspace;
}
//
// copy token
//
token_p = token;
if (*script_p == '"')
{
if (*script_p == '"') {
script_p++;
while ( *script_p != '"' )
{
while (*script_p != '"') {
if (!*script_p)
Sys_Error ("EOF inside quoted token");
*token_p++ = *script_p++;
if (token_p > &token[MAXTOKEN-1])
Sys_Error ("Token too large on line %i",scriptline);
if (token_p > &token[MAXTOKEN - 1])
Sys_Error ("Token too large on line %i", scriptline);
}
script_p++;
}
else while ( *script_p > 32 )
{
*token_p++ = *script_p++;
if (token_p > &token[MAXTOKEN-1])
Sys_Error ("Token too large on line %i",scriptline);
}
} else
while (*script_p > 32) {
*token_p++ = *script_p++;
if (token_p > &token[MAXTOKEN - 1])
Sys_Error ("Token too large on line %i", scriptline);
}
*token_p = 0;
return true;
}
void UngetToken ()
void
UngetToken ()
{
unget = true;
}
@ -208,27 +202,28 @@ void UngetToken ()
//============================================================================
entity_t *mapent;
entity_t *mapent;
/*
=================
ParseEpair
=================
*/
void ParseEpair (void)
void
ParseEpair (void)
{
epair_t *e;
e = malloc (sizeof(epair_t));
memset (e, 0, sizeof(epair_t));
epair_t *e;
e = malloc (sizeof (epair_t));
memset (e, 0, sizeof (epair_t));
e->next = mapent->epairs;
mapent->epairs = e;
if (strlen(token) >= MAX_KEY-1)
if (strlen (token) >= MAX_KEY - 1)
Sys_Error ("ParseEpar: token too long");
e->key = strdup (token);
GetToken (false);
if (strlen(token) >= MAX_VALUE-1)
if (strlen (token) >= MAX_VALUE - 1)
Sys_Error ("ParseEpar: token too long");
e->value = strdup (token);
}
@ -241,37 +236,35 @@ void ParseEpair (void)
textureAxisFromPlane
==================
*/
vec3_t baseaxis[18] =
{
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
vec3_t baseaxis[18] = {
{0, 0, 1}, {1, 0, 0}, {0, -1, 0}, // floor
{0, 0, -1}, {1, 0, 0}, {0, -1, 0}, // ceiling
{1, 0, 0}, {0, 1, 0}, {0, 0, -1}, // west wall
{-1, 0, 0}, {0, 1, 0}, {0, 0, -1}, // east wall
{0, 1, 0}, {1, 0, 0}, {0, 0, -1}, // south wall
{0, -1, 0}, {1, 0, 0}, {0, 0, -1} // north wall
};
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
void
TextureAxisFromPlane (plane_t *pln, vec3_t xv, vec3_t yv)
{
int bestaxis;
float dot,best;
int i;
int bestaxis;
float dot, best;
int i;
best = 0;
bestaxis = 0;
for (i=0 ; i<6 ; i++)
{
dot = DotProduct (pln->normal, baseaxis[i*3]);
if (dot > best)
{
for (i = 0; i < 6; i++) {
dot = DotProduct (pln->normal, baseaxis[i * 3]);
if (dot > best) {
best = dot;
bestaxis = i;
}
}
VectorCopy (baseaxis[bestaxis*3+1], xv);
VectorCopy (baseaxis[bestaxis*3+2], yv);
VectorCopy (baseaxis[bestaxis * 3 + 1], xv);
VectorCopy (baseaxis[bestaxis * 3 + 2], yv);
}
@ -283,98 +276,91 @@ void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
ParseBrush
=================
*/
void ParseBrush (void)
void
ParseBrush (void)
{
mbrush_t *b;
mface_t *f, *f2;
vec3_t planepts[3];
vec3_t t1, t2, t3;
int i,j;
texinfo_t tx;
vec_t d;
float shift[2], rotate, scale[2];
mbrush_t *b;
mface_t *f, *f2;
vec3_t planepts[3];
vec3_t t1, t2, t3;
int i, j;
texinfo_t tx;
vec_t d;
float shift[2], rotate, scale[2];
b = &mapbrushes[nummapbrushes];
nummapbrushes++;
b->next = mapent->brushes;
mapent->brushes = b;
do
{
do {
if (!GetToken (true))
break;
if (!strcmp (token, "}") )
if (!strcmp (token, "}"))
break;
// read the three point plane definition
for (i=0 ; i<3 ; i++)
{
// read the three point plane definition
for (i = 0; i < 3; i++) {
if (i != 0)
GetToken (true);
if (strcmp (token, "(") )
if (strcmp (token, "("))
Sys_Error ("parsing brush");
for (j=0 ; j<3 ; j++)
{
for (j = 0; j < 3; j++) {
GetToken (false);
planepts[i][j] = atoi(token);
planepts[i][j] = atoi (token);
}
GetToken (false);
if (strcmp (token, ")") )
if (strcmp (token, ")"))
Sys_Error ("parsing brush");
}
// read the texturedef
memset (&tx, 0, sizeof(tx));
// read the texturedef
memset (&tx, 0, sizeof (tx));
GetToken (false);
tx.miptex = FindMiptex (token);
GetToken (false);
shift[0] = atoi(token);
shift[0] = atoi (token);
GetToken (false);
shift[1] = atoi(token);
shift[1] = atoi (token);
GetToken (false);
rotate = atoi(token);
rotate = atoi (token);
GetToken (false);
scale[0] = atof(token);
scale[0] = atof (token);
GetToken (false);
scale[1] = atof(token);
scale[1] = atof (token);
// if the three points are all on a previous plane, it is a
// duplicate plane
for (f2 = b->faces ; f2 ; f2=f2->next)
{
for (i=0 ; i<3 ; i++)
{
d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
for (f2 = b->faces; f2; f2 = f2->next) {
for (i = 0; i < 3; i++) {
d = DotProduct (planepts[i], f2->plane.normal) - f2->plane.dist;
if (d < -ON_EPSILON || d > ON_EPSILON)
break;
}
if (i==3)
if (i == 3)
break;
}
if (f2)
{
if (f2) {
printf ("WARNING: brush with duplicate plane\n");
continue;
}
f = malloc(sizeof(mface_t));
f = malloc (sizeof (mface_t));
f->next = b->faces;
b->faces = f;
// convert to a vector / dist plane
for (j=0 ; j<3 ; j++)
{
// convert to a vector / dist plane
for (j = 0; j < 3; j++) {
t1[j] = planepts[0][j] - planepts[1][j];
t2[j] = planepts[2][j] - planepts[1][j];
t3[j] = planepts[1][j];
}
CrossProduct(t1,t2, f->plane.normal);
if (VectorCompare (f->plane.normal, vec3_origin))
{
CrossProduct (t1, t2, f->plane.normal);
if (VectorCompare (f->plane.normal, vec3_origin)) {
printf ("WARNING: brush plane with no normal\n");
b->faces = f->next;
free (f);
@ -383,71 +369,73 @@ void ParseBrush (void)
VectorNormalize (f->plane.normal);
f->plane.dist = DotProduct (t3, f->plane.normal);
//
// fake proper texture vectors from QuakeEd style
//
//
// fake proper texture vectors from QuakeEd style
//
{
vec3_t vecs[2];
int sv, tv;
float ang, sinv, cosv;
float ns, nt;
TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);
vec3_t vecs[2];
int sv, tv;
float ang, sinv, cosv;
float ns, nt;
TextureAxisFromPlane (&f->plane, vecs[0], vecs[1]);
if (!scale[0])
scale[0] = 1;
if (!scale[1])
scale[1] = 1;
// rotate axis
if (rotate == 0)
{ sinv = 0 ; cosv = 1; }
else if (rotate == 90)
{ sinv = 1 ; cosv = 0; }
else if (rotate == 180)
{ sinv = 0 ; cosv = -1; }
else if (rotate == 270)
{ sinv = -1 ; cosv = 0; }
else
{
// rotate axis
if (rotate == 0) {
sinv = 0;
cosv = 1;
} else if (rotate == 90) {
sinv = 1;
cosv = 0;
} else if (rotate == 180) {
sinv = 0;
cosv = -1;
} else if (rotate == 270) {
sinv = -1;
cosv = 0;
} else {
ang = rotate / 180 * M_PI;
sinv = sin(ang);
cosv = cos(ang);
sinv = sin (ang);
cosv = cos (ang);
}
if (vecs[0][0])
sv = 0;
else if (vecs[0][1])
sv = 1;
else
sv = 2;
if (vecs[1][0])
tv = 0;
else if (vecs[1][1])
tv = 1;
else
tv = 2;
for (i=0 ; i<2 ; i++)
{
for (i = 0; i < 2; i++) {
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
vecs[i][sv] = ns;
vecs[i][tv] = nt;
}
for (i=0 ; i<2 ; i++)
for (j=0 ; j<3 ; j++)
for (i = 0; i < 2; i++)
for (j = 0; j < 3; j++)
tx.vecs[i][j] = vecs[i][j] / scale[i];
tx.vecs[0][3] = shift[0];
tx.vecs[1][3] = shift[1];
}
// unique the texinfo
f->texinfo = FindTexinfo (&tx);
// unique the texinfo
f->texinfo = FindTexinfo (&tx);
} while (1);
}
@ -456,32 +444,32 @@ void ParseBrush (void)
ParseEntity
================
*/
qboolean ParseEntity (void)
qboolean
ParseEntity (void)
{
if (!GetToken (true))
return false;
if (strcmp (token, "{") )
if (strcmp (token, "{"))
Sys_Error ("ParseEntity: { not found");
if (num_entities == MAX_MAP_ENTITIES)
Sys_Error ("num_entities == MAX_MAP_ENTITIES");
mapent = &entities[num_entities];
num_entities++;
do
{
do {
if (!GetToken (true))
Sys_Error ("ParseEntity: EOF without closing brace");
if (!strcmp (token, "}") )
if (!strcmp (token, "}"))
break;
if (!strcmp (token, "{") )
if (!strcmp (token, "{"))
ParseBrush ();
else
ParseEpair ();
} while (1);
GetVectorForKey (mapent, "origin", mapent->origin);
return true;
}
@ -491,22 +479,22 @@ qboolean ParseEntity (void)
LoadMapFile
================
*/
void LoadMapFile (char *filename)
void
LoadMapFile (char *filename)
{
char *buf;
char *buf;
buf = COM_LoadFile (filename, 0);
StartTokenParsing (buf);
num_entities = 0;
while (ParseEntity ())
{
while (ParseEntity ()) {
}
free (buf);
qprintf ("--- LoadMapFile ---\n");
qprintf ("%s\n", filename);
qprintf ("%5i brushes\n", nummapbrushes);
@ -515,55 +503,59 @@ void LoadMapFile (char *filename)
qprintf ("%5i texinfo\n", bsp->numtexinfo);
}
void PrintEntity (entity_t *ent)
void
PrintEntity (entity_t *ent)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
epair_t *ep;
for (ep = ent->epairs; ep; ep = ep->next)
printf ("%20s : %s\n", ep->key, ep->value);
}
char *ValueForKey (entity_t *ent, char *key)
char *
ValueForKey (entity_t *ent, char *key)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
epair_t *ep;
for (ep = ent->epairs; ep; ep = ep->next)
if (!strcmp (ep->key, key))
return ep->value;
return "";
}
void SetKeyValue (entity_t *ent, char *key, char *value)
void
SetKeyValue (entity_t *ent, char *key, char *value)
{
epair_t *ep;
for (ep=ent->epairs ; ep ; ep=ep->next)
if (!strcmp (ep->key, key) )
{
epair_t *ep;
for (ep = ent->epairs; ep; ep = ep->next)
if (!strcmp (ep->key, key)) {
free (ep->value);
ep->value = strdup (value);
return;
}
ep = malloc (sizeof(*ep));
ep = malloc (sizeof (*ep));
ep->next = ent->epairs;
ent->epairs = ep;
ep->key = strdup (key);
ep->value = strdup (value);
}
float FloatForKey (entity_t *ent, char *key)
float
FloatForKey (entity_t *ent, char *key)
{
char *k;
char *k;
k = ValueForKey (ent, key);
return atof(k);
return atof (k);
}
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
void
GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
{
char *k;
double v1, v2, v3;
char *k;
double v1, v2, v3;
k = ValueForKey (ent, key);
v1 = v2 = v3 = 0;
@ -575,33 +567,32 @@ void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
}
void WriteEntitiesToString (void)
void
WriteEntitiesToString (void)
{
char *buf, *end;
epair_t *ep;
char line[128];
int i;
char *buf, *end;
epair_t *ep;
char line[128];
int i;
buf = bsp->entdata;
end = buf;
*end = 0;
for (i=0 ; i<num_entities ; i++)
{
for (i = 0; i < num_entities; i++) {
ep = entities[i].epairs;
if (!ep)
continue; // ent got removed
strcat (end,"{\n");
continue; // ent got removed
strcat (end, "{\n");
end += 2;
for (ep = entities[i].epairs ; ep ; ep=ep->next)
{
for (ep = entities[i].epairs; ep; ep = ep->next) {
sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
strcat (end, line);
end += strlen(line);
end += strlen (line);
}
strcat (end,"}\n");
strcat (end, "}\n");
end += 2;
if (end > buf + MAX_MAP_ENTSTRING)
@ -609,4 +600,3 @@ void WriteEntitiesToString (void)
}
bsp->entdatasize = end - buf + 1;
}

View file

@ -36,27 +36,27 @@ CheckColinear
================
*/
void CheckColinear (face_t *f)
void
CheckColinear (face_t * f)
{
int i, j;
vec3_t v1, v2;
for (i=0 ; i<f->numpoints ;i++)
{
int i, j;
vec3_t v1, v2;
for (i = 0; i < f->numpoints; i++) {
// skip the point if the vector from the previous point is the same
// as the vector to the next point
j = (i - 1 < 0) ? f->numpoints - 1 : i - 1;
VectorSubtract (f->pts[i], f->pts[j], v1);
VectorNormalize (v1);
j = (i + 1 == f->numpoints) ? 0 : i + 1;
VectorSubtract (f->pts[j], f->pts[i], v2);
VectorNormalize (v2);
if (VectorCompare (v1, v2))
Sys_Error ("Colinear edge");
Sys_Error ("Colinear edge");
}
}
@ -71,16 +71,17 @@ Returns NULL if the faces couldn't be merged, or the new face.
The originals will NOT be freed.
=============
*/
face_t *TryMerge (face_t *f1, face_t *f2)
face_t *
TryMerge (face_t * f1, face_t * f2)
{
vec_t *p1, *p2, *p3, *p4, *back;
face_t *newf;
int i, j, k, l;
vec3_t normal, delta, planenormal;
vec_t dot;
plane_t *plane;
qboolean keep1, keep2;
vec_t *p1, *p2, *p3, *p4, *back;
face_t *newf;
int i, j, k, l;
vec3_t normal, delta, planenormal;
vec_t dot;
plane_t *plane;
qboolean keep1, keep2;
if (f1->numpoints == -1 || f2->numpoints == -1)
return NULL;
if (f1->planeside != f2->planeside)
@ -91,37 +92,34 @@ face_t *TryMerge (face_t *f1, face_t *f2)
return NULL;
if (f1->contents[1] != f2->contents[1])
return NULL;
//
// find a common edge
//
p1 = p2 = NULL; // stop compiler warning
j = 0; //
for (i=0 ; i<f1->numpoints ; i++)
{
//
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++)
{
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 (k=0 ; k<3 ; k++)
{
if (fabs(p1[k] - p4[k]) > EQUAL_EPSILON)
p4 = f2->pts[(j + 1) % f2->numpoints];
for (k = 0; k < 3; k++) {
if (fabs (p1[k] - p4[k]) > EQUAL_EPSILON)
break;
if (fabs(p2[k] - p3[k]) > EQUAL_EPSILON)
if (fabs (p2[k] - p3[k]) > EQUAL_EPSILON)
break;
}
if (k==3)
if (k == 3)
break;
}
if (j < f2->numpoints)
break;
}
if (i == f1->numpoints)
return NULL; // no matching edges
return NULL; // no matching edges
//
// check slope of connected lines
@ -131,56 +129,53 @@ face_t *TryMerge (face_t *f1, face_t *f2)
VectorCopy (plane->normal, planenormal);
if (f1->planeside)
VectorSubtract (vec3_origin, planenormal, planenormal);
back = f1->pts[(i+f1->numpoints-1)%f1->numpoints];
back = f1->pts[(i + f1->numpoints - 1) % f1->numpoints];
VectorSubtract (p1, back, delta);
CrossProduct (planenormal, delta, normal);
VectorNormalize (normal);
back = f2->pts[(j+2)%f2->numpoints];
back = f2->pts[(j + 2) % f2->numpoints];
VectorSubtract (back, p1, delta);
dot = DotProduct (delta, normal);
if (dot > CONTINUOUS_EPSILON)
return NULL; // not a convex polygon
return NULL; // not a convex polygon
keep1 = dot < -CONTINUOUS_EPSILON;
back = f1->pts[(i+2)%f1->numpoints];
back = f1->pts[(i + 2) % f1->numpoints];
VectorSubtract (back, p2, delta);
CrossProduct (planenormal, delta, normal);
VectorNormalize (normal);
back = f2->pts[(j+f2->numpoints-1)%f2->numpoints];
back = f2->pts[(j + f2->numpoints - 1) % f2->numpoints];
VectorSubtract (back, p2, delta);
dot = DotProduct (delta, normal);
if (dot > CONTINUOUS_EPSILON)
return NULL; // not a convex polygon
return NULL; // not a convex polygon
keep2 = dot < -CONTINUOUS_EPSILON;
//
// build the new polygon
//
if (f1->numpoints + f2->numpoints > MAXEDGES)
{
// Sys_Error ("TryMerge: too many edges!");
if (f1->numpoints + f2->numpoints > MAXEDGES) {
// Sys_Error ("TryMerge: too many edges!");
return NULL;
}
newf = NewFaceFromFace (f1);
// 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) % f1->numpoints; k != i; k = (k + 1) % f1->numpoints) {
if (k == (i + 1) % f1->numpoints && !keep2)
continue;
VectorCopy (f1->pts[k], newf->pts[newf->numpoints]);
newf->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) % f2->numpoints; l != j; l = (l + 1) % f2->numpoints) {
if (l == (j + 1) % f2->numpoints && !keep1)
continue;
VectorCopy (f2->pts[l], newf->pts[newf->numpoints]);
newf->numpoints++;
@ -195,29 +190,28 @@ face_t *TryMerge (face_t *f1, face_t *f2)
MergeFaceToList
===============
*/
qboolean mergedebug;
face_t *MergeFaceToList (face_t *face, face_t *list)
{
face_t *newf, *f;
for (f=list ; f ; f=f->next)
{
//CheckColinear (f);
if (mergedebug)
qboolean mergedebug;
face_t *
MergeFaceToList (face_t * face, face_t * list)
{
Draw_ClearWindow ();
Draw_DrawFace (face);
Draw_DrawFace (f);
Draw_SetBlack ();
}
face_t *newf, *f;
for (f = list; f; f = f->next) {
//CheckColinear (f);
if (mergedebug) {
Draw_ClearWindow ();
Draw_DrawFace (face);
Draw_DrawFace (f);
Draw_SetBlack ();
}
newf = TryMerge (face, f);
if (!newf)
continue;
FreeFace (face);
f->numpoints = -1; // merged out
f->numpoints = -1; // merged out
return MergeFaceToList (newf, list);
}
// didn't merge, so add at start
face->next = list;
return face;
@ -229,18 +223,17 @@ Draw_SetBlack ();
FreeMergeListScraps
===============
*/
face_t *FreeMergeListScraps (face_t *merged)
face_t *
FreeMergeListScraps (face_t * merged)
{
face_t *head, *next;
face_t *head, *next;
head = NULL;
for ( ; merged ; merged = next)
{
for (; merged; merged = next) {
next = merged->next;
if (merged->numpoints == -1)
FreeFace (merged);
else
{
else {
merged->next = head;
head = merged;
}
@ -255,15 +248,15 @@ face_t *FreeMergeListScraps (face_t *merged)
MergePlaneFaces
===============
*/
void MergePlaneFaces (surface_t *plane)
void
MergePlaneFaces (surface_t * plane)
{
face_t *f1, *next;
face_t *merged;
face_t *f1, *next;
face_t *merged;
merged = NULL;
for (f1 = plane->faces ; f1 ; f1 = next)
{
for (f1 = plane->faces; f1; f1 = next) {
next = f1->next;
merged = MergeFaceToList (f1, merged);
}
@ -278,25 +271,24 @@ void MergePlaneFaces (surface_t *plane)
MergeAll
============
*/
void MergeAll (surface_t *surfhead)
void
MergeAll (surface_t * surfhead)
{
surface_t *surf;
int mergefaces;
face_t *f;
surface_t *surf;
int mergefaces;
face_t *f;
printf ("---- MergeAll ----\n");
mergefaces = 0;
for (surf = surfhead ; surf ; surf=surf->next)
{
mergefaces = 0;
for (surf = surfhead; surf; surf = surf->next) {
MergePlaneFaces (surf);
Draw_ClearWindow ();
for (f=surf->faces ; f ; f=f->next)
{
Draw_DrawFace (f);
Draw_ClearWindow ();
for (f = surf->faces; f; f = f->next) {
Draw_DrawFace (f);
mergefaces++;
}
}
printf ("%i mergefaces\n", mergefaces);
}

View file

@ -20,54 +20,67 @@
#include "bsp5.h"
void Draw_ClearBounds (void)
void
Draw_ClearBounds (void)
{
}
void Draw_AddToBounds (vec3_t v)
void
Draw_AddToBounds (vec3_t v)
{
}
void Draw_DrawFace (face_t *f)
void
Draw_DrawFace (face_t * f)
{
}
void Draw_ClearWindow (void)
void
Draw_ClearWindow (void)
{
}
void Draw_SetRed (void)
void
Draw_SetRed (void)
{
}
void Draw_SetGrey (void)
void
Draw_SetGrey (void)
{
}
void Draw_SetBlack (void)
void
Draw_SetBlack (void)
{
}
void DrawPoint (vec3_t v)
void
DrawPoint (vec3_t v)
{
}
void DrawLeaf (node_t *l, int color)
void
DrawLeaf (node_t * l, int color)
{
}
void DrawBrush (brush_t *b)
void
DrawBrush (brush_t * b)
{
}
void DrawWinding (winding_t *w)
void
DrawWinding (winding_t * w)
{
}
void DrawTri (vec3_t p1, vec3_t p2, vec3_t p3)
void
DrawTri (vec3_t p1, vec3_t p2, vec3_t p3)
{
}
void DrawPortal (portal_t *portal)
void
DrawPortal (portal_t * portal)
{
}

View file

@ -25,25 +25,28 @@
#include "bsp5.h"
int outleafs;
int outleafs;
/*
===========
PointInLeaf
===========
*/
node_t *PointInLeaf (node_t *node, vec3_t point)
node_t *
PointInLeaf (node_t * node, vec3_t point)
{
vec_t d;
vec_t d;
if (node->contents)
return node;
d = DotProduct (planes[node->planenum].normal, point) - planes[node->planenum]. dist;
d =
DotProduct (planes[node->planenum].normal,
point) - planes[node->planenum].dist;
if (d > 0)
return PointInLeaf (node->children[0], point);
return PointInLeaf (node->children[1], point);
}
@ -52,10 +55,11 @@ node_t *PointInLeaf (node_t *node, vec3_t point)
PlaceOccupant
===========
*/
qboolean PlaceOccupant (int num, vec3_t point, node_t *headnode)
qboolean
PlaceOccupant (int num, vec3_t point, node_t * headnode)
{
node_t *n;
node_t *n;
n = PointInLeaf (headnode, point);
if (n->contents == CONTENTS_SOLID)
return false;
@ -69,47 +73,45 @@ qboolean PlaceOccupant (int num, vec3_t point, node_t *headnode)
MarkLeakTrail
==============
*/
portal_t *prevleaknode;
FILE *leakfile;
void MarkLeakTrail (portal_t *n2)
portal_t *prevleaknode;
FILE *leakfile;
void
MarkLeakTrail (portal_t * n2)
{
int i, j;
vec3_t p1, p2, dir;
float len;
portal_t *n1;
int i, j;
vec3_t p1, p2, dir;
float len;
portal_t *n1;
if (hullnum)
return;
n1 = prevleaknode;
prevleaknode = n2;
if (!n1)
return;
VectorCopy (n2->winding->points[0], p1);
for (i=1 ; i< n2->winding->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
for (i = 1; i < n2->winding->numpoints; i++) {
for (j = 0; j < 3; j++)
p1[j] = (p1[j] + n2->winding->points[i][j]) / 2;
}
VectorCopy (n1->winding->points[0], p2);
for (i=1 ; i< n1->winding->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
for (i = 1; i < n1->winding->numpoints; i++) {
for (j = 0; j < 3; j++)
p2[j] = (p2[j] + n1->winding->points[i][j]) / 2;
}
VectorSubtract (p2, p1, dir);
len = VectorLength (dir);
VectorNormalize (dir);
while (len > 2)
{
fprintf (leakfile,"%f %f %f\n", p1[0], p1[1], p1[2]);
for (i=0 ; i<3 ; i++)
p1[i] += dir[i]*2;
while (len > 2) {
fprintf (leakfile, "%f %f %f\n", p1[0], p1[1], p1[2]);
for (i = 0; i < 3; i++)
p1[i] += dir[i] * 2;
len -= 2;
}
}
@ -122,22 +124,23 @@ If fill is false, just check, don't fill
Returns true if an occupied leaf is reached
==================
*/
int hit_occupied;
int backdraw;
qboolean RecursiveFillOutside (node_t *l, qboolean fill)
int hit_occupied;
int backdraw;
qboolean
RecursiveFillOutside (node_t * l, qboolean fill)
{
portal_t *p;
int s;
portal_t *p;
int s;
if (l->contents == CONTENTS_SOLID || l->contents == CONTENTS_SKY)
return false;
if (l->valid == valid)
return false;
if (l->occupied)
return true;
l->valid = valid;
// fill it and it's neighbors
@ -145,14 +148,12 @@ qboolean RecursiveFillOutside (node_t *l, qboolean fill)
l->contents = CONTENTS_SOLID;
outleafs++;
for (p=l->portals ; p ; )
{
for (p = l->portals; p;) {
s = (p->nodes[0] == l);
if (RecursiveFillOutside (p->nodes[s], fill) )
{ // leaked, so stop filling
if (backdraw-- > 0)
{
if (RecursiveFillOutside (p->nodes[s], fill)) { // leaked, so stop
// filling
if (backdraw-- > 0) {
MarkLeakTrail (p);
DrawLeaf (l, 2);
}
@ -160,7 +161,7 @@ qboolean RecursiveFillOutside (node_t *l, qboolean fill)
}
p = p->next[!s];
}
return false;
}
@ -170,12 +171,12 @@ ClearOutFaces
==================
*/
void ClearOutFaces (node_t *node)
void
ClearOutFaces (node_t * node)
{
face_t **fp;
if (node->planenum != -1)
{
face_t **fp;
if (node->planenum != -1) {
ClearOutFaces (node->children[0]);
ClearOutFaces (node->children[1]);
return;
@ -183,9 +184,8 @@ void ClearOutFaces (node_t *node)
if (node->contents != CONTENTS_SOLID)
return;
for (fp=node->markfaces ; *fp ; fp++)
{
// mark all the original faces that are removed
for (fp = node->markfaces; *fp; fp++) {
// mark all the original faces that are removed
(*fp)->numpoints = 0;
}
node->faces = NULL;
@ -200,34 +200,33 @@ FillOutside
===========
*/
qboolean FillOutside (node_t *node)
qboolean
FillOutside (node_t * node)
{
int s;
vec_t *v;
int i;
qboolean inside;
int s;
vec_t *v;
int i;
qboolean inside;
qprintf ("----- FillOutside ----\n");
if (nofill)
{
if (nofill) {
printf ("skipped\n");
return false;
}
inside = false;
for (i=1 ; i<num_entities ; i++)
{
if (!VectorCompare(entities[i].origin, vec3_origin))
{
for (i = 1; i < num_entities; i++) {
if (!VectorCompare (entities[i].origin, vec3_origin)) {
if (PlaceOccupant (i, entities[i].origin, node))
inside = true;
}
}
if (!inside)
{
printf ("Hullnum %i: No entities in empty space -- no filling performed\n", hullnum);
if (!inside) {
printf
("Hullnum %i: No entities in empty space -- no filling performed\n",
hullnum);
return false;
}
@ -238,24 +237,22 @@ qboolean FillOutside (node_t *node)
valid++;
prevleaknode = NULL;
if (!hullnum)
{
if (!hullnum) {
leakfile = fopen (pointfilename, "w");
if (!leakfile)
Sys_Error ("Couldn't open %s\n", pointfilename);
}
if (RecursiveFillOutside (outside_node.portals->nodes[s], false))
{
if (RecursiveFillOutside (outside_node.portals->nodes[s], false)) {
v = entities[hit_occupied].origin;
qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n"
, v[0], v[1], v[2]);
qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n", v[0], v[1],
v[2]);
qprintf ("no filling performed\n");
if (!hullnum)
fclose (leakfile);
qprintf ("leak file written to %s\n", pointfilename);
qprintf ("leak file written to %s\n", pointfilename);
qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
return false;
}
@ -266,11 +263,9 @@ qboolean FillOutside (node_t *node)
valid++;
RecursiveFillOutside (outside_node.portals->nodes[s], true);
// remove faces from filled in leafs
// remove faces from filled in leafs
ClearOutFaces (node);
qprintf ("%4i outleafs\n", outleafs);
return true;
}

View file

@ -26,7 +26,9 @@
#include "bsp5.h"
node_t outside_node; // portals outside the world face this
node_t outside_node; // portals outside the world face
// this
//=============================================================================
@ -35,7 +37,8 @@ node_t outside_node; // portals outside the world face this
AddPortalToNodes
=============
*/
void AddPortalToNodes (portal_t *p, node_t *front, node_t *back)
void
AddPortalToNodes (portal_t * p, node_t * front, node_t * back)
{
if (p->nodes[0] || p->nodes[1])
Sys_Error ("AddPortalToNode: allready included");
@ -43,7 +46,7 @@ void AddPortalToNodes (portal_t *p, node_t *front, node_t *back)
p->nodes[0] = front;
p->next[0] = front->portals;
front->portals = p;
p->nodes[1] = back;
p->next[1] = back->portals;
back->portals = p;
@ -55,19 +58,19 @@ void AddPortalToNodes (portal_t *p, node_t *front, node_t *back)
RemovePortalFromNode
=============
*/
void RemovePortalFromNode (portal_t *portal, node_t *l)
void
RemovePortalFromNode (portal_t * portal, node_t * l)
{
portal_t **pp, *t;
portal_t **pp, *t;
// remove reference to the current portal
pp = &l->portals;
while (1)
{
while (1) {
t = *pp;
if (!t)
Sys_Error ("RemovePortalFromNode: portal not in leaf");
Sys_Error ("RemovePortalFromNode: portal not in leaf");
if ( t == portal )
if (t == portal)
break;
if (t->nodes[0] == l)
@ -77,30 +80,28 @@ void RemovePortalFromNode (portal_t *portal, node_t *l)
else
Sys_Error ("RemovePortalFromNode: portal not bounding leaf");
}
if (portal->nodes[0] == l)
{
if (portal->nodes[0] == l) {
*pp = portal->next[0];
portal->nodes[0] = NULL;
}
else if (portal->nodes[1] == l)
{
*pp = portal->next[1];
} else if (portal->nodes[1] == l) {
*pp = portal->next[1];
portal->nodes[1] = NULL;
}
}
//============================================================================
void PrintPortal (portal_t *p)
void
PrintPortal (portal_t * p)
{
int i;
winding_t *w;
int i;
winding_t *w;
w = p->winding;
for (i=0 ; i<w->numpoints ; i++)
printf ("(%5.0f,%5.0f,%5.0f)\n",w->points[i][0]
, w->points[i][1], w->points[i][2]);
for (i = 0; i < w->numpoints; i++)
printf ("(%5.0f,%5.0f,%5.0f)\n", w->points[i][0]
, w->points[i][1], w->points[i][2]);
}
/*
@ -110,108 +111,103 @@ MakeHeadnodePortals
The created portals will face the global outside_node
================
*/
void MakeHeadnodePortals (node_t *node)
void
MakeHeadnodePortals (node_t * node)
{
vec3_t bounds[2];
int i, j, n;
portal_t *p, *portals[6];
plane_t bplanes[6], *pl;
int side;
vec3_t bounds[2];
int i, j, n;
portal_t *p, *portals[6];
plane_t bplanes[6], *pl;
int side;
Draw_ClearWindow ();
// pad with some space so there will never be null volume leafs
for (i=0 ; i<3 ; i++)
{
for (i = 0; i < 3; i++) {
bounds[0][i] = brushset->mins[i] - SIDESPACE;
bounds[1][i] = brushset->maxs[i] + SIDESPACE;
}
outside_node.contents = CONTENTS_SOLID;
outside_node.portals = NULL;
for (i=0 ; i<3 ; i++)
for (j=0 ; j<2 ; j++)
{
n = j*3 + i;
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++) {
n = j * 3 + i;
p = AllocPortal ();
portals[n] = p;
pl = &bplanes[n];
memset (pl, 0, sizeof(*pl));
if (j)
{
memset (pl, 0, sizeof (*pl));
if (j) {
pl->normal[i] = -1;
pl->dist = -bounds[j][i];
}
else
{
} else {
pl->normal[i] = 1;
pl->dist = bounds[j][i];
}
p->planenum = FindPlane (pl, &side);
p->winding = BaseWindingForPlane (pl);
if (side)
AddPortalToNodes (p, &outside_node, node);
else
AddPortalToNodes (p, node, &outside_node);
}
// clip the basewindings by all the other planes
for (i=0 ; i<6 ; i++)
{
for (j=0 ; j<6 ; j++)
{
for (i = 0; i < 6; i++) {
for (j = 0; j < 6; j++) {
if (j == i)
continue;
portals[i]->winding = ClipWinding (portals[i]->winding, &bplanes[j], true);
portals[i]->winding =
ClipWinding (portals[i]->winding, &bplanes[j], true);
}
}
}
//============================================================================
void CheckWindingInNode (winding_t *w, node_t *node)
void
CheckWindingInNode (winding_t * w, node_t * node)
{
int i, j;
for (i=0 ; i<w->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
int i, j;
for (i = 0; i < w->numpoints; i++) {
for (j = 0; j < 3; j++)
if (w->points[i][j] < node->mins[j] - 1
|| w->points[i][j] > node->maxs[j] + 1)
{
|| w->points[i][j] > node->maxs[j] + 1) {
printf ("WARNING: CheckWindingInNode: outside\n");
return;
}
}
}
void CheckWindingArea (winding_t *w)
void
CheckWindingArea (winding_t * w)
{
int i;
float total, add;
vec3_t v1, v2, cross;
int i;
float total, add;
vec3_t v1, v2, cross;
total = 0;
for (i=1 ; i<w->numpoints ; i++)
{
for (i = 1; i < w->numpoints; i++) {
VectorSubtract (w->points[i], w->points[0], v1);
VectorSubtract (w->points[i+1], w->points[0], v2);
VectorSubtract (w->points[i + 1], w->points[0], v2);
CrossProduct (v1, v2, cross);
add = VectorLength (cross);
total += add*0.5;
total += add * 0.5;
}
if (total < 16)
printf ("WARNING: winding area %f\n", total);
}
void PlaneFromWinding (winding_t *w, plane_t *plane)
void
PlaneFromWinding (winding_t * w, plane_t *plane)
{
vec3_t v1, v2;
vec3_t v1, v2;
// calc plane
VectorSubtract (w->points[2], w->points[1], v1);
@ -221,19 +217,19 @@ void PlaneFromWinding (winding_t *w, plane_t *plane)
plane->dist = DotProduct (w->points[0], plane->normal);
}
void CheckLeafPortalConsistancy (node_t *node)
void
CheckLeafPortalConsistancy (node_t * node)
{
int side, side2;
portal_t *p, *p2;
plane_t plane, plane2;
int i;
winding_t *w;
float dist;
int side, side2;
portal_t *p, *p2;
plane_t plane, plane2;
int i;
winding_t *w;
float dist;
side = side2 = 0; // quiet compiler warning
side = side2 = 0; // quiet compiler warning
for (p = node->portals ; p ; p = p->next[side])
{
for (p = node->portals; p; p = p->next[side]) {
if (p->nodes[0] == node)
side = 0;
else if (p->nodes[1] == node)
@ -243,12 +239,11 @@ void CheckLeafPortalConsistancy (node_t *node)
CheckWindingInNode (p->winding, node);
CheckWindingArea (p->winding);
// check that the side orders are correct
// check that the side orders are correct
plane = planes[p->planenum];
PlaneFromWinding (p->winding, &plane2);
for (p2 = node->portals ; p2 ; p2 = p2->next[side2])
{
PlaneFromWinding (p->winding, &plane2);
for (p2 = node->portals; p2; p2 = p2->next[side2]) {
if (p2->nodes[0] == node)
side2 = 0;
else if (p2->nodes[1] == node)
@ -256,16 +251,14 @@ void CheckLeafPortalConsistancy (node_t *node)
else
Sys_Error ("CutNodePortals_r: mislinked portal");
w = p2->winding;
for (i=0 ; i<w->numpoints ; i++)
{
for (i = 0; i < w->numpoints; i++) {
dist = DotProduct (w->points[i], plane.normal) - plane.dist;
if ( (side == 0 && dist < -1) || (side == 1 && dist > 1) )
{
if ((side == 0 && dist < -1) || (side == 1 && dist > 1)) {
printf ("WARNING: portal siding direction is wrong\n");
return;
}
}
}
}
}
@ -277,22 +270,22 @@ CutNodePortals_r
================
*/
void CutNodePortals_r (node_t *node)
void
CutNodePortals_r (node_t * node)
{
plane_t *plane, clipplane;
node_t *f, *b, *other_node;
portal_t *p, *new_portal, *next_portal;
winding_t *w, *frontwinding, *backwinding;
int side;
plane_t *plane, clipplane;
node_t *f, *b, *other_node;
portal_t *p, *new_portal, *next_portal;
winding_t *w, *frontwinding, *backwinding;
int side;
// CheckLeafPortalConsistancy (node);
// CheckLeafPortalConsistancy (node);
//
// seperate the portals on node into it's children
// seperate the portals on node into it's children
//
if (node->contents)
{
return; // at a leaf, no more dividing
if (node->contents) {
return; // at a leaf, no more dividing
}
plane = &planes[node->planenum];
@ -306,43 +299,36 @@ void CutNodePortals_r (node_t *node)
//
new_portal = AllocPortal ();
new_portal->planenum = node->planenum;
w = BaseWindingForPlane (&planes[node->planenum]);
side = 0; // shut up compiler warning
for (p = node->portals ; p ; p = p->next[side])
{
side = 0; // shut up compiler warning
for (p = node->portals; p; p = p->next[side]) {
clipplane = planes[p->planenum];
if (p->nodes[0] == node)
side = 0;
else if (p->nodes[1] == node)
{
else if (p->nodes[1] == node) {
clipplane.dist = -clipplane.dist;
VectorSubtract (vec3_origin, clipplane.normal, clipplane.normal);
side = 1;
}
else
} else
Sys_Error ("CutNodePortals_r: mislinked portal");
w = ClipWinding (w, &clipplane, true);
if (!w)
{
if (!w) {
printf ("WARNING: CutNodePortals_r:new portal was clipped away\n");
break;
}
}
if (w)
{
// if the plane was not clipped on all sides, there was an error
new_portal->winding = w;
if (w) {
// if the plane was not clipped on all sides, there was an error
new_portal->winding = w;
AddPortalToNodes (new_portal, f, b);
}
//
// partition the portals
//
for (p = node->portals ; p ; p = next_portal)
{
for (p = node->portals; p; p = next_portal) {
if (p->nodes[0] == node)
side = 0;
else if (p->nodes[1] == node)
@ -359,48 +345,42 @@ void CutNodePortals_r (node_t *node)
// cut the portal into two portals, one on each side of the cut plane
//
DivideWinding (p->winding, plane, &frontwinding, &backwinding);
if (!frontwinding)
{
if (!frontwinding) {
if (side == 0)
AddPortalToNodes (p, b, other_node);
else
AddPortalToNodes (p, other_node, b);
continue;
}
if (!backwinding)
{
if (!backwinding) {
if (side == 0)
AddPortalToNodes (p, f, other_node);
else
AddPortalToNodes (p, other_node, f);
continue;
}
// the winding is split
// the winding is split
new_portal = AllocPortal ();
*new_portal = *p;
new_portal->winding = backwinding;
FreeWinding (p->winding);
p->winding = frontwinding;
if (side == 0)
{
if (side == 0) {
AddPortalToNodes (p, f, other_node);
AddPortalToNodes (new_portal, b, other_node);
}
else
{
} else {
AddPortalToNodes (p, other_node, f);
AddPortalToNodes (new_portal, other_node, b);
}
}
DrawLeaf (f,1);
DrawLeaf (b,2);
CutNodePortals_r (f);
CutNodePortals_r (b);
DrawLeaf (f, 1);
DrawLeaf (b, 2);
CutNodePortals_r (f);
CutNodePortals_r (b);
}
@ -412,12 +392,13 @@ PortalizeWorld
Builds the exact polyhedrons for the nodes and leafs
==================
*/
void PortalizeWorld (node_t *headnode)
void
PortalizeWorld (node_t * headnode)
{
qprintf ("----- portalize ----\n");
MakeHeadnodePortals (headnode);
CutNodePortals_r (headnode);
CutNodePortals_r (headnode);
}
@ -427,18 +408,17 @@ FreeAllPortals
==================
*/
void FreeAllPortals (node_t *node)
void
FreeAllPortals (node_t * node)
{
portal_t *p, *nextp;
if (!node->contents)
{
portal_t *p, *nextp;
if (!node->contents) {
FreeAllPortals (node->children[0]);
FreeAllPortals (node->children[1]);
}
for (p=node->portals ; p ; p=nextp)
{
for (p = node->portals; p; p = nextp) {
if (p->nodes[0] == node)
nextp = p->next[0];
else
@ -460,65 +440,64 @@ PORTAL FILE GENERATION
#define PORTALFILE "PRT1"
FILE *pf;
int num_visleafs; // leafs the player can be in
int num_visportals;
FILE *pf;
int num_visleafs; // leafs the player can be in
int num_visportals;
void WriteFloat (FILE *f, vec_t v)
void
WriteFloat (FILE * f, vec_t v)
{
if ( fabs(v - (int) (v + 0.5)) < 0.001 )
fprintf (f,"%i ",(int)(v + 0.5));
if (fabs (v - (int) (v + 0.5)) < 0.001)
fprintf (f, "%i ", (int) (v + 0.5));
else
fprintf (f,"%f ",v);
fprintf (f, "%f ", v);
}
void WritePortalFile_r (node_t *node)
void
WritePortalFile_r (node_t * node)
{
int i;
portal_t *p;
winding_t *w;
plane_t *pl, plane2;
int i;
portal_t *p;
winding_t *w;
plane_t *pl, plane2;
if (!node->contents)
{
if (!node->contents) {
WritePortalFile_r (node->children[0]);
WritePortalFile_r (node->children[1]);
return;
}
if (node->contents == CONTENTS_SOLID)
return;
for (p = node->portals ; p ; )
{
for (p = node->portals; p;) {
w = p->winding;
if (w && p->nodes[0] == node
&& p->nodes[0]->contents == p->nodes[1]->contents)
{
// write out to the file
// sometimes planes get turned around when they are very near
// the changeover point between different axis. interpret the
// plane the same way vis will, and flip the side orders if needed
&& p->nodes[0]->contents == p->nodes[1]->contents) {
// write out to the file
// sometimes planes get turned around when they are very near
// the changeover point between different axis. interpret the
// plane the same way vis will, and flip the side orders if
// needed
pl = &planes[p->planenum];
PlaneFromWinding (w, &plane2);
if ( DotProduct (pl->normal, plane2.normal) < 0.99 )
{ // backwards...
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->visleafnum, p->nodes[0]->visleafnum);
}
else
fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->visleafnum, p->nodes[1]->visleafnum);
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (pf,"(");
if (DotProduct (pl->normal, plane2.normal) < 0.99) { // backwards...
fprintf (pf, "%i %i %i ", w->numpoints, p->nodes[1]->visleafnum,
p->nodes[0]->visleafnum);
} else
fprintf (pf, "%i %i %i ", w->numpoints, p->nodes[0]->visleafnum,
p->nodes[1]->visleafnum);
for (i = 0; i < w->numpoints; i++) {
fprintf (pf, "(");
WriteFloat (pf, w->points[i][0]);
WriteFloat (pf, w->points[i][1]);
WriteFloat (pf, w->points[i][2]);
fprintf (pf,") ");
fprintf (pf, ") ");
}
fprintf (pf,"\n");
fprintf (pf, "\n");
}
if (p->nodes[0] == node)
p = p->next[0];
else
@ -526,45 +505,43 @@ void WritePortalFile_r (node_t *node)
}
}
/*
================
NumberLeafs_r
================
*/
void NumberLeafs_r (node_t *node)
void
NumberLeafs_r (node_t * node)
{
portal_t *p;
portal_t *p;
if (!node->contents)
{ // decision node
if (!node->contents) { // decision node
node->visleafnum = -99;
NumberLeafs_r (node->children[0]);
NumberLeafs_r (node->children[1]);
return;
}
Draw_ClearWindow ();
DrawLeaf (node, 1);
if (node->contents == CONTENTS_SOLID)
{ // solid block, viewpoint never inside
if (node->contents == CONTENTS_SOLID) { // solid block, viewpoint never
// inside
node->visleafnum = -1;
return;
}
node->visleafnum = num_visleafs++;
for (p = node->portals ; p ; )
{
for (p = node->portals; p;) {
if (p->nodes[0] == node) // only write out from first leaf
{
if (p->nodes[0]->contents == p->nodes[1]->contents)
num_visportals++;
p = p->next[0];
}
else
p = p->next[1];
} else
p = p->next[1];
}
}
@ -575,26 +552,25 @@ void NumberLeafs_r (node_t *node)
WritePortalfile
================
*/
void WritePortalfile (node_t *headnode)
void
WritePortalfile (node_t * headnode)
{
// set the visleafnum field in every leaf and count the total number of portals
num_visleafs = 0;
num_visportals = 0;
NumberLeafs_r (headnode);
// write the file
printf ("writing %s\n", portfilename);
pf = fopen (portfilename, "w");
if (!pf)
Sys_Error ("Error opening %s", portfilename);
fprintf (pf, "%s\n", PORTALFILE);
fprintf (pf, "%i\n", num_visleafs);
fprintf (pf, "%i\n", num_visportals);
WritePortalFile_r (headnode);
fclose (pf);
}

File diff suppressed because it is too large Load diff

View file

@ -47,34 +47,36 @@ face to region mapping numbers
#define MAX_EDGES_IN_REGION 32
int firstedge;
int firstedge;
vec3_t region_mins, region_maxs;
vec3_t region_mins, region_maxs;
void AddPointToRegion (vec3_t p)
void
AddPointToRegion (vec3_t p)
{
int i;
for (i=0 ; i<3 ; i++)
{
int i;
for (i = 0; i < 3; i++) {
if (p[i] < region_mins[i])
region_mins[i] = p[i];
if (p[i] > region_maxs[i])
region_maxs[i] = p[i];
}
}
}
void ClearRegionSize (void)
void
ClearRegionSize (void)
{
region_mins[0] = region_mins[1] = region_mins[2] = 9999;
region_maxs[0] = region_maxs[1] = region_maxs[2] = -9999;
}
void AddFaceToRegionSize (face_t *f)
void
AddFaceToRegionSize (face_t * f)
{
int i;
int i;
for (i=0 ; i<f->numpoints ; i++)
for (i = 0; i < f->numpoints; i++)
AddPointToRegion (f->pts[i]);
}
@ -83,45 +85,39 @@ void AddFaceToRegionSize (face_t *f)
CanJoinFaces
==============
*/
qboolean CanJoinFaces (face_t *f, face_t *f2)
qboolean
CanJoinFaces (face_t * f, face_t * f2)
{
vec3_t oldmins, oldmaxs;
int i;
vec3_t oldmins, oldmaxs;
int i;
if (f2->planenum != f->planenum
|| f2->planeside != f->planeside
|| f2->texturenum != f->texturenum)
|| f2->planeside != f->planeside || f2->texturenum != f->texturenum)
return false;
if (f2->outputnumber != -1)
return false;
if (f2->contents[0] != f->contents[0])
{ // does this ever happen? theyy shouldn't share.
if (f2->contents[0] != f->contents[0]) { // does this ever happen?
// theyy shouldn't share.
printf ("CanJoinFaces: edge with different contents");
return false;
}
// check size constraints
if ( ! (bsp->texinfo[f->texturenum].flags & TEX_SPECIAL) )
{
if (!(bsp->texinfo[f->texturenum].flags & TEX_SPECIAL)) {
VectorCopy (region_mins, oldmins);
VectorCopy (region_maxs, oldmaxs);
AddFaceToRegionSize (f2);
for (i=0 ; i<3 ; i++)
{
if (region_maxs[i] - region_mins[i] > 240)
{
for (i = 0; i < 3; i++) {
if (region_maxs[i] - region_mins[i] > 240) {
VectorCopy (oldmins, region_mins);
VectorCopy (oldmaxs, region_maxs);
return false;
}
}
}
else
{
} else {
if (bsp->numsurfedges - firstedge + f2->numpoints > MAX_EDGES_IN_REGION)
return false; // a huge water or sky polygon
return false; // a huge water or sky polygon
}
// check edge count constraints
return true;
}
@ -132,44 +128,41 @@ qboolean CanJoinFaces (face_t *f, face_t *f2)
RecursiveGrowRegion
==============
*/
void RecursiveGrowRegion (dface_t *r, face_t *f)
void
RecursiveGrowRegion (dface_t *r, face_t * f)
{
int e;
face_t *f2;
int i;
int e;
face_t *f2;
int i;
if (f->outputnumber == bsp->numfaces)
return;
if (f->outputnumber != -1)
Sys_Error ("RecursiveGrowRegion: region collision");
f->outputnumber = bsp->numfaces;
// add edges
for (i=0 ; i<f->numpoints ; i++)
{
// add edges
for (i = 0; i < f->numpoints; i++) {
e = f->edges[i];
if (!edgefaces[abs(e)][0])
continue; // edge has allready been removed
if (!edgefaces[abs (e)][0])
continue; // edge has allready been removed
if (e > 0)
f2 = edgefaces[e][1];
else
f2 = edgefaces[-e][0];
if (f2 && f2->outputnumber == bsp->numfaces)
{
edgefaces[abs(e)][0] = NULL;
edgefaces[abs(e)][1] = NULL;
continue; // allready merged
if (f2 && f2->outputnumber == bsp->numfaces) {
edgefaces[abs (e)][0] = NULL;
edgefaces[abs (e)][1] = NULL;
continue; // allready merged
}
if (f2 && CanJoinFaces (f, f2))
{ // remove the edge and merge the faces
edgefaces[abs(e)][0] = NULL;
edgefaces[abs(e)][1] = NULL;
if (f2 && CanJoinFaces (f, f2)) { // remove the edge and merge the
// faces
edgefaces[abs (e)][0] = NULL;
edgefaces[abs (e)][1] = NULL;
RecursiveGrowRegion (r, f2);
}
else
{
// emit a surfedge
} else {
// emit a surfedge
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
bsp->surfedges[bsp->numsurfedges] = e;
@ -179,17 +172,17 @@ void RecursiveGrowRegion (dface_t *r, face_t *f)
}
void PrintDface (int f)
{ // for debugging
dface_t *df;
dedge_t *e;
int i, n;
void
PrintDface (int f)
{ // for debugging
dface_t *df;
dedge_t *e;
int i, n;
df = &bsp->faces[f];
for (i=0 ; i<df->numedges ; i++)
{
n = bsp->surfedges[df->firstedge+i];
e = &bsp->edges[abs(n)];
for (i = 0; i < df->numedges; i++) {
n = bsp->surfedges[df->firstedge + i];
e = &bsp->edges[abs (n)];
if (n < 0)
printf ("%5i = %5i : %5i\n", n, e->v[1], e->v[0]);
else
@ -197,21 +190,19 @@ void PrintDface (int f)
}
}
void FindVertexUse (int v)
{ // for debugging
int i, j, n;
dface_t *df;
dedge_t *e;
for (i=firstmodelface ; i<bsp->numfaces ; i++)
{
void
FindVertexUse (int v)
{ // for debugging
int i, j, n;
dface_t *df;
dedge_t *e;
for (i = firstmodelface; i < bsp->numfaces; i++) {
df = &bsp->faces[i];
for (j=0 ; j<df->numedges ; j++)
{
n = bsp->surfedges[df->firstedge+j];
e = &bsp->edges[abs(n)];
if (e->v[0] == v || e->v[1] == v)
{
for (j = 0; j < df->numedges; j++) {
n = bsp->surfedges[df->firstedge + j];
e = &bsp->edges[abs (n)];
if (e->v[0] == v || e->v[1] == v) {
printf ("on face %i\n", i);
break;
}
@ -219,19 +210,17 @@ void FindVertexUse (int v)
}
}
void FindEdgeUse (int v)
{ // for debugging
int i, j, n;
dface_t *df;
for (i=firstmodelface ; i<bsp->numfaces ; i++)
{
void
FindEdgeUse (int v)
{ // for debugging
int i, j, n;
dface_t *df;
for (i = firstmodelface; i < bsp->numfaces; i++) {
df = &bsp->faces[i];
for (j=0 ; j<df->numedges ; j++)
{
n = bsp->surfedges[df->firstedge+j];
if (n == v || -n == v)
{
for (j = 0; j < df->numedges; j++) {
n = bsp->surfedges[df->firstedge + j];
if (n == v || -n == v) {
printf ("on face %i\n", i);
break;
}
@ -247,26 +236,28 @@ Extends e1 so that it goes all the way to e2, and removes all references
to e2
================
*/
int edgemapping[MAX_MAP_EDGES];
void HealEdges (int e1, int e2)
int edgemapping[MAX_MAP_EDGES];
void
HealEdges (int e1, int e2)
{
int i, j, n, saved;
dface_t *df;
dedge_t *ed, *ed2;
vec3_t v1, v2;
dface_t *found[2];
int foundj[2];
int i, j, n, saved;
dface_t *df;
dedge_t *ed, *ed2;
vec3_t v1, v2;
dface_t *found[2];
int foundj[2];
return;
return;
e1 = edgemapping[e1];
e2 = edgemapping[e2];
// extend e1 to e2
ed = &bsp->edges[e1];
ed2 = &bsp->edges[e2];
VectorSubtract (bsp->vertexes[ed->v[1]].point, bsp->vertexes[ed->v[0]].point, v1);
VectorSubtract (bsp->vertexes[ed->v[1]].point,
bsp->vertexes[ed->v[0]].point, v1);
VectorNormalize (v1);
if (ed->v[0] == ed2->v[0])
ed->v[0] = ed2->v[1];
else if (ed->v[0] == ed2->v[1])
@ -278,24 +269,22 @@ return;
else
Sys_Error ("HealEdges: edges don't meet");
VectorSubtract (bsp->vertexes[ed->v[1]].point, bsp->vertexes[ed->v[0]].point, v2);
VectorSubtract (bsp->vertexes[ed->v[1]].point,
bsp->vertexes[ed->v[0]].point, v2);
VectorNormalize (v2);
if (!VectorCompare (v1, v2))
Sys_Error ("HealEdges: edges not colinear");
edgemapping[e2] = e1;
saved = 0;
// remove all uses of e2
for (i=firstmodelface ; i<bsp->numfaces ; i++)
{
for (i = firstmodelface; i < bsp->numfaces; i++) {
df = &bsp->faces[i];
for (j=0 ; j<df->numedges ; j++)
{
n = bsp->surfedges[df->firstedge+j];
if (n == e2 || n == -e2)
{
for (j = 0; j < df->numedges; j++) {
n = bsp->surfedges[df->firstedge + j];
if (n == e2 || n == -e2) {
found[saved] = df;
foundj[saved] = j;
saved++;
@ -303,19 +292,17 @@ return;
}
}
}
if (saved != 2)
printf ("WARNING: didn't find both faces for a saved edge\n");
else
{
for (i=0 ; i<2 ; i++)
{ // remove this edge
else {
for (i = 0; i < 2; i++) { // remove this edge
df = found[i];
j = foundj[i];
for (j++ ; j<df->numedges ; j++)
bsp->surfedges[df->firstedge+j-1] =
bsp->surfedges[df->firstedge+j];
bsp->surfedges[df->firstedge+j-1] = 0;
for (j++; j < df->numedges; j++)
bsp->surfedges[df->firstedge + j - 1] =
bsp->surfedges[df->firstedge + j];
bsp->surfedges[df->firstedge + j - 1] = 0;
df->numedges--;
}
@ -324,74 +311,70 @@ return;
}
}
typedef struct
{
int numedges;
int edges[2];
typedef struct {
int numedges;
int edges[2];
} checkpoint_t;
checkpoint_t checkpoints[MAX_MAP_VERTS];
checkpoint_t checkpoints[MAX_MAP_VERTS];
/*
==============
RemoveColinearEdges
==============
*/
void RemoveColinearEdges (void)
void
RemoveColinearEdges (void)
{
int i,j, v;
int c0, c1, c2, c3;
checkpoint_t *cp;
int i, j, v;
int c0, c1, c2, c3;
checkpoint_t *cp;
// no edges remapped yet
for (i=0 ; i<bsp->numedges ; i++)
for (i = 0; i < bsp->numedges; i++)
edgemapping[i] = i;
// find vertexes that only have two edges
memset (checkpoints, 0, sizeof(checkpoints));
for (i=firstmodeledge ; i<bsp->numedges ; i++)
{
memset (checkpoints, 0, sizeof (checkpoints));
for (i = firstmodeledge; i < bsp->numedges; i++) {
if (!edgefaces[i][0])
continue; // removed
for (j=0 ; j<2 ; j++)
{
continue; // removed
for (j = 0; j < 2; j++) {
v = bsp->edges[i].v[j];
cp = &checkpoints[v];
if (cp->numedges<2)
if (cp->numedges < 2)
cp->edges[cp->numedges] = i;
cp->numedges++;
}
}
// if a vertex only has two edges and they are colinear, it can be removed
c0 = c1 = c2 = c3 = 0;
for (i=0 ; i<bsp->numvertexes ; i++)
{
for (i = 0; i < bsp->numvertexes; i++) {
cp = &checkpoints[i];
switch (cp->numedges)
{
case 0:
c0++;
break;
case 1:
c1++;
break;
case 2:
c2++;
HealEdges (cp->edges[0], cp->edges[1]);
break;
default:
c3++;
break;
switch (cp->numedges) {
case 0:
c0++;
break;
case 1:
c1++;
break;
case 2:
c2++;
HealEdges (cp->edges[0], cp->edges[1]);
break;
default:
c3++;
break;
}
}
// qprintf ("%5i c0\n", c0);
// qprintf ("%5i c1\n", c1);
// qprintf ("%5i c2\n", c2);
// qprintf ("%5i c3+\n", c3);
// qprintf ("%5i c0\n", c0);
// qprintf ("%5i c1\n", c1);
// qprintf ("%5i c2\n", c2);
// qprintf ("%5i c3+\n", c3);
qprintf ("%5i deges removed by tjunction healing\n", c2);
}
@ -400,22 +383,23 @@ void RemoveColinearEdges (void)
CountRealNumbers
==============
*/
void CountRealNumbers (void)
void
CountRealNumbers (void)
{
int i;
int c;
qprintf ("%5i regions\n", bsp->numfaces-firstmodelface);
int i;
int c;
qprintf ("%5i regions\n", bsp->numfaces - firstmodelface);
c = 0;
for (i=firstmodelface ; i<bsp->numfaces ; i++)
for (i = firstmodelface; i < bsp->numfaces; i++)
c += bsp->faces[i].numedges;
qprintf ("%5i real marksurfaces\n", c);
c = 0;
for (i=firstmodeledge ; i<bsp->numedges ; i++)
for (i = firstmodeledge; i < bsp->numedges; i++)
if (edgefaces[i][0])
c++; // not removed
c++; // not removed
qprintf ("%5i real edges\n", c);
}
@ -427,23 +411,23 @@ void CountRealNumbers (void)
GrowNodeRegion_r
==============
*/
void GrowNodeRegion_r (node_t *node)
void
GrowNodeRegion_r (node_t * node)
{
dface_t *r;
face_t *f;
int i;
dface_t *r;
face_t *f;
int i;
if (node->planenum == PLANENUM_LEAF)
return;
node->firstface = bsp->numfaces;
for (f=node->faces ; f ; f=f->next)
{
// if (f->outputnumber != -1)
// continue; // allready grown into an earlier region
// emit a region
for (f = node->faces; f; f = f->next) {
// if (f->outputnumber != -1)
// continue; // allready grown into an earlier region
// emit a region
if (bsp->numfaces == MAX_MAP_FACES)
Sys_Error ("MAX_MAP_FACES");
@ -453,26 +437,25 @@ void GrowNodeRegion_r (node_t *node)
r->planenum = node->outputplanenum;
r->side = f->planeside;
r->texinfo = f->texturenum;
for (i=0 ; i<MAXLIGHTMAPS ; i++)
for (i = 0; i < MAXLIGHTMAPS; i++)
r->styles[i] = 255;
r->lightofs = -1;
// add the face and mergable neighbors to it
// add the face and mergable neighbors to it
#if 0
ClearRegionSize ();
AddFaceToRegionSize (f);
RecursiveGrowRegion (r, f);
#endif
r->firstedge = firstedge = bsp->numsurfedges;
for (i=0 ; i<f->numpoints ; i++)
{
for (i = 0; i < f->numpoints; i++) {
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
bsp->surfedges[bsp->numsurfedges] = f->edges[i];
bsp->numsurfedges++;
}
r->numedges = bsp->numsurfedges - r->firstedge;
bsp->numfaces++;
@ -490,12 +473,13 @@ void GrowNodeRegion_r (node_t *node)
GrowNodeRegions
==============
*/
void GrowNodeRegions (node_t *headnode)
void
GrowNodeRegions (node_t * headnode)
{
qprintf ("---- GrowRegions ----\n");
GrowNodeRegion_r (headnode);
//RemoveColinearEdges ();
CountRealNumbers ();
}
@ -521,16 +505,3 @@ for all faces
===============================================================================
*/

View file

@ -28,13 +28,13 @@
#include "bsp5.h"
int leaffaces;
int nodefaces;
int splitnodes;
int leaffaces;
int nodefaces;
int splitnodes;
int c_solid, c_empty, c_water;
int c_solid, c_empty, c_water;
qboolean usemidsplit;
qboolean usemidsplit;
//============================================================================
@ -45,58 +45,51 @@ FaceSide
For BSP hueristic
==================
*/
int FaceSide (face_t *in, plane_t *split)
int
FaceSide (face_t * in, plane_t *split)
{
int frontcount, backcount;
vec_t dot;
int i;
vec_t *p;
int frontcount, backcount;
vec_t dot;
int i;
vec_t *p;
frontcount = backcount = 0;
// axial planes are fast
if (split->type < 3)
for (i=0, p = in->pts[0]+split->type ; i<in->numpoints ; i++, p+=3)
{
if (*p > split->dist + ON_EPSILON)
{
for (i = 0, p = in->pts[0] + split->type; i < in->numpoints;
i++, p += 3) {
if (*p > split->dist + ON_EPSILON) {
if (backcount)
return SIDE_ON;
frontcount = 1;
}
else if (*p < split->dist - ON_EPSILON)
{
} else if (*p < split->dist - ON_EPSILON) {
if (frontcount)
return SIDE_ON;
backcount = 1;
}
}
else
} else
// sloping planes take longer
for (i=0, p = in->pts[0] ; i<in->numpoints ; i++, p+=3)
{
for (i = 0, p = in->pts[0]; i < in->numpoints; i++, p += 3) {
dot = DotProduct (p, split->normal);
dot -= split->dist;
if (dot > ON_EPSILON)
{
if (dot > ON_EPSILON) {
if (backcount)
return SIDE_ON;
frontcount = 1;
}
else if (dot < -ON_EPSILON)
{
} else if (dot < -ON_EPSILON) {
if (frontcount)
return SIDE_ON;
backcount = 1;
}
}
if (!frontcount)
return SIDE_BACK;
if (!backcount)
return SIDE_FRONT;
return SIDE_ON;
}
@ -107,66 +100,62 @@ ChooseMidPlaneFromList
The clipping hull BSP doesn't worry about avoiding splits
==================
*/
surface_t *ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs)
surface_t *
ChooseMidPlaneFromList (surface_t * surfaces, vec3_t mins, vec3_t maxs)
{
int j,l;
surface_t *p, *bestsurface;
vec_t bestvalue, value, dist;
plane_t *plane;
int j, l;
surface_t *p, *bestsurface;
vec_t bestvalue, value, dist;
plane_t *plane;
//
// pick the plane that splits the least
//
bestvalue = 6*8192*8192;
bestvalue = 6 * 8192 * 8192;
bestsurface = NULL;
for (p=surfaces ; p ; p=p->next)
{
for (p = surfaces; p; p = p->next) {
if (p->onnode)
continue;
plane = &planes[p->planenum];
// check for axis aligned surfaces
// check for axis aligned surfaces
l = plane->type;
if (l > PLANE_Z)
continue;
//
// calculate the split metric along axis l, smaller values are better
//
//
// calculate the split metric along axis l, smaller values are better
//
value = 0;
dist = plane->dist * plane->normal[l];
for (j=0 ; j<3 ; j++)
{
if (j == l)
{
value += (maxs[l]-dist)*(maxs[l]-dist);
value += (dist-mins[l])*(dist-mins[l]);
}
else
value += 2*(maxs[j]-mins[j])*(maxs[j]-mins[j]);
for (j = 0; j < 3; j++) {
if (j == l) {
value += (maxs[l] - dist) * (maxs[l] - dist);
value += (dist - mins[l]) * (dist - mins[l]);
} else
value += 2 * (maxs[j] - mins[j]) * (maxs[j] - mins[j]);
}
if (value > bestvalue)
continue;
//
// currently the best!
//
//
// currently the best!
//
bestvalue = value;
bestsurface = p;
}
if (!bestsurface)
{
for (p=surfaces ; p ; p=p->next)
if (!bestsurface) {
for (p = surfaces; p; p = p->next)
if (!p->onnode)
return p; // first valid surface
return p; // first valid surface
Sys_Error ("ChooseMidPlaneFromList: no valid planes");
}
return bestsurface;
}
@ -179,23 +168,24 @@ ChoosePlaneFromList
The real BSP hueristic
==================
*/
surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, qboolean usefloors)
surface_t *
ChoosePlaneFromList (surface_t * surfaces, vec3_t mins, vec3_t maxs,
qboolean usefloors)
{
int j,k,l;
surface_t *p, *p2, *bestsurface;
vec_t bestvalue, bestdistribution, value, dist;
plane_t *plane;
face_t *f;
int j, k, l;
surface_t *p, *p2, *bestsurface;
vec_t bestvalue, bestdistribution, value, dist;
plane_t *plane;
face_t *f;
//
// pick the plane that splits the least
//
bestvalue = 99999;
bestsurface = NULL;
bestdistribution = 9e30;
for (p=surfaces ; p ; p=p->next)
{
for (p = surfaces; p; p = p->next) {
if (p->onnode)
continue;
@ -205,22 +195,19 @@ surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, q
if (!usefloors && plane->normal[2] == 1)
continue;
for (p2=surfaces ; p2 ; p2=p2->next)
{
for (p2 = surfaces; p2; p2 = p2->next) {
if (p2 == p)
continue;
if (p2->onnode)
continue;
for (f=p2->faces ; f ; f=f->next)
{
if (FaceSide (f, plane) == SIDE_ON)
{
for (f = p2->faces; f; f = f->next) {
if (FaceSide (f, plane) == SIDE_ON) {
k++;
if (k >= bestvalue)
break;
}
}
if (k > bestvalue)
break;
@ -228,40 +215,37 @@ surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, q
if (k > bestvalue)
continue;
// if equal numbers, axial planes win, then decide on spatial subdivision
if (k < bestvalue || (k == bestvalue && plane->type < PLANE_ANYX) )
{
// check for axis aligned surfaces
// if equal numbers, axial planes win, then decide on spatial
// subdivision
if (k < bestvalue || (k == bestvalue && plane->type < PLANE_ANYX)) {
// check for axis aligned surfaces
l = plane->type;
if (l <= PLANE_Z)
{ // axial aligned
//
// calculate the split metric along axis l
//
if (l <= PLANE_Z) { // axial aligned
//
//
// calculate the split metric along axis l
//
value = 0;
for (j=0 ; j<3 ; j++)
{
if (j == l)
{
for (j = 0; j < 3; j++) {
if (j == l) {
dist = plane->dist * plane->normal[l];
value += (maxs[l]-dist)*(maxs[l]-dist);
value += (dist-mins[l])*(dist-mins[l]);
}
else
value += 2*(maxs[j]-mins[j])*(maxs[j]-mins[j]);
value += (maxs[l] - dist) * (maxs[l] - dist);
value += (dist - mins[l]) * (dist - mins[l]);
} else
value += 2 * (maxs[j] - mins[j]) * (maxs[j] - mins[j]);
}
if (value > bestdistribution && k == bestvalue)
continue;
bestdistribution = value;
}
//
// currently the best!
//
//
// currently the best!
//
bestvalue = k;
bestsurface = p;
}
@ -281,57 +265,55 @@ Selects a surface from a linked list of surfaces to split the group on
returns NULL if the surface list can not be divided any more (a leaf)
==================
*/
surface_t *SelectPartition (surface_t *surfaces)
surface_t *
SelectPartition (surface_t * surfaces)
{
int i,j;
vec3_t mins, maxs;
surface_t *p, *bestsurface;
int i, j;
vec3_t mins, maxs;
surface_t *p, *bestsurface;
//
// count onnode surfaces
//
i = 0;
bestsurface = NULL;
for (p=surfaces ; p ; p=p->next)
if (!p->onnode)
{
for (p = surfaces; p; p = p->next)
if (!p->onnode) {
i++;
bestsurface = p;
}
if (i==0)
if (i == 0)
return NULL;
if (i==1)
return bestsurface; // this is a final split
if (i == 1)
return bestsurface; // this is a final split
//
// calculate a bounding box of the entire surfaceset
//
for (i=0 ; i<3 ; i++)
{
for (i = 0; i < 3; i++) {
mins[i] = 99999;
maxs[i] = -99999;
}
for (p=surfaces ; p ; p=p->next)
for (j=0 ; j<3 ; j++)
{
for (p = surfaces; p; p = p->next)
for (j = 0; j < 3; j++) {
if (p->mins[j] < mins[j])
mins[j] = p->mins[j];
if (p->maxs[j] > maxs[j])
maxs[j] = p->maxs[j];
}
if (usemidsplit) // do fast way for clipping hull
if (usemidsplit) // do fast way for clipping hull
return ChooseMidPlaneFromList (surfaces, mins, maxs);
// do slow way to save poly splits for drawing hull
#if 0
bestsurface = ChoosePlaneFromList (surfaces, mins, maxs, false);
if (bestsurface)
if (bestsurface)
return bestsurface;
#endif
#endif
return ChoosePlaneFromList (surfaces, mins, maxs, true);
}
@ -344,30 +326,28 @@ CalcSurfaceInfo
Calculates the bounding box
=================
*/
void CalcSurfaceInfo (surface_t *surf)
void
CalcSurfaceInfo (surface_t * surf)
{
int i,j;
face_t *f;
int i, j;
face_t *f;
if (!surf->faces)
Sys_Error ("CalcSurfaceInfo: surface without a face");
//
// calculate a bounding box
//
for (i=0 ; i<3 ; i++)
{
for (i = 0; i < 3; i++) {
surf->mins[i] = 99999;
surf->maxs[i] = -99999;
}
for (f=surf->faces ; f ; f=f->next)
{
if (f->contents[0] >= 0 || f->contents[1] >= 0)
Sys_Error ("Bad contents");
for (i=0 ; i<f->numpoints ; i++)
for (j=0 ; j<3 ; j++)
{
for (f = surf->faces; f; f = f->next) {
if (f->contents[0] >= 0 || f->contents[1] >= 0)
Sys_Error ("Bad contents");
for (i = 0; i < f->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])
@ -383,45 +363,42 @@ Sys_Error ("Bad contents");
DividePlane
==================
*/
void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **back)
void
DividePlane (surface_t * in, plane_t *split, surface_t ** front,
surface_t ** back)
{
face_t *facet, *next;
face_t *frontlist, *backlist;
face_t *frontfrag, *backfrag;
surface_t *news;
plane_t *inplane;
face_t *facet, *next;
face_t *frontlist, *backlist;
face_t *frontfrag, *backfrag;
surface_t *news;
plane_t *inplane;
inplane = &planes[in->planenum];
// parallel case is easy
if (VectorCompare (inplane->normal, split->normal))
{
if (VectorCompare (inplane->normal, split->normal)) {
// check for exactly on node
if (inplane->dist == split->dist)
{ // divide the facets to the front and back sides
if (inplane->dist == split->dist) { // divide the facets to the front
// and back sides
news = AllocSurface ();
*news = *in;
facet=in->faces;
facet = in->faces;
in->faces = NULL;
news->faces = NULL;
in->onnode = news->onnode = true;
for ( ; facet ; facet=next)
{
for (; facet; facet = next) {
next = facet->next;
if (facet->planeside == 1)
{
if (facet->planeside == 1) {
facet->next = news->faces;
news->faces = facet;
}
else
{
} else {
facet->next = in->faces;
in->faces = facet;
}
}
if (in->faces)
*front = in;
else
@ -432,72 +409,62 @@ void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **
*back = NULL;
return;
}
if (inplane->dist > split->dist)
{
if (inplane->dist > split->dist) {
*front = in;
*back = NULL;
}
else
{
} else {
*front = NULL;
*back = in;
}
return;
}
// do a real split. may still end up entirely on one side
// OPTIMIZE: use bounding box for fast test
frontlist = NULL;
backlist = NULL;
for (facet = in->faces ; facet ; facet = next)
{
for (facet = in->faces; facet; facet = next) {
next = facet->next;
SplitFace (facet, split, &frontfrag, &backfrag);
if (frontfrag)
{
if (frontfrag) {
frontfrag->next = frontlist;
frontlist = frontfrag;
}
if (backfrag)
{
if (backfrag) {
backfrag->next = backlist;
backlist = backfrag;
}
}
// if nothing actually got split, just move the in plane
if (frontlist == NULL)
{
if (frontlist == NULL) {
*front = NULL;
*back = in;
in->faces = backlist;
return;
}
if (backlist == NULL)
{
if (backlist == NULL) {
*front = in;
*back = NULL;
in->faces = frontlist;
return;
}
// stuff got split, so allocate one new plane and reuse in
news = AllocSurface ();
*news = *in;
news->faces = backlist;
*back = news;
in->faces = frontlist;
*front = in;
// recalc bboxes and flags
CalcSurfaceInfo (news);
CalcSurfaceInfo (in);
CalcSurfaceInfo (in);
}
/*
@ -505,7 +472,8 @@ void DividePlane (surface_t *in, plane_t *split, surface_t **front, surface_t **
DivideNodeBounds
==================
*/
void DivideNodeBounds (node_t *node, plane_t *split)
void
DivideNodeBounds (node_t * node, plane_t *split)
{
VectorCopy (node->mins, node->children[0]->mins);
VectorCopy (node->mins, node->children[1]->mins);
@ -517,7 +485,7 @@ void DivideNodeBounds (node_t *node, plane_t *split)
return;
node->children[0]->mins[split->type] =
node->children[1]->maxs[split->type] = split->dist;
node->children[1]->maxs[split->type] = split->dist;
}
/*
@ -528,21 +496,20 @@ Determines the contents of the leaf and creates the final list of
original faces that have some fragment inside this leaf
==================
*/
void LinkConvexFaces (surface_t *planelist, node_t *leafnode)
void
LinkConvexFaces (surface_t * planelist, node_t * leafnode)
{
face_t *f, *next;
surface_t *surf, *pnext;
int i, count;
face_t *f, *next;
surface_t *surf, *pnext;
int i, count;
leafnode->faces = NULL;
leafnode->contents = 0;
leafnode->planenum = -1;
count = 0;
for ( surf = planelist ; surf ; surf = surf->next)
{
for (f = surf->faces ; f ; f=f->next)
{
for (surf = planelist; surf; surf = surf->next) {
for (f = surf->faces; f; f = f->next) {
count++;
if (!leafnode->contents)
leafnode->contents = f->contents[0];
@ -553,36 +520,33 @@ void LinkConvexFaces (surface_t *planelist, node_t *leafnode)
if (!leafnode->contents)
leafnode->contents = CONTENTS_SOLID;
switch (leafnode->contents)
{
case CONTENTS_EMPTY:
c_empty++;
break;
case CONTENTS_SOLID:
c_solid++;
break;
case CONTENTS_WATER:
case CONTENTS_SLIME:
case CONTENTS_LAVA:
case CONTENTS_SKY:
c_water++;
break;
default:
Sys_Error ("LinkConvexFaces: bad contents number");
switch (leafnode->contents) {
case CONTENTS_EMPTY:
c_empty++;
break;
case CONTENTS_SOLID:
c_solid++;
break;
case CONTENTS_WATER:
case CONTENTS_SLIME:
case CONTENTS_LAVA:
case CONTENTS_SKY:
c_water++;
break;
default:
Sys_Error ("LinkConvexFaces: bad contents number");
}
//
// write the list of faces, and free the originals
//
leaffaces += count;
leafnode->markfaces = malloc(sizeof(face_t *)*(count+1));
leafnode->markfaces = malloc (sizeof (face_t *) * (count + 1));
i = 0;
for ( surf = planelist ; surf ; surf = pnext)
{
for (surf = planelist; surf; surf = pnext) {
pnext = surf->next;
for (f = surf->faces ; f ; f=next)
{
for (f = surf->faces; f; f = next) {
next = f->next;
leafnode->markfaces[i] = f->original;
i++;
@ -590,7 +554,7 @@ void LinkConvexFaces (surface_t *planelist, node_t *leafnode)
}
FreeSurface (surf);
}
leafnode->markfaces[i] = NULL; // sentinal
leafnode->markfaces[i] = NULL; // sentinal
}
@ -601,18 +565,18 @@ LinkNodeFaces
Returns a duplicated list of all faces on surface
==================
*/
face_t *LinkNodeFaces (surface_t *surface)
face_t *
LinkNodeFaces (surface_t * surface)
{
face_t *f, *new, **prevptr;
face_t *list;
face_t *f, *new, **prevptr;
face_t *list;
list = NULL;
// subdivide
prevptr = &surface->faces;
while (1)
{
while (1) {
f = *prevptr;
if (!f)
break;
@ -622,8 +586,7 @@ face_t *LinkNodeFaces (surface_t *surface)
}
// copy
for (f=surface->faces ; f ; f=f->next)
{
for (f = surface->faces; f; f = f->next) {
nodefaces++;
new = AllocFace ();
*new = *f;
@ -641,21 +604,21 @@ face_t *LinkNodeFaces (surface_t *surface)
PartitionSurfaces
==================
*/
void PartitionSurfaces (surface_t *surfaces, node_t *node)
void
PartitionSurfaces (surface_t * surfaces, node_t * node)
{
surface_t *split, *p, *next;
surface_t *frontlist, *backlist;
surface_t *frontfrag, *backfrag;
plane_t *splitplane;
surface_t *split, *p, *next;
surface_t *frontlist, *backlist;
surface_t *frontfrag, *backfrag;
plane_t *splitplane;
split = SelectPartition (surfaces);
if (!split)
{ // this is a leaf node
if (!split) { // this is a leaf node
node->planenum = PLANENUM_LEAF;
LinkConvexFaces (surfaces, node);
return;
}
splitnodes++;
node->faces = LinkNodeFaces (split);
node->children[0] = AllocNode ();
@ -663,7 +626,7 @@ void PartitionSurfaces (surface_t *surfaces, node_t *node)
node->planenum = split->planenum;
splitplane = &planes[split->planenum];
DivideNodeBounds (node, splitplane);
@ -672,28 +635,24 @@ void PartitionSurfaces (surface_t *surfaces, node_t *node)
//
frontlist = NULL;
backlist = NULL;
for (p=surfaces ; p ; p=next)
{
for (p = surfaces; p; p = next) {
next = p->next;
DividePlane (p, splitplane, &frontfrag, &backfrag);
if (frontfrag && backfrag)
{
// the plane was split, which may expose oportunities to merge
// adjacent faces into a single face
// MergePlaneFaces (frontfrag);
// MergePlaneFaces (backfrag);
if (frontfrag && backfrag) {
// the plane was split, which may expose oportunities to merge
// adjacent faces into a single face
// MergePlaneFaces (frontfrag);
// MergePlaneFaces (backfrag);
}
if (frontfrag)
{
if (frontfrag) {
if (!frontfrag->faces)
Sys_Error ("surface with no faces");
frontfrag->next = frontlist;
frontlist = frontfrag;
}
if (backfrag)
{
if (backfrag) {
if (!backfrag->faces)
Sys_Error ("surface with no faces");
backfrag->next = backlist;
@ -710,11 +669,12 @@ void PartitionSurfaces (surface_t *surfaces, node_t *node)
DrawSurface
==================
*/
void DrawSurface (surface_t *surf)
void
DrawSurface (surface_t * surf)
{
face_t *f;
for (f=surf->faces ; f ; f=f->next)
face_t *f;
for (f = surf->faces; f; f = f->next)
Draw_DrawFace (f);
}
@ -723,11 +683,11 @@ void DrawSurface (surface_t *surf)
DrawSurfaceList
==================
*/
void DrawSurfaceList (surface_t *surf)
{
void
DrawSurfaceList (surface_t * surf)
{
Draw_ClearWindow ();
while (surf)
{
while (surf) {
DrawSurface (surf);
surf = surf->next;
}
@ -738,25 +698,25 @@ void DrawSurfaceList (surface_t *surf)
SolidBSP
==================
*/
node_t *SolidBSP (surface_t *surfhead, qboolean midsplit)
node_t *
SolidBSP (surface_t * surfhead, qboolean midsplit)
{
int i;
node_t *headnode;
int i;
node_t *headnode;
qprintf ("----- SolidBSP -----\n");
headnode = AllocNode ();
usemidsplit = midsplit;
//
// calculate a bounding box for the entire model
//
for (i=0 ; i<3 ; i++)
{
for (i = 0; i < 3; i++) {
headnode->mins[i] = brushset->mins[i] - SIDESPACE;
headnode->maxs[i] = brushset->maxs[i] + SIDESPACE;
}
//
// recursively partition everything
//
@ -771,10 +731,9 @@ node_t *SolidBSP (surface_t *surfhead, qboolean midsplit)
qprintf ("%5i split nodes\n", splitnodes);
qprintf ("%5i solid leafs\n", c_solid);
qprintf ("%5i empty leafs\n", c_empty);
qprintf ("%5i water leafs\n", c_water);
qprintf ("%5i leaffaces\n",leaffaces);
qprintf ("%5i water leafs\n", c_water);
qprintf ("%5i leaffaces\n", leaffaces);
qprintf ("%5i nodefaces\n", nodefaces);
return headnode;
}

View file

@ -29,7 +29,7 @@
#include "bsp5.h"
surface_t newcopy_t;
surface_t newcopy_t;
/*
a surface has all of the faces that could be drawn on a given plane
@ -38,7 +38,7 @@ the outside filling stage can remove some of them so a better bsp can be generat
*/
int subdivides;
int subdivides;
/*
@ -49,48 +49,46 @@ If the face is >256 in either texture direction, carve a valid sized
piece off and insert the remainder in the next link
===============
*/
void SubdivideFace (face_t *f, face_t **prevptr)
void
SubdivideFace (face_t * f, face_t ** prevptr)
{
float mins, maxs;
vec_t v;
int axis, i;
plane_t plane;
face_t *front, *back, *next;
texinfo_t *tex;
float mins, maxs;
vec_t v;
int axis, i;
plane_t plane;
face_t *front, *back, *next;
texinfo_t *tex;
// special (non-surface cached) faces don't need subdivision
tex = &bsp->texinfo[f->texturenum];
if ( tex->flags & TEX_SPECIAL)
if (tex->flags & TEX_SPECIAL)
return;
for (axis = 0 ; axis < 2 ; axis++)
{
while (1)
{
for (axis = 0; axis < 2; axis++) {
while (1) {
mins = 9999;
maxs = -9999;
for (i=0 ; i<f->numpoints ; i++)
{
for (i = 0; i < f->numpoints; i++) {
v = DotProduct (f->pts[i], tex->vecs[axis]);
if (v < mins)
mins = v;
if (v > maxs)
maxs = v;
}
if (maxs - mins <= subdivide_size)
break;
// split it
// split it
subdivides++;
VectorCopy (tex->vecs[axis], plane.normal);
v = VectorLength (plane.normal);
VectorNormalize (plane.normal);
plane.dist = (mins + subdivide_size - 16)/v;
VectorNormalize (plane.normal);
plane.dist = (mins + subdivide_size - 16) / v;
next = f->next;
SplitFace (f, &plane, &front, &back);
if (!front || !back)
@ -109,20 +107,19 @@ void SubdivideFace (face_t *f, face_t **prevptr)
SubdivideFaces
================
*/
void SubdivideFaces (surface_t *surfhead)
void
SubdivideFaces (surface_t * surfhead)
{
surface_t *surf;
face_t *f , **prevptr;
surface_t *surf;
face_t *f, **prevptr;
qprintf ("--- SubdivideFaces ---\n");
subdivides = 0;
for (surf = surfhead ; surf ; surf=surf->next)
{
for (surf = surfhead; surf; surf = surf->next) {
prevptr = &surf->faces;
while (1)
{
while (1) {
f = *prevptr;
if (!f)
break;
@ -133,7 +130,7 @@ void SubdivideFaces (surface_t *surfhead)
}
qprintf ("%i faces added by subdivision\n", subdivides);
}
@ -147,36 +144,30 @@ have inside faces.
=============================================================================
*/
void GatherNodeFaces_r (node_t *node)
void
GatherNodeFaces_r (node_t * node)
{
face_t *f, *next;
if (node->planenum != PLANENUM_LEAF)
{
face_t *f, *next;
if (node->planenum != PLANENUM_LEAF) {
//
// decision node
//
for (f=node->faces ; f ; f=next)
{
for (f = node->faces; f; f = next) {
next = f->next;
if (!f->numpoints)
{ // face was removed outside
if (!f->numpoints) { // face was removed outside
FreeFace (f);
}
else
{
} else {
f->next = validfaces[f->planenum];
validfaces[f->planenum] = f;
}
}
GatherNodeFaces_r (node->children[0]);
GatherNodeFaces_r (node->children[1]);
free (node);
}
else
{
} else {
//
// leaf node
//
@ -190,63 +181,63 @@ GatherNodeFaces
================
*/
surface_t *GatherNodeFaces (node_t *headnode)
surface_t *
GatherNodeFaces (node_t * headnode)
{
memset (validfaces, 0, sizeof(validfaces));
memset (validfaces, 0, sizeof (validfaces));
GatherNodeFaces_r (headnode);
return BuildSurfaces ();
return BuildSurfaces ();
}
//===========================================================================
typedef struct hashvert_s
{
struct hashvert_s *next;
vec3_t point;
int num;
int numplanes; // for corner determination
int planenums[2];
int numedges;
typedef struct hashvert_s {
struct hashvert_s *next;
vec3_t point;
int num;
int numplanes; // for corner determination
int planenums[2];
int numedges;
} hashvert_t;
#define POINT_EPSILON 0.01
int c_cornerverts;
int c_cornerverts;
hashvert_t hvertex[MAX_MAP_VERTS];
hashvert_t *hvert_p;
hashvert_t hvertex[MAX_MAP_VERTS];
hashvert_t *hvert_p;
face_t *edgefaces[MAX_MAP_EDGES][2];
int firstmodeledge = 1;
int firstmodelface;
face_t *edgefaces[MAX_MAP_EDGES][2];
int firstmodeledge = 1;
int firstmodelface;
//============================================================================
#define NUM_HASH 4096
hashvert_t *hashverts[NUM_HASH];
hashvert_t *hashverts[NUM_HASH];
static vec3_t hash_min, hash_scale;
static vec3_t hash_min, hash_scale;
static void InitHash (void)
static void
InitHash (void)
{
vec3_t size;
vec_t volume;
vec_t scale;
int newsize[2];
int i;
memset (hashverts, 0, sizeof(hashverts));
vec3_t size;
vec_t volume;
vec_t scale;
int newsize[2];
int i;
for (i=0 ; i<3 ; i++)
{
memset (hashverts, 0, sizeof (hashverts));
for (i = 0; i < 3; i++) {
hash_min[i] = -8000;
size[i] = 16000;
}
volume = size[0]*size[1];
scale = sqrt(volume / NUM_HASH);
volume = size[0] * size[1];
scale = sqrt (volume / NUM_HASH);
newsize[0] = size[0] / scale;
newsize[1] = size[1] / scale;
@ -254,17 +245,18 @@ static void InitHash (void)
hash_scale[0] = newsize[0] / size[0];
hash_scale[1] = newsize[1] / size[1];
hash_scale[2] = newsize[1];
hvert_p = hvertex;
}
static unsigned HashVec (vec3_t vec)
static unsigned
HashVec (vec3_t vec)
{
unsigned h;
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
unsigned h;
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
+ hash_scale[1] * (vec[1] - hash_min[1]);
if ( h >= NUM_HASH)
if (h >= NUM_HASH)
return NUM_HASH - 1;
return h;
}
@ -275,33 +267,31 @@ static unsigned HashVec (vec3_t vec)
GetVertex
=============
*/
int GetVertex (vec3_t in, int planenum)
int
GetVertex (vec3_t in, int planenum)
{
int h;
int i;
hashvert_t *hv;
vec3_t vert;
for (i=0 ; i<3 ; i++)
{
if ( fabs(in[i] - (int) (in[i] + 0.5)) < 0.001)
int h;
int i;
hashvert_t *hv;
vec3_t vert;
for (i = 0; i < 3; i++) {
if (fabs (in[i] - (int) (in[i] + 0.5)) < 0.001)
vert[i] = (int) (in[i] + 0.5);
else
vert[i] = in[i];
}
h = HashVec (vert);
for (hv=hashverts[h] ; hv ; hv=hv->next)
{
if ( fabs(hv->point[0]-vert[0])<POINT_EPSILON
&& fabs(hv->point[1]-vert[1])<POINT_EPSILON
&& fabs(hv->point[2]-vert[2])<POINT_EPSILON )
{
for (hv = hashverts[h]; hv; hv = hv->next) {
if (fabs (hv->point[0] - vert[0]) < POINT_EPSILON
&& fabs (hv->point[1] - vert[1]) < POINT_EPSILON
&& fabs (hv->point[2] - vert[2]) < POINT_EPSILON) {
hv->numedges++;
if (hv->numplanes == 3)
return hv->num; // allready known to be a corner
for (i=0 ; i<hv->numplanes ; i++)
return hv->num; // allready known to be a corner
for (i = 0; i < hv->numplanes; i++)
if (hv->planenums[i] == planenum)
return hv->num; // allready know this plane
if (hv->numplanes == 2)
@ -312,7 +302,7 @@ int GetVertex (vec3_t in, int planenum)
return hv->num;
}
}
hv = hvert_p;
hv->numedges = 1;
hv->numplanes = 1;
@ -321,10 +311,10 @@ int GetVertex (vec3_t in, int planenum)
hashverts[h] = hv;
VectorCopy (vert, hv->point);
hv->num = bsp->numvertexes;
if (hv->num==MAX_MAP_VERTS)
if (hv->num == MAX_MAP_VERTS)
Sys_Error ("GetVertex: MAX_MAP_VERTS");
hvert_p++;
// emit a vertex
if (bsp->numvertexes == MAX_MAP_VERTS)
Sys_Error ("numvertexes == MAX_MAP_VERTS");
@ -347,32 +337,31 @@ GetEdge
Don't allow four way edges
==================
*/
int c_tryedges;
int c_tryedges;
int GetEdge (vec3_t p1, vec3_t p2, face_t *f)
int
GetEdge (vec3_t p1, vec3_t p2, face_t * f)
{
int v1, v2;
dedge_t *edge;
int i;
int v1, v2;
dedge_t *edge;
int i;
if (!f->contents[0])
Sys_Error ("GetEdge: 0 contents");
c_tryedges++;
c_tryedges++;
v1 = GetVertex (p1, f->planenum);
v2 = GetVertex (p2, f->planenum);
for (i=firstmodeledge ; i < bsp->numedges ; i++)
{
for (i = firstmodeledge; i < bsp->numedges; i++) {
edge = &bsp->edges[i];
if (v1 == edge->v[1] && v2 == edge->v[0]
&& !edgefaces[i][1]
&& edgefaces[i][0]->contents[0] == f->contents[0])
{
&& !edgefaces[i][1]
&& edgefaces[i][0]->contents[0] == f->contents[0]) {
edgefaces[i][1] = f;
return -i;
}
}
// emit an edge
if (bsp->numedges == MAX_MAP_EDGES)
Sys_Error ("numedges == MAX_MAP_EDGES");
@ -381,7 +370,7 @@ int GetEdge (vec3_t p1, vec3_t p2, face_t *f)
edge->v[0] = v1;
edge->v[1] = v2;
edgefaces[i][0] = f;
return i;
}
@ -391,17 +380,18 @@ int GetEdge (vec3_t p1, vec3_t p2, face_t *f)
FindFaceEdges
==================
*/
void FindFaceEdges (face_t *face)
void
FindFaceEdges (face_t * face)
{
int i;
int i;
face->outputnumber = -1;
face->outputnumber = -1;
if (face->numpoints > MAXEDGES)
Sys_Error ("WriteFace: %i points", face->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 < face->numpoints; i++)
face->edges[i] = GetEdge
(face->pts[i], face->pts[(i + 1) % face->numpoints], face);
}
/*
@ -410,14 +400,14 @@ CheckVertexes
// debugging
=============
*/
void CheckVertexes (void)
void
CheckVertexes (void)
{
int cb, c0, c1, c2, c3;
hashvert_t *hv;
int cb, c0, c1, c2, c3;
hashvert_t *hv;
cb = c0 = c1 = c2 = c3 = 0;
for (hv=hvertex ; hv!=hvert_p ; hv++)
{
for (hv = hvertex; hv != hvert_p; hv++) {
if (hv->numedges < 0 || hv->numedges & 1)
cb++;
else if (!hv->numedges)
@ -429,7 +419,7 @@ void CheckVertexes (void)
else
c3++;
}
qprintf ("%5i bad edge points\n", cb);
qprintf ("%5i 0 edge points\n", c0);
qprintf ("%5i 2 edge points\n", c1);
@ -443,54 +433,52 @@ CheckEdges
// debugging
=============
*/
void CheckEdges (void)
void
CheckEdges (void)
{
dedge_t *edge;
int i;
dvertex_t *d1, *d2;
face_t *f1, *f2;
int c_nonconvex;
int c_multitexture;
dedge_t *edge;
int i;
dvertex_t *d1, *d2;
face_t *f1, *f2;
int c_nonconvex;
int c_multitexture;
c_nonconvex = c_multitexture = 0;
// CheckVertexes ();
for (i=1 ; i < bsp->numedges ; i++)
{
// CheckVertexes ();
for (i = 1; i < bsp->numedges; i++) {
edge = &bsp->edges[i];
if (!edgefaces[i][1])
{
if (!edgefaces[i][1]) {
d1 = &bsp->vertexes[edge->v[0]];
d2 = &bsp->vertexes[edge->v[1]];
qprintf ("unshared edge at: (%8.2f, %8.2f, %8.2f) (%8.2f, %8.2f, %8.2f)\n",d1->point[0], d1->point[1], d1->point[2], d2->point[0], d2->point[1], d2->point[2]);
}
else
{
qprintf
("unshared edge at: (%8.2f, %8.2f, %8.2f) (%8.2f, %8.2f, %8.2f)\n",
d1->point[0], d1->point[1], d1->point[2], d2->point[0],
d2->point[1], d2->point[2]);
} else {
f1 = edgefaces[i][0];
f2 = edgefaces[i][1];
if (f1->planeside != f2->planeside)
continue;
if (f1->planenum != f2->planenum)
continue;
// on the same plane, might be discardable
if (f1->texturenum == f2->texturenum)
{
hvertex[edge->v[0]].numedges-=2;
hvertex[edge->v[1]].numedges-=2;
if (f1->texturenum == f2->texturenum) {
hvertex[edge->v[0]].numedges -= 2;
hvertex[edge->v[1]].numedges -= 2;
c_nonconvex++;
}
else
} else
c_multitexture++;
}
}
// qprintf ("%5i edges\n", i);
// qprintf ("%5i c_nonconvex\n", c_nonconvex);
// qprintf ("%5i c_multitexture\n", c_multitexture);
// qprintf ("%5i edges\n", i);
// qprintf ("%5i c_nonconvex\n", c_nonconvex);
// qprintf ("%5i c_multitexture\n", c_multitexture);
// CheckVertexes ();
// CheckVertexes ();
}
@ -499,16 +487,17 @@ void CheckEdges (void)
MakeFaceEdges_r
================
*/
void MakeFaceEdges_r (node_t *node)
void
MakeFaceEdges_r (node_t * node)
{
face_t *f;
face_t *f;
if (node->planenum == PLANENUM_LEAF)
return;
for (f=node->faces ; f ; f=f->next)
for (f = node->faces; f; f = f->next)
FindFaceEdges (f);
MakeFaceEdges_r (node->children[0]);
MakeFaceEdges_r (node->children[1]);
}
@ -518,21 +507,21 @@ void MakeFaceEdges_r (node_t *node)
MakeFaceEdges
================
*/
void MakeFaceEdges (node_t *headnode)
void
MakeFaceEdges (node_t * headnode)
{
qprintf ("----- MakeFaceEdges -----\n");
InitHash ();
c_tryedges = 0;
c_cornerverts = 0;
MakeFaceEdges_r (headnode);
// CheckEdges ();
// CheckEdges ();
GrowNodeRegions (headnode);
firstmodeledge = bsp->numedges;
firstmodelface = bsp->numfaces;
}

View file

@ -28,62 +28,63 @@
#include "bsp5.h"
typedef struct wvert_s
{
vec_t t;
typedef struct wvert_s {
vec_t t;
struct wvert_s *prev, *next;
} wvert_t;
typedef struct wedge_s
{
typedef struct wedge_s {
struct wedge_s *next;
vec3_t dir;
vec3_t origin;
wvert_t head;
vec3_t dir;
vec3_t origin;
wvert_t head;
} wedge_t;
int numwedges, numwverts;
int tjuncs;
int tjuncfaces;
int numwedges, numwverts;
int tjuncs;
int tjuncfaces;
#define MAXWVERTS 0x20000
#define MAXWEDGES 0x10000
wvert_t wverts[MAXWVERTS];
wedge_t wedges[MAXWEDGES];
wvert_t wverts[MAXWVERTS];
wedge_t wedges[MAXWEDGES];
void PrintFace (face_t *f)
void
PrintFace (face_t * f)
{
int i;
for (i=0 ; i<f->numpoints ; i++)
printf ("(%5.2f, %5.2f, %5.2f)\n", f->pts[i][0], f->pts[i][1], f->pts[i][2]);
int i;
for (i = 0; i < f->numpoints; i++)
printf ("(%5.2f, %5.2f, %5.2f)\n", f->pts[i][0], f->pts[i][1],
f->pts[i][2]);
}
//============================================================================
#define NUM_HASH 1024
wedge_t *wedge_hash[NUM_HASH];
wedge_t *wedge_hash[NUM_HASH];
static vec3_t hash_min, hash_scale;
static vec3_t hash_min, hash_scale;
static void InitHash (vec3_t mins, vec3_t maxs)
static void
InitHash (vec3_t mins, vec3_t maxs)
{
vec3_t size;
vec_t volume;
vec_t scale;
int newsize[2];
vec3_t size;
vec_t volume;
vec_t scale;
int newsize[2];
VectorCopy (mins, hash_min);
VectorSubtract (maxs, mins, size);
memset (wedge_hash, 0, sizeof(wedge_hash));
volume = size[0]*size[1];
scale = sqrt(volume / NUM_HASH);
memset (wedge_hash, 0, sizeof (wedge_hash));
volume = size[0] * size[1];
scale = sqrt (volume / NUM_HASH);
newsize[0] = size[0] / scale;
newsize[1] = size[1] / scale;
@ -93,62 +94,59 @@ static void InitHash (vec3_t mins, vec3_t maxs)
hash_scale[2] = newsize[1];
}
static unsigned HashVec (vec3_t vec)
static unsigned
HashVec (vec3_t vec)
{
unsigned h;
unsigned h;
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2]
+ hash_scale[1] * (vec[1] - hash_min[1]);
if ( h >= NUM_HASH)
if (h >= NUM_HASH)
return NUM_HASH - 1;
return h;
}
//============================================================================
void CanonicalVector (vec3_t vec)
void
CanonicalVector (vec3_t vec)
{
VectorNormalize (vec);
if (vec[0] > EQUAL_EPSILON)
return;
else if (vec[0] < -EQUAL_EPSILON)
{
else if (vec[0] < -EQUAL_EPSILON) {
VectorSubtract (vec3_origin, vec, vec);
return;
}
else
} else
vec[0] = 0;
if (vec[1] > EQUAL_EPSILON)
return;
else if (vec[1] < -EQUAL_EPSILON)
{
else if (vec[1] < -EQUAL_EPSILON) {
VectorSubtract (vec3_origin, vec, vec);
return;
}
else
} else
vec[1] = 0;
if (vec[2] > EQUAL_EPSILON)
return;
else if (vec[2] < -EQUAL_EPSILON)
{
else if (vec[2] < -EQUAL_EPSILON) {
VectorSubtract (vec3_origin, vec, vec);
return;
}
else
} else
vec[2] = 0;
Sys_Error ("CanonicalVector: degenerate");
}
wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
wedge_t *
FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
{
vec3_t origin;
vec3_t dir;
wedge_t *w;
vec_t temp;
int h;
vec3_t origin;
vec3_t dir;
wedge_t *w;
vec_t temp;
int h;
VectorSubtract (p2, p1, dir);
CanonicalVector (dir);
@ -157,17 +155,15 @@ wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
VectorMA (p1, -*t1, dir, origin);
if (*t1 > *t2)
{
if (*t1 > *t2) {
temp = *t1;
*t1 = *t2;
*t2 = temp;
}
h = HashVec (origin);
for (w = wedge_hash[h] ; w ; w=w->next)
{
for (w = wedge_hash[h]; w; w = w->next) {
temp = w->origin[0] - origin[0];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
@ -177,7 +173,7 @@ wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
temp = w->origin[2] - origin[2];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
temp = w->dir[0] - dir[0];
if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
continue;
@ -190,15 +186,15 @@ wedge_t *FindEdge (vec3_t p1, vec3_t p2, vec_t *t1, vec_t *t2)
return w;
}
if (numwedges == MAXWEDGES)
Sys_Error ("FindEdge: numwedges == MAXWEDGES");
w = &wedges[numwedges];
numwedges++;
w->next = wedge_hash[h];
wedge_hash[h] = w;
VectorCopy (origin, w->origin);
VectorCopy (dir, w->dir);
w->head.next = w->head.prev = &w->head;
@ -215,27 +211,27 @@ AddVert
*/
#define T_EPSILON 0.01
void AddVert (wedge_t *w, vec_t t)
void
AddVert (wedge_t * w, vec_t t)
{
wvert_t *v, *newv;
wvert_t *v, *newv;
v = w->head.next;
do
{
if (fabs(v->t - t) < T_EPSILON)
do {
if (fabs (v->t - t) < T_EPSILON)
return;
if (v->t > t)
break;
v = v->next;
} while (1);
// insert a new wvert before v
if (numwverts == MAXWVERTS)
Sys_Error ("AddVert: numwverts == MAXWVERTS");
newv = &wverts[numwverts];
numwverts++;
newv->t = t;
newv->next = v;
newv->prev = v->prev;
@ -250,12 +246,13 @@ AddEdge
===============
*/
void AddEdge (vec3_t p1, vec3_t p2)
void
AddEdge (vec3_t p1, vec3_t p2)
{
wedge_t *w;
vec_t t1, t2;
w = FindEdge(p1, p2, &t1, &t2);
wedge_t *w;
vec_t t1, t2;
w = FindEdge (p1, p2, &t1, &t2);
AddVert (w, t1);
AddVert (w, t2);
}
@ -266,14 +263,14 @@ AddFaceEdges
===============
*/
void AddFaceEdges (face_t *f)
void
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]);
int i, j;
for (i = 0; i < f->numpoints; i++) {
j = (i + 1) % f->numpoints;
AddEdge (f->pts[i], f->pts[j]);
}
}
@ -281,26 +278,26 @@ void AddFaceEdges (face_t *f)
//============================================================================
// a specially allocated face that can hold hundreds of edges if needed
byte superfacebuf[8192];
face_t *superface = (face_t *)superfacebuf;
byte superfacebuf[8192];
face_t *superface = (face_t *) superfacebuf;
void FixFaceEdges (face_t *f);
void FixFaceEdges (face_t * f);
face_t *newlist;
face_t *newlist;
void SplitFaceForTjunc (face_t *f, face_t *original)
void
SplitFaceForTjunc (face_t * f, face_t * original)
{
int i;
face_t *new, *chain;
vec3_t dir, test;
vec_t v;
int firstcorner, lastcorner;
int i;
face_t *new, *chain;
vec3_t dir, test;
vec_t v;
int firstcorner, lastcorner;
chain = NULL;
do
{
if (f->numpoints <= MAXPOINTS)
{ // the face is now small enough without more cutting
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;
@ -308,81 +305,72 @@ void SplitFaceForTjunc (face_t *f, face_t *original)
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);
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)
{
if (v < 0.9999 || v > 1.00001) {
break;
}
}
// find the first corner
// 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 (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)
{
if (v < 0.9999 || v > 1.00001) {
break;
}
}
if (firstcorner+2 >= MAXPOINTS)
{
// rotate the point winding
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]);
for (i = 1; i < f->numpoints; i++) {
VectorCopy (f->pts[i], f->pts[i - 1]);
}
VectorCopy (test, f->pts[f->numpoints-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
// 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;
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++)
{
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)]);
for (i = new->numpoints - 1; i < f->numpoints; i++) {
VectorCopy (f->pts[i], f->pts[i - (new->numpoints - 2)]);
}
f->numpoints -= (new->numpoints-2);
f->numpoints -= (new->numpoints - 2);
} while (1);
}
@ -394,49 +382,44 @@ FixFaceEdges
===============
*/
void FixFaceEdges (face_t *f)
void
FixFaceEdges (face_t * f)
{
int i, j, k;
wedge_t *w;
wvert_t *v;
vec_t t1, t2;
int i, j, k;
wedge_t *w;
wvert_t *v;
vec_t t1, t2;
*superface = *f;
restart:
for (i=0 ; i < superface->numpoints ; i++)
{
j = (i+1)%superface->numpoints;
restart:
for (i = 0; i < superface->numpoints; i++) {
j = (i + 1) % superface->numpoints;
w = FindEdge (superface->pts[i], superface->pts[j], &t1, &t2);
for (v=w->head.next ; v->t < t1 + T_EPSILON ; v = v->next)
{
for (v = w->head.next; v->t < t1 + T_EPSILON; v = v->next) {
}
if (v->t < t2-T_EPSILON)
{
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]);
// insert a new vertex here
for (k = superface->numpoints; k > j; k--) {
VectorCopy (superface->pts[k - 1], superface->pts[k]);
}
VectorMA (w->origin, v->t, w->dir, superface->pts[j]);
superface->numpoints++;
goto restart;
goto restart;
}
}
if (superface->numpoints <= MAXPOINTS)
{
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);
@ -446,31 +429,32 @@ restart:
//============================================================================
void tjunc_find_r (node_t *node)
void
tjunc_find_r (node_t * node)
{
face_t *f;
face_t *f;
if (node->planenum == PLANENUM_LEAF)
return;
for (f=node->faces ; f ; f=f->next)
for (f = node->faces; f; f = f->next)
AddFaceEdges (f);
tjunc_find_r (node->children[0]);
tjunc_find_r (node->children[1]);
}
void tjunc_fix_r (node_t *node)
void
tjunc_fix_r (node_t * node)
{
face_t *f, *next;
face_t *f, *next;
if (node->planenum == PLANENUM_LEAF)
return;
newlist = NULL;
for (f=node->faces ; f ; f=next)
{
for (f = node->faces; f; f = next) {
next = f->next;
FixFaceEdges (f);
}
@ -487,13 +471,14 @@ tjunc
===========
*/
void tjunc (node_t *headnode)
void
tjunc (node_t * headnode)
{
vec3_t maxs, mins;
int i;
vec3_t maxs, mins;
int i;
qprintf ("---- tjunc ----\n");
if (notjunc)
return;
@ -502,21 +487,20 @@ void tjunc (node_t *headnode)
//
// origin points won't allways be inside the map, so extend the hash area
for (i=0 ; i<3 ; i++)
{
if ( fabs(brushset->maxs[i]) > fabs(brushset->mins[i]) )
maxs[i] = fabs(brushset->maxs[i]);
for (i = 0; i < 3; i++) {
if (fabs (brushset->maxs[i]) > fabs (brushset->mins[i]))
maxs[i] = fabs (brushset->maxs[i]);
else
maxs[i] = fabs(brushset->mins[i]);
maxs[i] = fabs (brushset->mins[i]);
}
VectorSubtract (vec3_origin, maxs, mins);
InitHash (mins, maxs);
numwedges = numwverts = 0;
tjunc_find_r (headnode);
qprintf ("%i world edges %i edge points\n", numwedges, numwverts);
//

View file

@ -35,8 +35,8 @@
#include "bsp5.h"
int headclipnode;
int firstface;
int headclipnode;
int firstface;
//===========================================================================
@ -47,13 +47,13 @@ FindFinalPlane
Used to find plane index numbers for clip nodes read from child processes
==================
*/
int FindFinalPlane (dplane_t *p)
int
FindFinalPlane (dplane_t *p)
{
int i;
dplane_t *dplane;
for (i=0, dplane = bsp->planes ; i<bsp->numplanes ; i++, dplane++)
{
int i;
dplane_t *dplane;
for (i = 0, dplane = bsp->planes; i < bsp->numplanes; i++, dplane++) {
if (p->type != dplane->type)
continue;
if (p->dist != dplane->dist)
@ -66,7 +66,7 @@ int FindFinalPlane (dplane_t *p)
continue;
return i;
}
//
// new plane
//
@ -75,25 +75,25 @@ int FindFinalPlane (dplane_t *p)
dplane = &bsp->planes[bsp->numplanes];
*dplane = *p;
bsp->numplanes++;
return bsp->numplanes - 1;
}
int planemapping[MAX_MAP_PLANES];
int planemapping[MAX_MAP_PLANES];
void WriteNodePlanes_r (node_t *node)
void
WriteNodePlanes_r (node_t * node)
{
plane_t *plane;
dplane_t *dplane;
plane_t *plane;
dplane_t *dplane;
if (node->planenum == -1)
return;
if (planemapping[node->planenum] == -1)
{ // a new plane
if (planemapping[node->planenum] == -1) { // a new plane
planemapping[node->planenum] = bsp->numplanes;
if (bsp->numplanes == MAX_MAP_PLANES)
Sys_Error ("numplanes == MAX_MAP_PLANES");
plane = &planes[node->planenum];
@ -108,7 +108,7 @@ void WriteNodePlanes_r (node_t *node)
}
node->outputplanenum = planemapping[node->planenum];
WriteNodePlanes_r (node->children[0]);
WriteNodePlanes_r (node->children[1]);
}
@ -119,9 +119,10 @@ WriteNodePlanes
==================
*/
void WriteNodePlanes (node_t *nodes)
void
WriteNodePlanes (node_t * nodes)
{
memset (planemapping,-1, sizeof(planemapping));
memset (planemapping, -1, sizeof (planemapping));
WriteNodePlanes_r (nodes);
}
@ -133,28 +134,27 @@ WriteClipNodes_r
==================
*/
int WriteClipNodes_r (node_t *node)
int
WriteClipNodes_r (node_t * node)
{
int i, c;
dclipnode_t *cn;
int num;
// FIXME: free more stuff?
if (node->planenum == -1)
{
int i, c;
dclipnode_t *cn;
int num;
// FIXME: free more stuff?
if (node->planenum == -1) {
num = node->contents;
free (node);
return num;
}
// emit a clipnode
c = bsp->numclipnodes;
cn = &bsp->clipnodes[bsp->numclipnodes];
bsp->numclipnodes++;
cn->planenum = node->outputplanenum;
for (i=0 ; i<2 ; i++)
cn->children[i] = WriteClipNodes_r(node->children[i]);
for (i = 0; i < 2; i++)
cn->children[i] = WriteClipNodes_r (node->children[i]);
free (node);
return c;
}
@ -167,7 +167,8 @@ Called after the clipping hull is completed. Generates a disk format
representation and frees the original memory.
==================
*/
void WriteClipNodes (node_t *nodes)
void
WriteClipNodes (node_t * nodes)
{
headclipnode = bsp->numclipnodes;
WriteClipNodes_r (nodes);
@ -180,11 +181,12 @@ void WriteClipNodes (node_t *nodes)
WriteLeaf
==================
*/
void WriteLeaf (node_t *node)
void
WriteLeaf (node_t * node)
{
face_t **fp, *f;
dleaf_t *leaf_p;
face_t **fp, *f;
dleaf_t *leaf_p;
// emit a leaf
leaf_p = &bsp->leafs[bsp->numleafs];
bsp->numleafs++;
@ -193,31 +195,29 @@ void WriteLeaf (node_t *node)
//
// write bounding box info
//
//
VectorCopy (node->mins, leaf_p->mins);
VectorCopy (node->maxs, leaf_p->maxs);
leaf_p->visofs = -1; // no vis info yet
leaf_p->visofs = -1; // no vis info yet
//
// write the marksurfaces
//
leaf_p->firstmarksurface = bsp->nummarksurfaces;
for (fp=node->markfaces ; *fp ; fp++)
{
// emit a marksurface
for (fp = node->markfaces; *fp; fp++) {
// emit a marksurface
if (bsp->nummarksurfaces == MAX_MAP_MARKSURFACES)
Sys_Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
f = *fp;
do
{
bsp->marksurfaces[bsp->nummarksurfaces] = f->outputnumber;
do {
bsp->marksurfaces[bsp->nummarksurfaces] = f->outputnumber;
bsp->nummarksurfaces++;
f=f->original; // grab tjunction split faces
f = f->original; // grab tjunction split faces
} while (f);
}
leaf_p->nummarksurfaces = bsp->nummarksurfaces - leaf_p->firstmarksurface;
}
@ -227,12 +227,13 @@ void WriteLeaf (node_t *node)
WriteDrawNodes_r
==================
*/
void WriteDrawNodes_r (node_t *node)
void
WriteDrawNodes_r (node_t * node)
{
dnode_t *n;
int i;
dnode_t *n;
int i;
// emit a node
// emit a node
if (bsp->numnodes == MAX_MAP_NODES)
Sys_Error ("numnodes == MAX_MAP_NODES");
n = &bsp->nodes[bsp->numnodes];
@ -247,23 +248,18 @@ void WriteDrawNodes_r (node_t *node)
//
// recursively output the other nodes
//
for (i=0 ; i<2 ; i++)
{
if (node->children[i]->planenum == -1)
{
//
for (i = 0; i < 2; i++) {
if (node->children[i]->planenum == -1) {
if (node->children[i]->contents == CONTENTS_SOLID)
n->children[i] = -1;
else
{
else {
n->children[i] = -(bsp->numleafs + 1);
WriteLeaf (node->children[i]);
}
}
else
{
n->children[i] = bsp->numnodes;
} else {
n->children[i] = bsp->numnodes;
WriteDrawNodes_r (node->children[i]);
}
}
@ -274,11 +270,12 @@ void WriteDrawNodes_r (node_t *node)
WriteDrawNodes
==================
*/
void WriteDrawNodes (node_t *headnode)
void
WriteDrawNodes (node_t * headnode)
{
int i;
int start;
dmodel_t *bm;
int i;
int start;
dmodel_t *bm;
#if 0
if (headnode->contents < 0)
@ -290,23 +287,23 @@ void WriteDrawNodes (node_t *headnode)
Sys_Error ("nummodels == MAX_MAP_MODELS");
bm = &bsp->models[bsp->nummodels];
bsp->nummodels++;
bm->headnode[0] = bsp->numnodes;
bm->firstface = firstface;
bm->numfaces = bsp->numfaces - firstface;
bm->numfaces = bsp->numfaces - firstface;
firstface = bsp->numfaces;
start = bsp->numleafs;
if (headnode->contents < 0)
if (headnode->contents < 0)
WriteLeaf (headnode);
else
WriteDrawNodes_r (headnode);
bm->visleafs = bsp->numleafs - start;
for (i=0 ; i<3 ; i++)
{
bm->mins[i] = headnode->mins[i] + SIDESPACE + 1; // remove the padding
for (i = 0; i < 3; i++) {
bm->mins[i] = headnode->mins[i] + SIDESPACE + 1; // remove the
// padding
bm->maxs[i] = headnode->maxs[i] - SIDESPACE - 1;
}
// FIXME: are all the children decendant of padded nodes?
@ -320,57 +317,56 @@ BumpModel
Used by the clipping hull processes that only need to store headclipnode
==================
*/
void BumpModel (int hullnum)
void
BumpModel (int hullnum)
{
dmodel_t *bm;
dmodel_t *bm;
// emit a model
if (bsp->nummodels == MAX_MAP_MODELS)
Sys_Error ("nummodels == MAX_MAP_MODELS");
bm = &bsp->models[bsp->nummodels];
bsp->nummodels++;
bm->headnode[hullnum] = headclipnode;
}
//=============================================================================
typedef struct
{
char identification[4]; // should be WAD2
int numlumps;
int infotableofs;
typedef struct {
char identification[4]; // should be WAD2
int numlumps;
int infotableofs;
} wadinfo_t;
typedef struct
{
int filepos;
int disksize;
int size; // uncompressed
char type;
char compression;
char pad1, pad2;
char name[16]; // must be null terminated
typedef struct {
int filepos;
int disksize;
int size; // uncompressed
char type;
char compression;
char pad1, pad2;
char name[16]; // must be null terminated
} lumpinfo_t;
QFile *texfile;
wadinfo_t wadinfo;
lumpinfo_t *lumpinfo;
QFile *texfile;
wadinfo_t wadinfo;
lumpinfo_t *lumpinfo;
void CleanupName (char *in, char *out)
void
CleanupName (char *in, char *out)
{
int i;
for (i=0 ; i< 16 ; i++ )
{
int i;
for (i = 0; i < 16; i++) {
if (!in[i])
break;
out[i] = toupper(in[i]);
out[i] = toupper (in[i]);
}
for ( ; i< 16 ; i++ )
for (; i < 16; i++)
out[i] = 0;
}
@ -380,25 +376,25 @@ void CleanupName (char *in, char *out)
TEX_InitFromWad
=================
*/
void TEX_InitFromWad (char *path)
void
TEX_InitFromWad (char *path)
{
int i;
int i;
texfile = Qopen (path, "rb");
Qread (texfile, &wadinfo, sizeof(wadinfo));
Qread (texfile, &wadinfo, sizeof (wadinfo));
if (strncmp (wadinfo.identification, "WAD2", 4))
Sys_Error ("TEX_InitFromWad: %s isn't a wadfile",path);
wadinfo.numlumps = LittleLong(wadinfo.numlumps);
wadinfo.infotableofs = LittleLong(wadinfo.infotableofs);
Sys_Error ("TEX_InitFromWad: %s isn't a wadfile", path);
wadinfo.numlumps = LittleLong (wadinfo.numlumps);
wadinfo.infotableofs = LittleLong (wadinfo.infotableofs);
Qseek (texfile, wadinfo.infotableofs, SEEK_SET);
lumpinfo = malloc(wadinfo.numlumps*sizeof(lumpinfo_t));
Qread (texfile, lumpinfo, wadinfo.numlumps*sizeof(lumpinfo_t));
for (i=0 ; i<wadinfo.numlumps ; i++)
{
lumpinfo = malloc (wadinfo.numlumps * sizeof (lumpinfo_t));
Qread (texfile, lumpinfo, wadinfo.numlumps * sizeof (lumpinfo_t));
for (i = 0; i < wadinfo.numlumps; i++) {
CleanupName (lumpinfo[i].name, lumpinfo[i].name);
lumpinfo[i].filepos = LittleLong(lumpinfo[i].filepos);
lumpinfo[i].disksize = LittleLong(lumpinfo[i].disksize);
lumpinfo[i].filepos = LittleLong (lumpinfo[i].filepos);
lumpinfo[i].disksize = LittleLong (lumpinfo[i].disksize);
}
}
@ -407,23 +403,22 @@ void TEX_InitFromWad (char *path)
LoadLump
==================
*/
int LoadLump (char *name, byte *dest)
int
LoadLump (char *name, byte * dest)
{
int i;
char cname[16];
int i;
char cname[16];
CleanupName (name, cname);
for (i=0 ; i<wadinfo.numlumps ; i++)
{
if (!strcmp(cname, lumpinfo[i].name))
{
for (i = 0; i < wadinfo.numlumps; i++) {
if (!strcmp (cname, lumpinfo[i].name)) {
Qseek (texfile, lumpinfo[i].filepos, SEEK_SET);
Qread (texfile, dest, lumpinfo[i].disksize);
return lumpinfo[i].disksize;
}
}
printf ("WARNING: texture %s not found\n", name);
return 0;
}
@ -434,38 +429,36 @@ int LoadLump (char *name, byte *dest)
AddAnimatingTextures
==================
*/
void AddAnimatingTextures (void)
void
AddAnimatingTextures (void)
{
int base;
int i, j, k;
char name[32];
int base;
int i, j, k;
char name[32];
base = nummiptex;
for (i=0 ; i<base ; i++)
{
for (i = 0; i < base; i++) {
if (miptex[i][0] != '+')
continue;
strcpy (name, miptex[i]);
for (j=0 ; j<20 ; j++)
{
for (j = 0; j < 20; j++) {
if (j < 10)
name[1] = '0'+j;
name[1] = '0' + j;
else
name[1] = 'A'+j-10; // alternate animation
name[1] = 'A' + j - 10; // alternate animation
// see if this name exists in the wadfile
for (k=0 ; k<wadinfo.numlumps ; k++)
if (!strcmp(name, lumpinfo[k].name))
{
// see if this name exists in the wadfile
for (k = 0; k < wadinfo.numlumps; k++)
if (!strcmp (name, lumpinfo[k].name)) {
FindMiptex (name); // add to the miptex list
break;
}
}
}
printf ("added %i texture frames\n", nummiptex - base);
}
@ -474,43 +467,41 @@ void AddAnimatingTextures (void)
WriteMiptex
==================
*/
void WriteMiptex (void)
void
WriteMiptex (void)
{
int i, len;
byte *data;
dmiptexlump_t *l;
char *path;
char fullpath[1024];
int i, len;
byte *data;
dmiptexlump_t *l;
char *path;
char fullpath[1024];
path = ValueForKey (&entities[0], "_wad");
if (!path || !path[0])
{
if (!path || !path[0]) {
path = ValueForKey (&entities[0], "wad");
if (!path || !path[0])
{
if (!path || !path[0]) {
printf ("WARNING: no wadfile specified\n");
bsp->texdatasize = 0;
return;
}
}
sprintf (fullpath, "%s/%s", /*FIXME gamedir*/".", path);
sprintf (fullpath, "%s/%s", /* FIXME gamedir */ ".", path);
TEX_InitFromWad (fullpath);
AddAnimatingTextures ();
l = (dmiptexlump_t *)bsp->texdata;
data = (byte *)&l->dataofs[nummiptex];
l = (dmiptexlump_t *) bsp->texdata;
data = (byte *) & l->dataofs[nummiptex];
l->nummiptex = nummiptex;
for (i=0 ; i<nummiptex ; i++)
{
l->dataofs[i] = data - (byte *)l;
for (i = 0; i < nummiptex; i++) {
l->dataofs[i] = data - (byte *) l;
len = LoadLump (miptex[i], data);
if (data + len - bsp->texdata >= MAX_MAP_MIPTEX)
Sys_Error ("Textures exceeded MAX_MAP_MIPTEX");
if (!len)
l->dataofs[i] = -1; // didn't find the texture
l->dataofs[i] = -1; // didn't find the texture
data += len;
}
@ -525,7 +516,8 @@ void WriteMiptex (void)
BeginBSPFile
==================
*/
void BeginBSPFile (void)
void
BeginBSPFile (void)
{
// edge 0 is not used, because 0 can't be negated
bsp->numedges = 1;
@ -534,7 +526,7 @@ void BeginBSPFile (void)
bsp->numleafs = 1;
bsp->leafs[0].contents = CONTENTS_SOLID;
firstface = 0;
firstface = 0;
}
@ -543,17 +535,18 @@ void BeginBSPFile (void)
FinishBSPFile
==================
*/
void FinishBSPFile (void)
void
FinishBSPFile (void)
{
QFile *f;
printf ("--- FinishBSPFile ---\n");
printf ("WriteBSPFile: %s\n", bspfilename);
WriteMiptex ();
//XXX PrintBSPFileSizes ();
// XXX PrintBSPFileSizes ();
f = Qopen (bspfilename, "wb");
WriteBSPFile (bsp, f);
Qclose (f);
}