port in OQ's detail, hint and skip brush/texture enhancements

This commit is contained in:
Bill Currie 2003-02-04 23:26:26 +00:00
parent 2dd8a6c39d
commit 7073afc0a4
17 changed files with 463 additions and 127 deletions

View file

@ -43,6 +43,9 @@ typedef struct
// volume. is this still needed? // volume. is this still needed?
#define SIDESPACE 24 #define SIDESPACE 24
#define TEX_SKIP -1
#define TEX_HINT -2
//============================================================================ //============================================================================
typedef struct typedef struct
@ -79,6 +82,8 @@ typedef struct visfacet_s
struct visfacet_s *original; // face on node struct visfacet_s *original; // face on node
int outputnumber; // only valid for original faces after int outputnumber; // only valid for original faces after
// write surfaces // write surfaces
qboolean detail; // is a detail face
int numpoints; int numpoints;
vec3_t pts[MAXEDGES]; // FIXME: change to use winding_t vec3_t pts[MAXEDGES]; // FIXME: change to use winding_t
int edges[MAXEDGES]; int edges[MAXEDGES];
@ -93,6 +98,8 @@ typedef struct surface_s
vec3_t mins, maxs; vec3_t mins, maxs;
qboolean onnode; // true if surface has already been used qboolean onnode; // true if surface has already been used
// as a splitting node // as a splitting node
qboolean has_detail; // true if the surface has detail brushes
qboolean has_struct; // true if the surface has non-detail brushes
face_t *faces; // links to all the faces on either side of the surf face_t *faces; // links to all the faces on either side of the surf
} surface_t; } surface_t;
@ -118,6 +125,8 @@ typedef struct node_s
int visleafnum; // -1 = solid int visleafnum; // -1 = solid
int valid; // for flood filling int valid; // for flood filling
int occupied; // light number in leaf for outside filling int occupied; // light number in leaf for outside filling
int o_dist; // distance to nearest entity
int detail; // 1 if created by detail split
} node_t; } node_t;
// brush.c ==================================================================== // brush.c ====================================================================
@ -199,6 +208,7 @@ typedef struct portal_s
extern node_t outside_node; // portals outside the world face this extern node_t outside_node; // portals outside the world face this
void PortalizeWorld (node_t *headnode); void PortalizeWorld (node_t *headnode);
void PortalizeWorldDetail (node_t *headnode); // stop at detail nodes
void WritePortalfile (node_t *headnode); void WritePortalfile (node_t *headnode);
void FreeAllPortals (node_t *node); void FreeAllPortals (node_t *node);

View file

@ -32,6 +32,7 @@ typedef struct mbrush_s
{ {
struct mbrush_s *next; struct mbrush_s *next;
mface_t *faces; mface_t *faces;
qboolean detail; // true if brush is detail brush
} mbrush_t; } mbrush_t;
typedef struct epair_s typedef struct epair_s

View file

@ -610,6 +610,10 @@ LoadBrush (mbrush_t *mb, int hullnum)
if (hullnum) { if (hullnum) {
ExpandBrush (hullnum); ExpandBrush (hullnum);
CreateBrushFaces (); CreateBrushFaces ();
} else if (mb->detail) {
face_t *f;
for (f = brush_faces; f; f = f->next);
f->detail = 1;
} }
// create the brush // create the brush

View file

@ -65,6 +65,7 @@ NewFaceFromFace (face_t *in)
newf->original = in->original; newf->original = in->original;
newf->contents[0] = in->contents[0]; newf->contents[0] = in->contents[0];
newf->contents[1] = in->contents[1]; newf->contents[1] = in->contents[1];
newf->detail = in->detail;
return newf; return newf;
} }
@ -306,8 +307,13 @@ BuildSurfaces (void)
s->next = surfhead; s->next = surfhead;
surfhead = s; surfhead = s;
s->faces = *f; s->faces = *f;
for (count = s->faces; count; count = count->next) for (count = s->faces; count; count = count->next) {
csgmergefaces++; csgmergefaces++;
if (count->detail)
s->has_detail = 1;
else
s->has_struct = 1;
}
CalcSurfaceInfo (s); // bounding box and flags CalcSurfaceInfo (s); // bounding box and flags
} }
@ -322,6 +328,9 @@ CopyFacesToOutside (brush_t *b)
outside = NULL; outside = NULL;
for (f = b->faces; f; f = f->next) { for (f = b->faces; f; f = f->next) {
if (f->texturenum == TEX_SKIP)
continue;
brushfaces++; brushfaces++;
newf = AllocFace (); newf = AllocFace ();
*newf = *f; *newf = *f;
@ -359,9 +368,17 @@ CSGFaces (brushset_t *bs)
// set outside to a copy of the brush's faces // set outside to a copy of the brush's faces
CopyFacesToOutside (b1); CopyFacesToOutside (b1);
if (b1->faces->texturenum < 0) {
// Don't split HINT and SKIP brushes.
SaveOutside (false);
continue;
}
overwrite = false; overwrite = false;
for (b2 = bs->brushes; b2; b2 = b2->next) { for (b2 = bs->brushes; b2; b2 = b2->next) {
if (b2->faces->texturenum < 0)
continue;
// see if b2 needs to clip a chunk out of b1 // see if b2 needs to clip a chunk out of b1
if (b1 == b2) { if (b1 == b2) {

View file

@ -47,12 +47,18 @@ entity_t entities[MAX_MAP_ENTITIES];
int nummiptex; int nummiptex;
char miptex[MAX_MAP_TEXINFO][16]; char miptex[MAX_MAP_TEXINFO][16];
int numdetailbrushes;
int int
FindMiptex (const char *name) FindMiptex (const char *name)
{ {
int i; int i;
if (strcmp (name, "hint") == 0)
return TEX_HINT;
if (strcmp (name, "skip") == 0)
return TEX_SKIP;
for (i = 0; i < nummiptex; i++) { for (i = 0; i < nummiptex; i++) {
if (!strcmp (name, miptex[i])) if (!strcmp (name, miptex[i]))
return i; return i;
@ -75,6 +81,9 @@ FindTexinfo (texinfo_t *t)
int i, j; int i, j;
texinfo_t *tex; texinfo_t *tex;
if (t->miptex < 0)
return t->miptex; // it's HINT or SKIP
// set the special flag // set the special flag
if (miptex[t->miptex][0] == '*' if (miptex[t->miptex][0] == '*'
|| !strncasecmp (miptex[t->miptex], "sky", 3)) || !strncasecmp (miptex[t->miptex], "sky", 3))
@ -345,11 +354,10 @@ ParseBrush (void)
while (TokenAvailable (false)) { while (TokenAvailable (false)) {
GetToken (false); GetToken (false);
//XXX if (!strcmp (token, "detail"))
//if (!strcmp (token, "detail")) b->detail = 1;
// b->detail = 1; else
//else Sys_Error ("Parse error on line %i", scriptline);
// Sys_Error ("Parse error on line %i", scriptline);
} }
// if the three points are all on a previous plane, it is a duplicate // if the three points are all on a previous plane, it is a duplicate
@ -484,6 +492,26 @@ ParseEntity (void)
ParseEpair (); ParseEpair ();
} while (1); } while (1);
if (!strcmp ("am_detail", ValueForKey (mapent, "classname"))) {
mbrush_t *b, *lb;
// set detail flag
for (lb = b = mapent->brushes; b; lb = b, b = b->next) {
b->detail = 1;
numdetailbrushes++;
}
// add to worldspawn
lb->next = entities->brushes;
entities->brushes = mapent->brushes;
num_entities--;
memset (mapent, 0, sizeof (entity_t));
return true;
} else {
mbrush_t *b;
for (b = mapent->brushes; b; b = b->next)
if (b->detail)
numdetailbrushes++;
}
GetVectorForKey (mapent, "origin", mapent->origin); GetVectorForKey (mapent, "origin", mapent->origin);
return true; return true;
} }
@ -511,7 +539,7 @@ LoadMapFile (const char *filename)
qprintf ("--- LoadMapFile ---\n"); qprintf ("--- LoadMapFile ---\n");
qprintf ("%s\n", filename); qprintf ("%s\n", filename);
qprintf ("%5i brushes\n", nummapbrushes); qprintf ("%5i brushes (%i detail)\n", nummapbrushes, numdetailbrushes);
qprintf ("%5i entities\n", num_entities); qprintf ("%5i entities\n", num_entities);
qprintf ("%5i miptex\n", nummiptex); qprintf ("%5i miptex\n", nummiptex);
qprintf ("%5i texinfo\n", bsp->numtexinfo); qprintf ("%5i texinfo\n", bsp->numtexinfo);

View file

@ -47,6 +47,32 @@ PointInLeaf (node_t *node, vec3_t point)
return PointInLeaf (node->children[1], point); return PointInLeaf (node->children[1], point);
} }
static void
FloodEntDist_r (node_t *n, int dist)
{
portal_t *p;
int s;
n->o_dist = dist;
for (p = n->portals; p; p = p->next[s]) {
s = (p->nodes[1] == n);
if (p->nodes[!s]->o_dist)
continue;
if ((p->nodes[0]->contents == CONTENTS_SOLID) ||
(p->nodes[1]->contents == CONTENTS_SOLID))
continue;
if ((p->nodes[0]->contents == CONTENTS_SKY) ||
(p->nodes[1]->contents == CONTENTS_SKY))
continue;
FloodEntDist_r (p->nodes[!s], dist + 1);
}
}
static qboolean static qboolean
PlaceOccupant (int num, vec3_t point, node_t *headnode) PlaceOccupant (int num, vec3_t point, node_t *headnode)
{ {
@ -56,6 +82,9 @@ PlaceOccupant (int num, vec3_t point, node_t *headnode)
if (n->contents == CONTENTS_SOLID) if (n->contents == CONTENTS_SOLID)
return false; return false;
n->occupied = num; n->occupied = num;
FloodEntDist_r (n, 1);
return true; return true;
} }
@ -230,6 +259,49 @@ FillOutside (node_t *node)
fclose (leakfile); fclose (leakfile);
qprintf ("leak file written to %s\n", options.pointfile); qprintf ("leak file written to %s\n", options.pointfile);
qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
if (!options.hullnum) {
node_t *n, *nextnode;;
portal_t *p, *p2;
int i, j, next, side;
vec3_t wc;
n = &outside_node;
next = -1;
while ((n->o_dist > 1) || (next == -1)) {
nextnode = NULL;
p2 = NULL;
for (p = n->portals; p; p = p->next[side]) {
side = (p->nodes[1] == n);
if ((next == -1)
|| ((p->nodes[!side]->o_dist < next)
&& (p->nodes[!side]->o_dist))
)
{
next = p->nodes[!side]->o_dist;
nextnode = p->nodes[!side];
p2 = p;
}
}
if (nextnode) {
n = nextnode;
wc[0] = wc[1] = wc[2] = 0;
for (i = 0; i < p2->winding->numpoints; i++) {
for (j = 0; j < 3; j++)
wc[j] += p2->winding->points[i][j];
}
for (j = 0; j < 3; j++)
wc[j] /= p2->winding->numpoints;
fprintf (leakfile, "%g %g %g\n", wc[0], wc[1], wc[2]);
} else
break;
}
v = entities[n->occupied].origin;
fprintf (leakfile, "%g %g %g\n", v[0], v[1], v[2]);
fclose (leakfile);
}
return false; return false;
} }
if (!options.hullnum) if (!options.hullnum)

View file

@ -159,6 +159,8 @@ PlaneFromWinding (winding_t *w, plane_t *plane)
plane->dist = DotProduct (w->points[0], plane->normal); plane->dist = DotProduct (w->points[0], plane->normal);
} }
static int cutnode_detail;
static void static void
CutNodePortals_r (node_t *node) CutNodePortals_r (node_t *node)
{ {
@ -174,6 +176,9 @@ CutNodePortals_r (node_t *node)
if (node->contents) if (node->contents)
return; // at a leaf, no more dividing return; // at a leaf, no more dividing
if (node->detail && cutnode_detail)
return;
plane = &planes[node->planenum]; plane = &planes[node->planenum];
f = node->children[0]; f = node->children[0];
@ -275,6 +280,22 @@ PortalizeWorld (node_t *headnode)
qprintf ("----- portalize ----\n"); qprintf ("----- portalize ----\n");
MakeHeadnodePortals (headnode); MakeHeadnodePortals (headnode);
cutnode_detail = 0;
CutNodePortals_r (headnode);
}
/*
PortalizeWorldDetail
Like PortalizeWorld, but stop at detail nodes - Alexander Malmberg.
*/
void
PortalizeWorldDetail (node_t *headnode)
{
qprintf ("----- portalize ----\n");
MakeHeadnodePortals (headnode);
cutnode_detail = 1;
CutNodePortals_r (headnode); CutNodePortals_r (headnode);
} }
@ -302,11 +323,12 @@ FreeAllPortals (node_t *node)
// PORTAL FILE GENERATION // PORTAL FILE GENERATION
#define PORTALFILE "PRT1" #define PORTALFILE "PRT1-AM"
FILE *pf; FILE *pf;
int num_visleafs; // leafs the player can be in int num_visleafs; // leafs the player can be in
int num_visportals; int num_visportals;
int num_realleafs;
static void static void
WriteFloat (FILE *f, vec_t v) WriteFloat (FILE *f, vec_t v)
@ -317,6 +339,47 @@ WriteFloat (FILE *f, vec_t v)
fprintf (f, "%f ", v); fprintf (f, "%f ", v);
} }
static int
HasContents (node_t *n, int cont)
{
if (n->contents == cont)
return 1;
if (n->contents)
return 0;
if (HasContents (n->children[0], cont))
return 1;
return HasContents (n->children[1], cont);
}
static int
ShareContents (node_t *n1, node_t *n2)
{
if (n1->contents) {
if (n1->contents == CONTENTS_SOLID)
return 0;
else
return HasContents (n2, n1->contents);
}
if (ShareContents (n1->children[0], n2))
return 1;
return ShareContents (n1->children[1], n2);
}
static int
SameContents (node_t *n1, node_t *n2)
{
if (n1->contents == CONTENTS_SOLID || n2->contents == CONTENTS_SOLID)
return 0;
if (n1->detail && n2->detail)
ShareContents (n1, n2);
if (n1->detail)
return HasContents (n1, n2->contents);
if (n2->detail)
return HasContents (n2, n1->contents);
return n1->contents == n2->contents;
}
static void static void
WritePortalFile_r (node_t *node) WritePortalFile_r (node_t *node)
{ {
@ -325,7 +388,7 @@ WritePortalFile_r (node_t *node)
portal_t *p; portal_t *p;
winding_t *w; winding_t *w;
if (!node->contents) { if (!node->contents && !node->detail) {
WritePortalFile_r (node->children[0]); WritePortalFile_r (node->children[0]);
WritePortalFile_r (node->children[1]); WritePortalFile_r (node->children[1]);
return; return;
@ -337,7 +400,7 @@ WritePortalFile_r (node_t *node)
for (p = node->portals; p;) { for (p = node->portals; p;) {
w = p->winding; w = p->winding;
if (w && p->nodes[0] == node if (w && p->nodes[0] == node
&& p->nodes[0]->contents == p->nodes[1]->contents) { && SameContents (p->nodes[0], p->nodes[1])) {
// write out to the file // write out to the file
// sometimes planes get turned around when they are very near the // sometimes planes get turned around when they are very near the
@ -369,12 +432,41 @@ WritePortalFile_r (node_t *node)
} }
static void
WritePortalLeafs_r (node_t *n)
{
if (!n->contents) {
WritePortalLeafs_r (n->children[0]);
WritePortalLeafs_r (n->children[1]);
} else {
if (n->visleafnum != -1)
fprintf (pf, "%i\n", n->visleafnum);
}
}
static void
SetCluster_r (node_t *n, int num)
{
if (n->contents == CONTENTS_SOLID) {
// solid block, viewpoint never inside
n->visleafnum = -1;
return;
}
n->visleafnum = num;
if (!n->contents) {
SetCluster_r (n->children[0], num);
SetCluster_r (n->children[1], num);
} else
num_realleafs++;
}
static void static void
NumberLeafs_r (node_t *node) NumberLeafs_r (node_t *node)
{ {
portal_t *p; portal_t *p;
if (!node->contents) { if (!node->contents && !node->detail) {
// decision node // decision node
node->visleafnum = -99; node->visleafnum = -99;
NumberLeafs_r (node->children[0]); NumberLeafs_r (node->children[0]);
@ -396,12 +488,19 @@ NumberLeafs_r (node_t *node)
for (p = node->portals; p;) { for (p = node->portals; p;) {
if (p->nodes[0] == node) { if (p->nodes[0] == node) {
// only write out from first leaf // only write out from first leaf
if (p->nodes[0]->contents == p->nodes[1]->contents) if (SameContents(p->nodes[0], p->nodes[1]))
num_visportals++; num_visportals++;
p = p->next[0]; p = p->next[0];
} else } else
p = p->next[1]; p = p->next[1];
} }
if (node->detail) {
SetCluster_r (node->children[0], node->visleafnum);
SetCluster_r (node->children[1], node->visleafnum);
} else {
num_realleafs++;
}
} }
void void
@ -411,6 +510,7 @@ WritePortalfile (node_t *headnode)
// portals // portals
num_visleafs = 0; num_visleafs = 0;
num_visportals = 0; num_visportals = 0;
num_realleafs = 0;
NumberLeafs_r (headnode); NumberLeafs_r (headnode);
// write the file // write the file
@ -422,8 +522,11 @@ WritePortalfile (node_t *headnode)
fprintf (pf, "%s\n", PORTALFILE); fprintf (pf, "%s\n", PORTALFILE);
fprintf (pf, "%i\n", num_visleafs); fprintf (pf, "%i\n", num_visleafs);
fprintf (pf, "%i\n", num_visportals); fprintf (pf, "%i\n", num_visportals);
fprintf (pf, "%i\n", num_realleafs);
WritePortalFile_r (headnode); WritePortalFile_r (headnode);
WritePortalLeafs_r (headnode);
fclose (pf); fclose (pf);
} }

View file

@ -199,6 +199,9 @@ GrowNodeRegion_r (node_t * node)
node->firstface = bsp->numfaces; node->firstface = bsp->numfaces;
for (f = node->faces; f; f = f->next) { for (f = node->faces; f; f = f->next) {
if (f->texturenum < 0)
continue;
// if (f->outputnumber != -1) // if (f->outputnumber != -1)
// continue; // allready grown into an earlier region // continue; // allready grown into an earlier region

View file

@ -24,6 +24,9 @@
static __attribute__ ((unused)) const char rcsid[] = static __attribute__ ((unused)) const char rcsid[] =
"$Id$"; "$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include <stdlib.h> #include <stdlib.h>
#include "QF/sys.h" #include "QF/sys.h"
@ -155,16 +158,16 @@ ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs)
*/ */
static surface_t * static surface_t *
ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs, ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs,
qboolean usefloors) qboolean usefloors, qboolean usedetail)
{ {
face_t *f; face_t *f;
int j, k, l; int j, k, l, ishint;
plane_t *plane; plane_t *plane;
surface_t *p, *p2, *bestsurface; surface_t *p, *p2, *bestsurface;
vec_t bestvalue, bestdistribution, value, dist; vec_t bestvalue, bestdistribution, value, dist;
// pick the plane that splits the least // pick the plane that splits the least
bestvalue = 99999; bestvalue = 999999;
bestsurface = NULL; bestsurface = NULL;
bestdistribution = 9e30; bestdistribution = 9e30;
@ -172,6 +175,16 @@ ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs,
if (p->onnode) if (p->onnode)
continue; continue;
for (f = p->faces; f; f = f->next)
if (f->texturenum == TEX_HINT)
break;
ishint = f != 0;
if (p->has_struct && usedetail)
continue;
if (!p->has_struct && !usedetail)
continue;
plane = &planes[p->planenum]; plane = &planes[p->planenum];
k = 0; k = 0;
@ -186,6 +199,9 @@ ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs,
for (f = p2->faces; f; f = f->next) { for (f = p2->faces; f; f = f->next) {
if (FaceSide (f, plane) == SIDE_ON) { if (FaceSide (f, plane) == SIDE_ON) {
if (!ishint && f->texturenum == TEX_HINT)
k += 9999;
else
k++; k++;
if (k >= bestvalue) if (k >= bestvalue)
break; break;
@ -239,12 +255,14 @@ ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs,
returns NULL if the surface list can not be divided any more (a leaf) returns NULL if the surface list can not be divided any more (a leaf)
*/ */
static surface_t * static surface_t *
SelectPartition (surface_t *surfaces) SelectPartition (surface_t *surfaces, int *detail)
{ {
int i, j; int i, j;
surface_t *p, *bestsurface; surface_t *p, *bestsurface;
vec3_t mins, maxs; vec3_t mins, maxs;
*detail = 0;
// count onnode surfaces // count onnode surfaces
i = 0; i = 0;
bestsurface = NULL; bestsurface = NULL;
@ -257,8 +275,11 @@ SelectPartition (surface_t *surfaces)
if (i == 0) if (i == 0)
return NULL; return NULL;
if (i == 1) if (i == 1) {
if (!bestsurface->has_struct && !usemidsplit)
*detail = 1;
return bestsurface; // this is a final split return bestsurface; // this is a final split
}
// calculate a bounding box of the entire surfaceset // calculate a bounding box of the entire surfaceset
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -283,7 +304,11 @@ SelectPartition (surface_t *surfaces)
if (bestsurface) if (bestsurface)
return bestsurface; return bestsurface;
#endif #endif
return ChoosePlaneFromList (surfaces, mins, maxs, true); bestsurface = ChoosePlaneFromList (surfaces, mins, maxs, true, false);
if (bestsurface)
return bestsurface;
*detail = 1;
return ChoosePlaneFromList (surfaces, mins, maxs, true, true);
} }
//============================================================================ //============================================================================
@ -331,6 +356,8 @@ DividePlane (surface_t *in, plane_t *split, surface_t **front,
plane_t *inplane; plane_t *inplane;
surface_t *news; surface_t *news;
int have[2][2]; // [front|back][detail|struct]
inplane = &planes[in->planenum]; inplane = &planes[in->planenum];
// parallel case is easy // parallel case is easy
@ -345,15 +372,26 @@ DividePlane (surface_t *in, plane_t *split, surface_t **front,
in->faces = NULL; in->faces = NULL;
news->faces = NULL; news->faces = NULL;
in->onnode = news->onnode = true; in->onnode = news->onnode = true;
in->has_detail = in->has_struct = false;
for (; facet; facet = next) { for (; facet; facet = next) {
next = facet->next; next = facet->next;
if (facet->planeside == 1) { if (facet->planeside == 1) {
facet->next = news->faces; facet->next = news->faces;
news->faces = facet; news->faces = facet;
if (facet->detail)
news->has_detail = true;
else
news->has_struct = true;
} else { } else {
facet->next = in->faces; facet->next = in->faces;
in->faces = facet; in->faces = facet;
if (facet->detail)
in->has_detail = true;
else
in->has_struct = true;
} }
} }
@ -382,16 +420,19 @@ DividePlane (surface_t *in, plane_t *split, surface_t **front,
frontlist = NULL; frontlist = NULL;
backlist = NULL; backlist = NULL;
memset (have, 0, sizeof (have));
for (facet = in->faces; facet; facet = next) { for (facet = in->faces; facet; facet = next) {
next = facet->next; next = facet->next;
SplitFace (facet, split, &frontfrag, &backfrag); SplitFace (facet, split, &frontfrag, &backfrag);
if (frontfrag) { if (frontfrag) {
frontfrag->next = frontlist; frontfrag->next = frontlist;
frontlist = frontfrag; frontlist = frontfrag;
have[0][frontfrag->detail] = 1;
} }
if (backfrag) { if (backfrag) {
backfrag->next = backlist; backfrag->next = backlist;
backlist = backfrag; backlist = backfrag;
have[1][backfrag->detail] = 1;
} }
} }
@ -418,6 +459,12 @@ DividePlane (surface_t *in, plane_t *split, surface_t **front,
in->faces = frontlist; in->faces = frontlist;
*front = in; *front = in;
in->has_struct = have[0][0];
in->has_detail = have[0][1];
news->has_struct = have[1][0];
news->has_detail = have[1][1];
// recalc bboxes and flags // recalc bboxes and flags
CalcSurfaceInfo (news); CalcSurfaceInfo (news);
CalcSurfaceInfo (in); CalcSurfaceInfo (in);
@ -459,6 +506,8 @@ LinkConvexFaces (surface_t *planelist, node_t *leafnode)
count = 0; count = 0;
for (surf = planelist; surf; surf = surf->next) { for (surf = planelist; surf; surf = surf->next) {
for (f = surf->faces; f; f = f->next) { for (f = surf->faces; f; f = f->next) {
if (f->texturenum < 0)
continue;
count++; count++;
if (!leafnode->contents) if (!leafnode->contents)
leafnode->contents = f->contents[0]; leafnode->contents = f->contents[0];
@ -495,8 +544,10 @@ LinkConvexFaces (surface_t *planelist, node_t *leafnode)
pnext = surf->next; pnext = surf->next;
for (f = surf->faces; f; f = next) { for (f = surf->faces; f; f = next) {
next = f->next; next = f->next;
if (f->texturenum >= 0) {
leafnode->markfaces[i] = f->original; leafnode->markfaces[i] = f->original;
i++; i++;
}
FreeFace (f); FreeFace (f);
} }
FreeSurface (surf); FreeSurface (surf);
@ -548,8 +599,9 @@ PartitionSurfaces (surface_t *surfaces, node_t *node)
surface_t *frontfrag, *backfrag; surface_t *frontfrag, *backfrag;
plane_t *splitplane; plane_t *splitplane;
split = SelectPartition (surfaces); split = SelectPartition (surfaces, &node->detail);
if (!split) { // this is a leaf node if (!split) { // this is a leaf node
node->detail = 0;
node->planenum = PLANENUM_LEAF; node->planenum = PLANENUM_LEAF;
LinkConvexFaces (surfaces, node); LinkConvexFaces (surfaces, node);
return; return;

View file

@ -365,6 +365,7 @@ MakeFaceEdges_r (node_t *node)
return; return;
for (f = node->faces; f; f = f->next) for (f = node->faces; f; f = f->next)
if (f->texturenum >= 0)
FindFaceEdges (f); FindFaceEdges (f);
MakeFaceEdges_r (node->children[0]); MakeFaceEdges_r (node->children[0]);

View file

@ -387,6 +387,7 @@ tjunc_find_r (node_t *node)
return; return;
for (f = node->faces; f; f = f->next) for (f = node->faces; f; f = f->next)
if (f->texturenum >= 0)
AddFaceEdges (f); AddFaceEdges (f);
tjunc_find_r (node->children[0]); tjunc_find_r (node->children[0]);
@ -405,6 +406,8 @@ tjunc_fix_r (node_t *node)
for (f = node->faces; f; f = next) { for (f = node->faces; f; f = next) {
next = f->next; next = f->next;
if (f->texturenum < 0)
continue;
FixFaceEdges (f); FixFaceEdges (f);
} }

View file

@ -173,6 +173,8 @@ WriteLeaf (node_t *node)
if (bsp->nummarksurfaces == MAX_MAP_MARKSURFACES) if (bsp->nummarksurfaces == MAX_MAP_MARKSURFACES)
Sys_Error ("nummarksurfaces == MAX_MAP_MARKSURFACES"); Sys_Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
f = *fp; f = *fp;
if (f->texturenum < 0)
continue;
do { do {
BSP_AddMarkSurface (bsp, f->outputnumber); BSP_AddMarkSurface (bsp, f->outputnumber);
f = f->original; // grab tjunction split faces f = f->original; // grab tjunction split faces

View file

@ -45,10 +45,10 @@ extern pthread_mutex_t *my_mutex;
#endif #endif
#define MAX_PORTALS 32768 #define MAX_PORTALS 32768
#define PORTALFILE "PRT1" #define PORTALFILE "PRT1-AM"
#define ON_EPSILON 0.1 #define ON_EPSILON 0.1
#define MAX_POINTS_ON_WINDING 64 #define MAX_POINTS_ON_WINDING 64
#define MAX_PORTALS_ON_LEAF 128 #define MAX_PORTALS_ON_CLUSTER 128
typedef struct { typedef struct {
vec3_t normal; vec3_t normal;
@ -70,7 +70,7 @@ typedef enum {
typedef struct { typedef struct {
plane_t plane; // normal pointing into neighbor plane_t plane; // normal pointing into neighbor
int leaf; // neighbor int cluster; // neighbor
winding_t *winding; winding_t *winding;
vstatus_t status; vstatus_t status;
byte *visbits; byte *visbits;
@ -86,19 +86,20 @@ typedef struct seperating_plane_s {
typedef struct passage_s { typedef struct passage_s {
struct passage_s *next; struct passage_s *next;
int from, to; // leaf numbers int from, to; // cluster numbers
sep_t *planes; sep_t *planes;
} passage_t; } passage_t;
typedef struct leaf_s { typedef struct cluster_s {
int numportals; int numportals;
passage_t *passages; passage_t *passages;
portal_t *portals[MAX_PORTALS_ON_LEAF]; portal_t *portals[MAX_PORTALS_ON_CLUSTER];
} leaf_t; int visofs;
} cluster_t;
typedef struct pstack_s { typedef struct pstack_s {
struct pstack_s *next; struct pstack_s *next;
leaf_t *leaf; cluster_t *cluster;
portal_t *portal; // portal exiting portal_t *portal; // portal exiting
winding_t *source, *pass; winding_t *source, *pass;
plane_t portalplane; plane_t portalplane;
@ -106,22 +107,25 @@ typedef struct pstack_s {
} pstack_t; } pstack_t;
typedef struct { typedef struct {
byte *leafvis; // bit string byte *clustervis; // bit string
portal_t *base; portal_t *base;
pstack_t pstack_head; pstack_t pstack_head;
} threaddata_t; } threaddata_t;
extern int numportals; extern int numportals;
extern int portalleafs; extern int portalclusters;
extern int numrealleafs;
extern int c_portaltest; extern int c_portaltest;
extern int c_portalpass; extern int c_portalpass;
extern int c_portalcheck; extern int c_portalcheck;
extern int bitbytes; extern int bitbytes;
extern int bitbytes_l;
extern int bitlongs; extern int bitlongs;
extern struct bsp_s *bsp; extern struct bsp_s *bsp;
extern portal_t *portals; extern portal_t *portals;
extern leaf_t *leafs; extern cluster_t *clusters;
extern int *leafcluster;
extern byte *uncompressed; extern byte *uncompressed;
extern int c_chains; extern int c_chains;
@ -133,7 +137,7 @@ winding_t *NewWinding (int points);
winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon); winding_t *ClipWinding (winding_t *in, plane_t *split, qboolean keepon);
winding_t *CopyWinding (winding_t *winding); winding_t *CopyWinding (winding_t *winding);
void LeafFlow (int leafnum); void ClusterFlow (int clusternum);
void BasePortalVis (void); void BasePortalVis (void);
void PortalFlow (portal_t *portal); void PortalFlow (portal_t *portal);
void CalcAmbientSounds (void); void CalcAmbientSounds (void);

View file

@ -60,7 +60,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "vis.h" #include "vis.h"
#include "options.h" #include "options.h"
static int leafsee; static int clustersee;
static byte portalsee[MAX_PORTALS]; static byte portalsee[MAX_PORTALS];
/* /*
@ -68,24 +68,24 @@ static byte portalsee[MAX_PORTALS];
some of the final calculations. some of the final calculations.
*/ */
static void static void
SimpleFlood (portal_t *srcportal, int leafnum) SimpleFlood (portal_t *srcportal, int clusternum)
{ {
int i; int i;
leaf_t *leaf; cluster_t *cluster;
portal_t *portal; portal_t *portal;
if (srcportal->mightsee[leafnum >> 3] & (1 << (leafnum & 7))) if (srcportal->mightsee[clusternum >> 3] & (1 << (clusternum & 7)))
return; return;
srcportal->mightsee[leafnum >> 3] |= (1 << (leafnum & 7)); srcportal->mightsee[clusternum >> 3] |= (1 << (clusternum & 7));
leafsee++; clustersee++;
leaf = &leafs[leafnum]; cluster = &clusters[clusternum];
for (i = 0; i < leaf->numportals; i++) { for (i = 0; i < cluster->numportals; i++) {
portal = leaf->portals[i]; portal = cluster->portals[i];
if (!portalsee[portal - portals]) if (!portalsee[portal - portals])
continue; continue;
SimpleFlood (srcportal, portal->leaf); SimpleFlood (srcportal, portal->cluster);
} }
} }
@ -129,8 +129,8 @@ BasePortalVis (void)
portalsee[j] = 1; portalsee[j] = 1;
} }
leafsee = 0; clustersee = 0;
SimpleFlood (portal, portal->leaf); SimpleFlood (portal, portal->cluster);
portal->nummightsee = leafsee; portal->nummightsee = clustersee;
} }
} }

View file

@ -61,13 +61,13 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "options.h" #include "options.h"
static void static void
CheckStack (leaf_t *leaf, threaddata_t *thread) CheckStack (cluster_t *cluster, threaddata_t *thread)
{ {
pstack_t *portal; pstack_t *portal;
for (portal = thread->pstack_head.next; portal; portal = portal->next) for (portal = thread->pstack_head.next; portal; portal = portal->next)
if (portal->leaf == leaf) if (portal->cluster == cluster)
Sys_Error ("CheckStack: leaf recursion"); Sys_Error ("CheckStack: cluster recursion");
} }
/* /*
@ -188,16 +188,16 @@ ClipToSeparators (winding_t *source, winding_t *pass, winding_t *target,
} }
/* /*
RecursiveLeafFlow RecursiveClusterFlow
Flood fill through the leafs Flood fill through the clusters
If src_portal is NULL, this is the originating leaf If src_portal is NULL, this is the originating cluster
*/ */
static void static void
RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack) RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
{ {
int i, j; int i, j;
leaf_t *leaf; cluster_t *cluster;
long *test, *might, *vis; long *test, *might, *vis;
qboolean more; qboolean more;
pstack_t stack; pstack_t stack;
@ -207,29 +207,29 @@ RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
c_chains++; c_chains++;
leaf = &leafs[leafnum]; cluster = &clusters[clusternum];
CheckStack(leaf, thread); CheckStack(cluster, thread);
// mark the leaf as visible // mark the cluster as visible
if (!(thread->leafvis[leafnum >> 3] & (1 << (leafnum & 7)))) { if (!(thread->clustervis[clusternum >> 3] & (1 << (clusternum & 7)))) {
thread->leafvis[leafnum >> 3] |= 1 << (leafnum & 7); thread->clustervis[clusternum >> 3] |= 1 << (clusternum & 7);
thread->base->numcansee++; thread->base->numcansee++;
} }
prevstack->next = &stack; prevstack->next = &stack;
stack.next = NULL; stack.next = NULL;
stack.leaf = leaf; stack.cluster = cluster;
stack.portal = NULL; stack.portal = NULL;
stack.mightsee = malloc(bitbytes); stack.mightsee = malloc(bitbytes);
might = (long *) stack.mightsee; might = (long *) stack.mightsee;
vis = (long *) thread->leafvis; vis = (long *) thread->clustervis;
// check all portals for flowing into other leafs // check all portals for flowing into other clusters
for (i = 0; i < leaf->numportals; i++) { for (i = 0; i < cluster->numportals; i++) {
portal = leaf->portals[i]; portal = cluster->portals[i];
if (!(prevstack->mightsee[portal->leaf >> 3] if (!(prevstack->mightsee[portal->cluster >> 3]
& (1 << (portal->leaf & 7)))) & (1 << (portal->cluster & 7))))
continue; // can't possibly see it continue; // can't possibly see it
// if the portal can't see anything we haven't already seen, skip it // if the portal can't see anything we haven't already seen, skip it
if (portal->status == stat_done) { if (portal->status == stat_done) {
@ -249,7 +249,7 @@ RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
if (!more) // can't see anything new if (!more) // can't see anything new
continue; continue;
// get plane of portal, point normal into the neighbor leaf // get plane of portal, point normal into the neighbor cluster
stack.portalplane = portal->plane; stack.portalplane = portal->plane;
VectorSubtract (vec3_origin, portal->plane.normal, backplane.normal); VectorSubtract (vec3_origin, portal->plane.normal, backplane.normal);
backplane.dist = -portal->plane.dist; backplane.dist = -portal->plane.dist;
@ -268,11 +268,11 @@ RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
continue; continue;
if (!prevstack->pass) { if (!prevstack->pass) {
// the second leaf can only be blocked if coplanar // the second cluster can only be blocked if coplanar
stack.source = prevstack->source; stack.source = prevstack->source;
stack.pass = target; stack.pass = target;
RecursiveLeafFlow (portal->leaf, thread, &stack); RecursiveClusterFlow (portal->cluster, thread, &stack);
FreeWinding (target); FreeWinding (target);
continue; continue;
} }
@ -340,7 +340,7 @@ RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
c_portalpass++; c_portalpass++;
// flow through it for real // flow through it for real
RecursiveLeafFlow (portal->leaf, thread, &stack); RecursiveClusterFlow (portal->cluster, thread, &stack);
FreeWinding (source); FreeWinding (source);
FreeWinding (target); FreeWinding (target);
@ -363,7 +363,7 @@ PortalFlow (portal_t *portal)
portal->visbits = calloc (1, bitbytes); portal->visbits = calloc (1, bitbytes);
memset (&data, 0, sizeof (data)); memset (&data, 0, sizeof (data));
data.leafvis = portal->visbits; data.clustervis = portal->visbits;
data.base = portal; data.base = portal;
data.pstack_head.portal = portal; data.pstack_head.portal = portal;
@ -371,7 +371,7 @@ PortalFlow (portal_t *portal)
data.pstack_head.portalplane = portal->plane; data.pstack_head.portalplane = portal->plane;
data.pstack_head.mightsee = portal->mightsee; data.pstack_head.mightsee = portal->mightsee;
RecursiveLeafFlow (portal->leaf, &data, &data.pstack_head); RecursiveClusterFlow (portal->cluster, &data, &data.pstack_head);
portal->status = stat_done; portal->status = stat_done;
} }

View file

@ -80,17 +80,20 @@ int c_portalcheck;
int c_vistest; int c_vistest;
int numportals; int numportals;
int portalleafs; int portalclusters;
int numrealleafs;
int originalvismapsize; int originalvismapsize;
int totalvis; int totalvis;
int count_sep; int count_sep;
int bitbytes; // (portalleafs + 63)>>3 int bitbytes; // (portalleafs + 63)>>3
int bitlongs; int bitlongs;
int bitbytes_l; // (numrealleafs + 63)>>3
portal_t *portals; portal_t *portals;
leaf_t *leafs; cluster_t *clusters;
dstring_t *visdata; dstring_t *visdata;
byte *uncompressed; // [bitbytes * portalleafs] byte *uncompressed; // [bitbytes * portalleafs]
int *leafcluster; // leaf to cluster mappings as read from .prt file
static void static void
@ -305,7 +308,7 @@ CompressRow (byte *vis, byte *dest)
byte *dest_p; byte *dest_p;
dest_p = dest; dest_p = dest;
visrow = (portalleafs + 7) >> 3; visrow = (numrealleafs + 7) >> 3;
for (j = 0; j < visrow; j++) { for (j = 0; j < visrow; j++) {
*dest_p++ = vis[j]; *dest_p++ = vis[j];
@ -325,49 +328,70 @@ CompressRow (byte *vis, byte *dest)
return dest_p - dest; return dest_p - dest;
} }
/* static void
LeafFlow ClusterFlowExpand (byte *src, byte *dest)
{
int i, j;
Builds the entire visibility list for a leaf for (j = 1, i = 0; i < numrealleafs; i++) {
if (src[leafcluster[i] >> 3] & (1 << (leafcluster[i] & 7)))
*dest |= j;
j <<= 1;
if (j == 256) {
j = 1;
dest++;
}
}
}
/*
ClusterFlow
Builds the entire visibility list for a cluster
*/ */
void void
LeafFlow (int leafnum) ClusterFlow (int clusternum)
{ {
byte *outbuffer; byte *outbuffer;
byte compressed[MAX_MAP_LEAFS / 8]; byte compressed[MAX_MAP_LEAFS / 8];
int numvis, i, j; int numvis, i, j;
leaf_t *leaf; cluster_t *cluster;
portal_t *portal; portal_t *portal;
outbuffer = uncompressed + clusternum * bitbytes_l;
cluster = &clusters[clusternum];
// flow through all portals, collecting visible bits // flow through all portals, collecting visible bits
outbuffer = uncompressed + leafnum * bitbytes;
leaf = &leafs[leafnum]; memset (compressed, 0, sizeof (compressed));
for (i = 0; i < leaf->numportals; i++) { for (i = 0; i < cluster->numportals; i++) {
portal = leaf->portals[i]; portal = cluster->portals[i];
if (portal->status != stat_done) if (portal->status != stat_done)
Sys_Error ("portal not done"); Sys_Error ("portal not done");
for (j = 0; j < bitbytes; j++) for (j = 0; j < bitbytes; j++)
outbuffer[j] |= portal->visbits[j]; compressed[j] |= portal->visbits[j];
} }
if (outbuffer[leafnum >> 3] & (1 << (leafnum & 7))) if (compressed[clusternum >> 3] & (1 << (clusternum & 7)))
Sys_Error ("Leaf portals saw into leaf"); Sys_Error ("Cluster portals saw into cluster");
outbuffer[leafnum >> 3] |= (1 << (leafnum & 7)); compressed[clusternum >> 3] |= (1 << (clusternum & 7));
numvis = 0; numvis = 0;
for (i = 0; i < portalleafs; i++) for (i = 0; i < portalclusters; i++)
if (outbuffer[i >> 3] & (1 << (i & 3))) if (compressed[i >> 3] & (1 << (i & 3)))
numvis++; numvis++;
// expand to cluster->leaf PVS
ClusterFlowExpand (compressed, outbuffer);
// compress the bit string // compress the bit string
if (options.verbosity > 0) if (options.verbosity > 0)
printf ("leaf %4i : %4i visible\n", leafnum, numvis); printf ("cluster %4i : %4i visible\n", clusternum, numvis);
totalvis += numvis; totalvis += numvis;
i = CompressRow (outbuffer, compressed); i = CompressRow (outbuffer, compressed);
cluster->visofs = visdata->size;
bsp->leafs[leafnum + 1].visofs = visdata->size;
dstring_append (visdata, compressed, i); dstring_append (visdata, compressed, i);
} }
@ -436,11 +460,14 @@ CalcVis (void)
CalcPortalVis (); CalcPortalVis ();
// assemble the leaf vis lists by oring and compressing the portal lists // assemble the leaf vis lists by oring and compressing the portal lists
for (i = 0; i < portalleafs; i++) for (i = 0; i < portalclusters; i++)
LeafFlow (i); ClusterFlow (i);
for (i = 0; i < numrealleafs; i++) {
bsp->leafs[i].visofs = clusters[leafcluster[i]].visofs;
}
if (options.verbosity >= 0) if (options.verbosity >= 0)
printf ("average leafs visible: %i\n", totalvis / portalleafs); printf ("average clusters visible: %i\n", totalvis / portalclusters);
} }
#if 0 #if 0
static qboolean static qboolean
@ -622,9 +649,9 @@ LoadPortals (char *name)
{ {
char magic[80]; char magic[80];
FILE *f; FILE *f;
int leafnums[2]; int clusternums[2];
int numpoints, i, j; int numpoints, i, j;
leaf_t *leaf; cluster_t *cluster;
plane_t plane; plane_t plane;
portal_t *portal; portal_t *portal;
winding_t *winding; winding_t *winding;
@ -640,35 +667,39 @@ LoadPortals (char *name)
} }
} }
if (fscanf (f, "%79s\n%i\n%i\n", magic, &portalleafs, &numportals) != 3) if (fscanf (f, "%79s\n%i\n%i\n%i\n", magic, &portalclusters, &numportals,
&numrealleafs) != 4)
Sys_Error ("LoadPortals: failed to read header"); Sys_Error ("LoadPortals: failed to read header");
if (strcmp (magic, PORTALFILE)) if (strcmp (magic, PORTALFILE))
Sys_Error ("LoadPortals: not a portal file"); Sys_Error ("LoadPortals: not a portal file");
if (options.verbosity >= 0) { if (options.verbosity >= 0) {
printf ("%4i portalleafs\n", portalleafs); printf ("%4i portalclusters\n", portalclusters);
printf ("%4i numportals\n", numportals); printf ("%4i numportals\n", numportals);
printf ("%4i numrealleafs\n", numrealleafs);
} }
bitbytes = ((portalleafs + 63) & ~63) >> 3; bitbytes = ((portalclusters + 63) & ~63) >> 3;
bitlongs = bitbytes / sizeof (long); bitlongs = bitbytes / sizeof (long);
bitbytes_l = ((numrealleafs + 63) & ~63) >> 3;
// each file portal is split into two memory portals, one for each // each file portal is split into two memory portals, one for each
// direction // direction
portals = calloc (2 * numportals, sizeof (portal_t)); portals = calloc (2 * numportals, sizeof (portal_t));
leafs = calloc (portalleafs, sizeof (leaf_t)); clusters = calloc (portalclusters, sizeof (cluster_t));
originalvismapsize = portalleafs * ((portalleafs + 7) / 8); originalvismapsize = numrealleafs * ((numrealleafs + 7) / 8);
for (i = 0, portal = portals; i < numportals; i++) { for (i = 0, portal = portals; i < numportals; i++) {
if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0], if (fscanf (f, "%i %i %i ", &numpoints, &clusternums[0],
&leafnums[1]) != 3) &clusternums[1]) != 3)
Sys_Error ("LoadPortals: reading portal %i", i); Sys_Error ("LoadPortals: reading portal %i", i);
if (numpoints > MAX_POINTS_ON_WINDING) if (numpoints > MAX_POINTS_ON_WINDING)
Sys_Error ("LoadPortals: portal %i has too many points", i); Sys_Error ("LoadPortals: portal %i has too many points", i);
if ((unsigned) leafnums[0] > portalleafs if ((unsigned) clusternums[0] > portalclusters
|| (unsigned) leafnums[1] > portalleafs) || (unsigned) clusternums[1] > portalclusters)
Sys_Error ("LoadPortals: reading portal %i", i); Sys_Error ("LoadPortals: reading portal %i", i);
winding = portal->winding = NewWinding (numpoints); winding = portal->winding = NewWinding (numpoints);
@ -693,30 +724,35 @@ LoadPortals (char *name)
PlaneFromWinding (winding, &plane); PlaneFromWinding (winding, &plane);
// create forward portal // create forward portal
leaf = &leafs[leafnums[0]]; cluster = &clusters[clusternums[0]];
if (leaf->numportals == MAX_PORTALS_ON_LEAF) if (cluster->numportals == MAX_PORTALS_ON_CLUSTER)
Sys_Error ("Leaf with too many portals"); Sys_Error ("Cluster with too many portals");
leaf->portals[leaf->numportals] = portal; cluster->portals[cluster->numportals] = portal;
leaf->numportals++; cluster->numportals++;
portal->winding = winding; portal->winding = winding;
VectorSubtract (vec3_origin, plane.normal, portal->plane.normal); VectorSubtract (vec3_origin, plane.normal, portal->plane.normal);
portal->plane.dist = -plane.dist; portal->plane.dist = -plane.dist;
portal->leaf = leafnums[1]; portal->cluster = clusternums[1];
portal++; portal++;
// create backwards portal // create backwards portal
leaf = &leafs[leafnums[1]]; cluster = &clusters[clusternums[1]];
if (leaf->numportals == MAX_PORTALS_ON_LEAF) if (cluster->numportals == MAX_PORTALS_ON_CLUSTER)
Sys_Error ("Leaf with too many portals"); Sys_Error ("Cluster with too many portals");
leaf->portals[leaf->numportals] = portal; cluster->portals[cluster->numportals] = portal;
leaf->numportals++; cluster->numportals++;
portal->winding = winding; portal->winding = winding;
portal->plane = plane; portal->plane = plane;
portal->leaf = leafnums[0]; portal->cluster = clusternums[0];
portal++; portal++;
} }
leafcluster = calloc (numrealleafs, sizeof (int));
for (i = 0; i < numrealleafs; i++)
if (fscanf (f, "%i\n", &leafcluster[i]) != 1)
Sys_Error ("LoadPortals: parse error in leaf->cluster mappings");
fclose (f); fclose (f);
} }
@ -753,7 +789,7 @@ main (int argc, char **argv)
dstring_appendstr (portalfile, ".prt"); dstring_appendstr (portalfile, ".prt");
LoadPortals (portalfile->str); LoadPortals (portalfile->str);
uncompressed = calloc (bitbytes, portalleafs); uncompressed = calloc (bitbytes_l, portalclusters);
CalcVis (); CalcVis ();

View file

@ -106,16 +106,16 @@ CalcAmbientSounds (void)
texinfo_t *info; texinfo_t *info;
miptex_t *miptex; miptex_t *miptex;
for (i = 0; i < portalleafs; i++) { for (i = 0; i < numrealleafs - 1; i++) {
leaf = &bsp->leafs[i + 1]; leaf = &bsp->leafs[i + 1];
// clear ambients // clear ambients
for (j = 0; j < NUM_AMBIENTS; j++) for (j = 0; j < NUM_AMBIENTS; j++)
dists[j] = 1020; dists[j] = 1020;
vis = &uncompressed[i * bitbytes]; vis = &uncompressed[leafcluster[i] * bitbytes_l];
for (j = 0; j < portalleafs; j++) { for (j = 0; j < numrealleafs - 1; j++) {
if (!(vis[j >> 3] & (1 << (j & 7)))) if (!(vis[j >> 3] & (1 << (j & 7))))
continue; continue;