mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
port in OQ's detail, hint and skip brush/texture enhancements
This commit is contained in:
parent
2dd8a6c39d
commit
7073afc0a4
17 changed files with 463 additions and 127 deletions
|
@ -43,6 +43,9 @@ typedef struct
|
|||
// volume. is this still needed?
|
||||
#define SIDESPACE 24
|
||||
|
||||
#define TEX_SKIP -1
|
||||
#define TEX_HINT -2
|
||||
|
||||
//============================================================================
|
||||
|
||||
typedef struct
|
||||
|
@ -79,6 +82,8 @@ typedef struct visfacet_s
|
|||
struct visfacet_s *original; // face on node
|
||||
int outputnumber; // only valid for original faces after
|
||||
// write surfaces
|
||||
qboolean detail; // is a detail face
|
||||
|
||||
int numpoints;
|
||||
vec3_t pts[MAXEDGES]; // FIXME: change to use winding_t
|
||||
int edges[MAXEDGES];
|
||||
|
@ -93,6 +98,8 @@ typedef struct surface_s
|
|||
vec3_t mins, maxs;
|
||||
qboolean onnode; // true if surface has already been used
|
||||
// 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
|
||||
} surface_t;
|
||||
|
||||
|
@ -118,6 +125,8 @@ typedef struct node_s
|
|||
int visleafnum; // -1 = solid
|
||||
int valid; // for flood 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;
|
||||
|
||||
// brush.c ====================================================================
|
||||
|
@ -199,6 +208,7 @@ typedef struct portal_s
|
|||
extern node_t outside_node; // portals outside the world face this
|
||||
|
||||
void PortalizeWorld (node_t *headnode);
|
||||
void PortalizeWorldDetail (node_t *headnode); // stop at detail nodes
|
||||
void WritePortalfile (node_t *headnode);
|
||||
void FreeAllPortals (node_t *node);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct mbrush_s
|
|||
{
|
||||
struct mbrush_s *next;
|
||||
mface_t *faces;
|
||||
qboolean detail; // true if brush is detail brush
|
||||
} mbrush_t;
|
||||
|
||||
typedef struct epair_s
|
||||
|
|
|
@ -610,6 +610,10 @@ LoadBrush (mbrush_t *mb, int hullnum)
|
|||
if (hullnum) {
|
||||
ExpandBrush (hullnum);
|
||||
CreateBrushFaces ();
|
||||
} else if (mb->detail) {
|
||||
face_t *f;
|
||||
for (f = brush_faces; f; f = f->next);
|
||||
f->detail = 1;
|
||||
}
|
||||
|
||||
// create the brush
|
||||
|
|
|
@ -65,6 +65,7 @@ NewFaceFromFace (face_t *in)
|
|||
newf->original = in->original;
|
||||
newf->contents[0] = in->contents[0];
|
||||
newf->contents[1] = in->contents[1];
|
||||
newf->detail = in->detail;
|
||||
|
||||
return newf;
|
||||
}
|
||||
|
@ -306,8 +307,13 @@ 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++;
|
||||
if (count->detail)
|
||||
s->has_detail = 1;
|
||||
else
|
||||
s->has_struct = 1;
|
||||
}
|
||||
CalcSurfaceInfo (s); // bounding box and flags
|
||||
}
|
||||
|
||||
|
@ -322,6 +328,9 @@ CopyFacesToOutside (brush_t *b)
|
|||
outside = NULL;
|
||||
|
||||
for (f = b->faces; f; f = f->next) {
|
||||
if (f->texturenum == TEX_SKIP)
|
||||
continue;
|
||||
|
||||
brushfaces++;
|
||||
newf = AllocFace ();
|
||||
*newf = *f;
|
||||
|
@ -359,9 +368,17 @@ CSGFaces (brushset_t *bs)
|
|||
// set outside to a copy of the brush's faces
|
||||
CopyFacesToOutside (b1);
|
||||
|
||||
if (b1->faces->texturenum < 0) {
|
||||
// Don't split HINT and SKIP brushes.
|
||||
SaveOutside (false);
|
||||
continue;
|
||||
}
|
||||
|
||||
overwrite = false;
|
||||
|
||||
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
|
||||
|
||||
if (b1 == b2) {
|
||||
|
|
|
@ -47,12 +47,18 @@ entity_t entities[MAX_MAP_ENTITIES];
|
|||
int nummiptex;
|
||||
char miptex[MAX_MAP_TEXINFO][16];
|
||||
|
||||
int numdetailbrushes;
|
||||
|
||||
|
||||
int
|
||||
FindMiptex (const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (strcmp (name, "hint") == 0)
|
||||
return TEX_HINT;
|
||||
if (strcmp (name, "skip") == 0)
|
||||
return TEX_SKIP;
|
||||
for (i = 0; i < nummiptex; i++) {
|
||||
if (!strcmp (name, miptex[i]))
|
||||
return i;
|
||||
|
@ -75,6 +81,9 @@ FindTexinfo (texinfo_t *t)
|
|||
int i, j;
|
||||
texinfo_t *tex;
|
||||
|
||||
if (t->miptex < 0)
|
||||
return t->miptex; // it's HINT or SKIP
|
||||
|
||||
// set the special flag
|
||||
if (miptex[t->miptex][0] == '*'
|
||||
|| !strncasecmp (miptex[t->miptex], "sky", 3))
|
||||
|
@ -345,11 +354,10 @@ ParseBrush (void)
|
|||
|
||||
while (TokenAvailable (false)) {
|
||||
GetToken (false);
|
||||
//XXX
|
||||
//if (!strcmp (token, "detail"))
|
||||
// b->detail = 1;
|
||||
//else
|
||||
// Sys_Error ("Parse error on line %i", scriptline);
|
||||
if (!strcmp (token, "detail"))
|
||||
b->detail = 1;
|
||||
else
|
||||
Sys_Error ("Parse error on line %i", scriptline);
|
||||
}
|
||||
|
||||
// if the three points are all on a previous plane, it is a duplicate
|
||||
|
@ -484,6 +492,26 @@ ParseEntity (void)
|
|||
ParseEpair ();
|
||||
} 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);
|
||||
return true;
|
||||
}
|
||||
|
@ -511,7 +539,7 @@ LoadMapFile (const char *filename)
|
|||
|
||||
qprintf ("--- LoadMapFile ---\n");
|
||||
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 miptex\n", nummiptex);
|
||||
qprintf ("%5i texinfo\n", bsp->numtexinfo);
|
||||
|
|
|
@ -47,6 +47,32 @@ PointInLeaf (node_t *node, vec3_t 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
|
||||
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)
|
||||
return false;
|
||||
n->occupied = num;
|
||||
|
||||
FloodEntDist_r (n, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -230,6 +259,49 @@ FillOutside (node_t *node)
|
|||
fclose (leakfile);
|
||||
qprintf ("leak file written to %s\n", options.pointfile);
|
||||
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;
|
||||
}
|
||||
if (!options.hullnum)
|
||||
|
|
|
@ -159,6 +159,8 @@ PlaneFromWinding (winding_t *w, plane_t *plane)
|
|||
plane->dist = DotProduct (w->points[0], plane->normal);
|
||||
}
|
||||
|
||||
static int cutnode_detail;
|
||||
|
||||
static void
|
||||
CutNodePortals_r (node_t *node)
|
||||
{
|
||||
|
@ -174,6 +176,9 @@ CutNodePortals_r (node_t *node)
|
|||
if (node->contents)
|
||||
return; // at a leaf, no more dividing
|
||||
|
||||
if (node->detail && cutnode_detail)
|
||||
return;
|
||||
|
||||
plane = &planes[node->planenum];
|
||||
|
||||
f = node->children[0];
|
||||
|
@ -275,6 +280,22 @@ PortalizeWorld (node_t *headnode)
|
|||
qprintf ("----- portalize ----\n");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -302,11 +323,12 @@ FreeAllPortals (node_t *node)
|
|||
|
||||
// PORTAL FILE GENERATION
|
||||
|
||||
#define PORTALFILE "PRT1"
|
||||
#define PORTALFILE "PRT1-AM"
|
||||
|
||||
FILE *pf;
|
||||
int num_visleafs; // leafs the player can be in
|
||||
int num_visportals;
|
||||
int num_realleafs;
|
||||
|
||||
static void
|
||||
WriteFloat (FILE *f, vec_t v)
|
||||
|
@ -317,6 +339,47 @@ WriteFloat (FILE *f, vec_t 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
|
||||
WritePortalFile_r (node_t *node)
|
||||
{
|
||||
|
@ -325,7 +388,7 @@ WritePortalFile_r (node_t *node)
|
|||
portal_t *p;
|
||||
winding_t *w;
|
||||
|
||||
if (!node->contents) {
|
||||
if (!node->contents && !node->detail) {
|
||||
WritePortalFile_r (node->children[0]);
|
||||
WritePortalFile_r (node->children[1]);
|
||||
return;
|
||||
|
@ -337,7 +400,7 @@ WritePortalFile_r (node_t *node)
|
|||
for (p = node->portals; p;) {
|
||||
w = p->winding;
|
||||
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
|
||||
|
||||
// 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
|
||||
NumberLeafs_r (node_t *node)
|
||||
{
|
||||
portal_t *p;
|
||||
|
||||
if (!node->contents) {
|
||||
if (!node->contents && !node->detail) {
|
||||
// decision node
|
||||
node->visleafnum = -99;
|
||||
NumberLeafs_r (node->children[0]);
|
||||
|
@ -396,12 +488,19 @@ NumberLeafs_r (node_t *node)
|
|||
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)
|
||||
if (SameContents(p->nodes[0], p->nodes[1]))
|
||||
num_visportals++;
|
||||
p = p->next[0];
|
||||
} else
|
||||
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
|
||||
|
@ -411,6 +510,7 @@ WritePortalfile (node_t *headnode)
|
|||
// portals
|
||||
num_visleafs = 0;
|
||||
num_visportals = 0;
|
||||
num_realleafs = 0;
|
||||
NumberLeafs_r (headnode);
|
||||
|
||||
// write the file
|
||||
|
@ -422,8 +522,11 @@ WritePortalfile (node_t *headnode)
|
|||
fprintf (pf, "%s\n", PORTALFILE);
|
||||
fprintf (pf, "%i\n", num_visleafs);
|
||||
fprintf (pf, "%i\n", num_visportals);
|
||||
fprintf (pf, "%i\n", num_realleafs);
|
||||
|
||||
WritePortalFile_r (headnode);
|
||||
|
||||
WritePortalLeafs_r (headnode);
|
||||
|
||||
fclose (pf);
|
||||
}
|
||||
|
|
|
@ -199,6 +199,9 @@ GrowNodeRegion_r (node_t * node)
|
|||
node->firstface = bsp->numfaces;
|
||||
|
||||
for (f = node->faces; f; f = f->next) {
|
||||
if (f->texturenum < 0)
|
||||
continue;
|
||||
|
||||
// if (f->outputnumber != -1)
|
||||
// continue; // allready grown into an earlier region
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
static __attribute__ ((unused)) const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/sys.h"
|
||||
|
@ -155,16 +158,16 @@ ChooseMidPlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs)
|
|||
*/
|
||||
static surface_t *
|
||||
ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs,
|
||||
qboolean usefloors)
|
||||
qboolean usefloors, qboolean usedetail)
|
||||
{
|
||||
face_t *f;
|
||||
int j, k, l;
|
||||
int j, k, l, ishint;
|
||||
plane_t *plane;
|
||||
surface_t *p, *p2, *bestsurface;
|
||||
vec_t bestvalue, bestdistribution, value, dist;
|
||||
|
||||
// pick the plane that splits the least
|
||||
bestvalue = 99999;
|
||||
bestvalue = 999999;
|
||||
bestsurface = NULL;
|
||||
bestdistribution = 9e30;
|
||||
|
||||
|
@ -172,6 +175,16 @@ ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs,
|
|||
if (p->onnode)
|
||||
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];
|
||||
k = 0;
|
||||
|
||||
|
@ -186,6 +199,9 @@ ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs,
|
|||
|
||||
for (f = p2->faces; f; f = f->next) {
|
||||
if (FaceSide (f, plane) == SIDE_ON) {
|
||||
if (!ishint && f->texturenum == TEX_HINT)
|
||||
k += 9999;
|
||||
else
|
||||
k++;
|
||||
if (k >= bestvalue)
|
||||
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)
|
||||
*/
|
||||
static surface_t *
|
||||
SelectPartition (surface_t *surfaces)
|
||||
SelectPartition (surface_t *surfaces, int *detail)
|
||||
{
|
||||
int i, j;
|
||||
surface_t *p, *bestsurface;
|
||||
vec3_t mins, maxs;
|
||||
|
||||
*detail = 0;
|
||||
|
||||
// count onnode surfaces
|
||||
i = 0;
|
||||
bestsurface = NULL;
|
||||
|
@ -257,8 +275,11 @@ SelectPartition (surface_t *surfaces)
|
|||
if (i == 0)
|
||||
return NULL;
|
||||
|
||||
if (i == 1)
|
||||
if (i == 1) {
|
||||
if (!bestsurface->has_struct && !usemidsplit)
|
||||
*detail = 1;
|
||||
return bestsurface; // this is a final split
|
||||
}
|
||||
|
||||
// calculate a bounding box of the entire surfaceset
|
||||
for (i = 0; i < 3; i++) {
|
||||
|
@ -283,7 +304,11 @@ SelectPartition (surface_t *surfaces)
|
|||
if (bestsurface)
|
||||
return bestsurface;
|
||||
#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;
|
||||
surface_t *news;
|
||||
|
||||
int have[2][2]; // [front|back][detail|struct]
|
||||
|
||||
inplane = &planes[in->planenum];
|
||||
|
||||
// parallel case is easy
|
||||
|
@ -345,15 +372,26 @@ DividePlane (surface_t *in, plane_t *split, surface_t **front,
|
|||
in->faces = NULL;
|
||||
news->faces = NULL;
|
||||
in->onnode = news->onnode = true;
|
||||
in->has_detail = in->has_struct = false;
|
||||
|
||||
for (; facet; facet = next) {
|
||||
next = facet->next;
|
||||
if (facet->planeside == 1) {
|
||||
facet->next = news->faces;
|
||||
news->faces = facet;
|
||||
|
||||
if (facet->detail)
|
||||
news->has_detail = true;
|
||||
else
|
||||
news->has_struct = true;
|
||||
} else {
|
||||
facet->next = in->faces;
|
||||
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;
|
||||
backlist = NULL;
|
||||
|
||||
memset (have, 0, sizeof (have));
|
||||
for (facet = in->faces; facet; facet = next) {
|
||||
next = facet->next;
|
||||
SplitFace (facet, split, &frontfrag, &backfrag);
|
||||
if (frontfrag) {
|
||||
frontfrag->next = frontlist;
|
||||
frontlist = frontfrag;
|
||||
have[0][frontfrag->detail] = 1;
|
||||
}
|
||||
if (backfrag) {
|
||||
backfrag->next = backlist;
|
||||
backlist = backfrag;
|
||||
have[1][backfrag->detail] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,6 +459,12 @@ DividePlane (surface_t *in, plane_t *split, surface_t **front,
|
|||
in->faces = frontlist;
|
||||
*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
|
||||
CalcSurfaceInfo (news);
|
||||
CalcSurfaceInfo (in);
|
||||
|
@ -459,6 +506,8 @@ LinkConvexFaces (surface_t *planelist, node_t *leafnode)
|
|||
count = 0;
|
||||
for (surf = planelist; surf; surf = surf->next) {
|
||||
for (f = surf->faces; f; f = f->next) {
|
||||
if (f->texturenum < 0)
|
||||
continue;
|
||||
count++;
|
||||
if (!leafnode->contents)
|
||||
leafnode->contents = f->contents[0];
|
||||
|
@ -495,8 +544,10 @@ LinkConvexFaces (surface_t *planelist, node_t *leafnode)
|
|||
pnext = surf->next;
|
||||
for (f = surf->faces; f; f = next) {
|
||||
next = f->next;
|
||||
if (f->texturenum >= 0) {
|
||||
leafnode->markfaces[i] = f->original;
|
||||
i++;
|
||||
}
|
||||
FreeFace (f);
|
||||
}
|
||||
FreeSurface (surf);
|
||||
|
@ -548,8 +599,9 @@ PartitionSurfaces (surface_t *surfaces, node_t *node)
|
|||
surface_t *frontfrag, *backfrag;
|
||||
plane_t *splitplane;
|
||||
|
||||
split = SelectPartition (surfaces);
|
||||
split = SelectPartition (surfaces, &node->detail);
|
||||
if (!split) { // this is a leaf node
|
||||
node->detail = 0;
|
||||
node->planenum = PLANENUM_LEAF;
|
||||
LinkConvexFaces (surfaces, node);
|
||||
return;
|
||||
|
|
|
@ -365,6 +365,7 @@ MakeFaceEdges_r (node_t *node)
|
|||
return;
|
||||
|
||||
for (f = node->faces; f; f = f->next)
|
||||
if (f->texturenum >= 0)
|
||||
FindFaceEdges (f);
|
||||
|
||||
MakeFaceEdges_r (node->children[0]);
|
||||
|
|
|
@ -387,6 +387,7 @@ tjunc_find_r (node_t *node)
|
|||
return;
|
||||
|
||||
for (f = node->faces; f; f = f->next)
|
||||
if (f->texturenum >= 0)
|
||||
AddFaceEdges (f);
|
||||
|
||||
tjunc_find_r (node->children[0]);
|
||||
|
@ -405,6 +406,8 @@ tjunc_fix_r (node_t *node)
|
|||
|
||||
for (f = node->faces; f; f = next) {
|
||||
next = f->next;
|
||||
if (f->texturenum < 0)
|
||||
continue;
|
||||
FixFaceEdges (f);
|
||||
}
|
||||
|
||||
|
|
|
@ -173,6 +173,8 @@ WriteLeaf (node_t *node)
|
|||
if (bsp->nummarksurfaces == MAX_MAP_MARKSURFACES)
|
||||
Sys_Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
|
||||
f = *fp;
|
||||
if (f->texturenum < 0)
|
||||
continue;
|
||||
do {
|
||||
BSP_AddMarkSurface (bsp, f->outputnumber);
|
||||
f = f->original; // grab tjunction split faces
|
||||
|
|
|
@ -45,10 +45,10 @@ extern pthread_mutex_t *my_mutex;
|
|||
#endif
|
||||
|
||||
#define MAX_PORTALS 32768
|
||||
#define PORTALFILE "PRT1"
|
||||
#define PORTALFILE "PRT1-AM"
|
||||
#define ON_EPSILON 0.1
|
||||
#define MAX_POINTS_ON_WINDING 64
|
||||
#define MAX_PORTALS_ON_LEAF 128
|
||||
#define MAX_PORTALS_ON_CLUSTER 128
|
||||
|
||||
typedef struct {
|
||||
vec3_t normal;
|
||||
|
@ -70,7 +70,7 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
plane_t plane; // normal pointing into neighbor
|
||||
int leaf; // neighbor
|
||||
int cluster; // neighbor
|
||||
winding_t *winding;
|
||||
vstatus_t status;
|
||||
byte *visbits;
|
||||
|
@ -86,19 +86,20 @@ typedef struct seperating_plane_s {
|
|||
|
||||
typedef struct passage_s {
|
||||
struct passage_s *next;
|
||||
int from, to; // leaf numbers
|
||||
int from, to; // cluster numbers
|
||||
sep_t *planes;
|
||||
} passage_t;
|
||||
|
||||
typedef struct leaf_s {
|
||||
typedef struct cluster_s {
|
||||
int numportals;
|
||||
passage_t *passages;
|
||||
portal_t *portals[MAX_PORTALS_ON_LEAF];
|
||||
} leaf_t;
|
||||
portal_t *portals[MAX_PORTALS_ON_CLUSTER];
|
||||
int visofs;
|
||||
} cluster_t;
|
||||
|
||||
typedef struct pstack_s {
|
||||
struct pstack_s *next;
|
||||
leaf_t *leaf;
|
||||
cluster_t *cluster;
|
||||
portal_t *portal; // portal exiting
|
||||
winding_t *source, *pass;
|
||||
plane_t portalplane;
|
||||
|
@ -106,22 +107,25 @@ typedef struct pstack_s {
|
|||
} pstack_t;
|
||||
|
||||
typedef struct {
|
||||
byte *leafvis; // bit string
|
||||
byte *clustervis; // bit string
|
||||
portal_t *base;
|
||||
pstack_t pstack_head;
|
||||
} threaddata_t;
|
||||
|
||||
extern int numportals;
|
||||
extern int portalleafs;
|
||||
extern int portalclusters;
|
||||
extern int numrealleafs;
|
||||
extern int c_portaltest;
|
||||
extern int c_portalpass;
|
||||
extern int c_portalcheck;
|
||||
extern int bitbytes;
|
||||
extern int bitbytes_l;
|
||||
extern int bitlongs;
|
||||
extern struct bsp_s *bsp;
|
||||
|
||||
extern portal_t *portals;
|
||||
extern leaf_t *leafs;
|
||||
extern cluster_t *clusters;
|
||||
extern int *leafcluster;
|
||||
extern byte *uncompressed;
|
||||
|
||||
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 *CopyWinding (winding_t *winding);
|
||||
|
||||
void LeafFlow (int leafnum);
|
||||
void ClusterFlow (int clusternum);
|
||||
void BasePortalVis (void);
|
||||
void PortalFlow (portal_t *portal);
|
||||
void CalcAmbientSounds (void);
|
||||
|
|
|
@ -60,7 +60,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
|||
#include "vis.h"
|
||||
#include "options.h"
|
||||
|
||||
static int leafsee;
|
||||
static int clustersee;
|
||||
static byte portalsee[MAX_PORTALS];
|
||||
|
||||
/*
|
||||
|
@ -68,24 +68,24 @@ static byte portalsee[MAX_PORTALS];
|
|||
some of the final calculations.
|
||||
*/
|
||||
static void
|
||||
SimpleFlood (portal_t *srcportal, int leafnum)
|
||||
SimpleFlood (portal_t *srcportal, int clusternum)
|
||||
{
|
||||
int i;
|
||||
leaf_t *leaf;
|
||||
cluster_t *cluster;
|
||||
portal_t *portal;
|
||||
|
||||
if (srcportal->mightsee[leafnum >> 3] & (1 << (leafnum & 7)))
|
||||
if (srcportal->mightsee[clusternum >> 3] & (1 << (clusternum & 7)))
|
||||
return;
|
||||
srcportal->mightsee[leafnum >> 3] |= (1 << (leafnum & 7));
|
||||
leafsee++;
|
||||
srcportal->mightsee[clusternum >> 3] |= (1 << (clusternum & 7));
|
||||
clustersee++;
|
||||
|
||||
leaf = &leafs[leafnum];
|
||||
cluster = &clusters[clusternum];
|
||||
|
||||
for (i = 0; i < leaf->numportals; i++) {
|
||||
portal = leaf->portals[i];
|
||||
for (i = 0; i < cluster->numportals; i++) {
|
||||
portal = cluster->portals[i];
|
||||
if (!portalsee[portal - portals])
|
||||
continue;
|
||||
SimpleFlood (srcportal, portal->leaf);
|
||||
SimpleFlood (srcportal, portal->cluster);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,8 +129,8 @@ BasePortalVis (void)
|
|||
portalsee[j] = 1;
|
||||
}
|
||||
|
||||
leafsee = 0;
|
||||
SimpleFlood (portal, portal->leaf);
|
||||
portal->nummightsee = leafsee;
|
||||
clustersee = 0;
|
||||
SimpleFlood (portal, portal->cluster);
|
||||
portal->nummightsee = clustersee;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,13 +61,13 @@ static __attribute__ ((unused)) const char rcsid[] =
|
|||
#include "options.h"
|
||||
|
||||
static void
|
||||
CheckStack (leaf_t *leaf, threaddata_t *thread)
|
||||
CheckStack (cluster_t *cluster, threaddata_t *thread)
|
||||
{
|
||||
pstack_t *portal;
|
||||
|
||||
for (portal = thread->pstack_head.next; portal; portal = portal->next)
|
||||
if (portal->leaf == leaf)
|
||||
Sys_Error ("CheckStack: leaf recursion");
|
||||
if (portal->cluster == cluster)
|
||||
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
|
||||
If src_portal is NULL, this is the originating leaf
|
||||
Flood fill through the clusters
|
||||
If src_portal is NULL, this is the originating cluster
|
||||
*/
|
||||
static void
|
||||
RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
|
||||
RecursiveClusterFlow (int clusternum, threaddata_t *thread, pstack_t *prevstack)
|
||||
{
|
||||
int i, j;
|
||||
leaf_t *leaf;
|
||||
cluster_t *cluster;
|
||||
long *test, *might, *vis;
|
||||
qboolean more;
|
||||
pstack_t stack;
|
||||
|
@ -207,29 +207,29 @@ RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
|
|||
|
||||
c_chains++;
|
||||
|
||||
leaf = &leafs[leafnum];
|
||||
CheckStack(leaf, thread);
|
||||
cluster = &clusters[clusternum];
|
||||
CheckStack(cluster, thread);
|
||||
|
||||
// mark the leaf as visible
|
||||
if (!(thread->leafvis[leafnum >> 3] & (1 << (leafnum & 7)))) {
|
||||
thread->leafvis[leafnum >> 3] |= 1 << (leafnum & 7);
|
||||
// mark the cluster as visible
|
||||
if (!(thread->clustervis[clusternum >> 3] & (1 << (clusternum & 7)))) {
|
||||
thread->clustervis[clusternum >> 3] |= 1 << (clusternum & 7);
|
||||
thread->base->numcansee++;
|
||||
}
|
||||
|
||||
prevstack->next = &stack;
|
||||
stack.next = NULL;
|
||||
stack.leaf = leaf;
|
||||
stack.cluster = cluster;
|
||||
stack.portal = NULL;
|
||||
stack.mightsee = malloc(bitbytes);
|
||||
might = (long *) stack.mightsee;
|
||||
vis = (long *) thread->leafvis;
|
||||
vis = (long *) thread->clustervis;
|
||||
|
||||
// check all portals for flowing into other leafs
|
||||
for (i = 0; i < leaf->numportals; i++) {
|
||||
portal = leaf->portals[i];
|
||||
// check all portals for flowing into other clusters
|
||||
for (i = 0; i < cluster->numportals; i++) {
|
||||
portal = cluster->portals[i];
|
||||
|
||||
if (!(prevstack->mightsee[portal->leaf >> 3]
|
||||
& (1 << (portal->leaf & 7))))
|
||||
if (!(prevstack->mightsee[portal->cluster >> 3]
|
||||
& (1 << (portal->cluster & 7))))
|
||||
continue; // can't possibly see it
|
||||
// if the portal can't see anything we haven't already seen, skip it
|
||||
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
|
||||
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;
|
||||
VectorSubtract (vec3_origin, portal->plane.normal, backplane.normal);
|
||||
backplane.dist = -portal->plane.dist;
|
||||
|
@ -268,11 +268,11 @@ RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
|
|||
continue;
|
||||
|
||||
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.pass = target;
|
||||
RecursiveLeafFlow (portal->leaf, thread, &stack);
|
||||
RecursiveClusterFlow (portal->cluster, thread, &stack);
|
||||
FreeWinding (target);
|
||||
continue;
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
|
|||
c_portalpass++;
|
||||
|
||||
// flow through it for real
|
||||
RecursiveLeafFlow (portal->leaf, thread, &stack);
|
||||
RecursiveClusterFlow (portal->cluster, thread, &stack);
|
||||
|
||||
FreeWinding (source);
|
||||
FreeWinding (target);
|
||||
|
@ -363,7 +363,7 @@ PortalFlow (portal_t *portal)
|
|||
portal->visbits = calloc (1, bitbytes);
|
||||
|
||||
memset (&data, 0, sizeof (data));
|
||||
data.leafvis = portal->visbits;
|
||||
data.clustervis = portal->visbits;
|
||||
data.base = portal;
|
||||
|
||||
data.pstack_head.portal = portal;
|
||||
|
@ -371,7 +371,7 @@ PortalFlow (portal_t *portal)
|
|||
data.pstack_head.portalplane = portal->plane;
|
||||
data.pstack_head.mightsee = portal->mightsee;
|
||||
|
||||
RecursiveLeafFlow (portal->leaf, &data, &data.pstack_head);
|
||||
RecursiveClusterFlow (portal->cluster, &data, &data.pstack_head);
|
||||
|
||||
portal->status = stat_done;
|
||||
}
|
||||
|
|
|
@ -80,17 +80,20 @@ int c_portalcheck;
|
|||
int c_vistest;
|
||||
|
||||
int numportals;
|
||||
int portalleafs;
|
||||
int portalclusters;
|
||||
int numrealleafs;
|
||||
int originalvismapsize;
|
||||
int totalvis;
|
||||
int count_sep;
|
||||
int bitbytes; // (portalleafs + 63)>>3
|
||||
int bitlongs;
|
||||
int bitbytes_l; // (numrealleafs + 63)>>3
|
||||
|
||||
portal_t *portals;
|
||||
leaf_t *leafs;
|
||||
cluster_t *clusters;
|
||||
dstring_t *visdata;
|
||||
byte *uncompressed; // [bitbytes * portalleafs]
|
||||
int *leafcluster; // leaf to cluster mappings as read from .prt file
|
||||
|
||||
|
||||
static void
|
||||
|
@ -305,7 +308,7 @@ CompressRow (byte *vis, byte *dest)
|
|||
byte *dest_p;
|
||||
|
||||
dest_p = dest;
|
||||
visrow = (portalleafs + 7) >> 3;
|
||||
visrow = (numrealleafs + 7) >> 3;
|
||||
|
||||
for (j = 0; j < visrow; j++) {
|
||||
*dest_p++ = vis[j];
|
||||
|
@ -325,49 +328,70 @@ CompressRow (byte *vis, byte *dest)
|
|||
return dest_p - dest;
|
||||
}
|
||||
|
||||
/*
|
||||
LeafFlow
|
||||
static void
|
||||
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
|
||||
LeafFlow (int leafnum)
|
||||
ClusterFlow (int clusternum)
|
||||
{
|
||||
byte *outbuffer;
|
||||
byte compressed[MAX_MAP_LEAFS / 8];
|
||||
int numvis, i, j;
|
||||
leaf_t *leaf;
|
||||
cluster_t *cluster;
|
||||
portal_t *portal;
|
||||
|
||||
outbuffer = uncompressed + clusternum * bitbytes_l;
|
||||
cluster = &clusters[clusternum];
|
||||
|
||||
// flow through all portals, collecting visible bits
|
||||
outbuffer = uncompressed + leafnum * bitbytes;
|
||||
leaf = &leafs[leafnum];
|
||||
for (i = 0; i < leaf->numportals; i++) {
|
||||
portal = leaf->portals[i];
|
||||
|
||||
memset (compressed, 0, sizeof (compressed));
|
||||
for (i = 0; i < cluster->numportals; i++) {
|
||||
portal = cluster->portals[i];
|
||||
if (portal->status != stat_done)
|
||||
Sys_Error ("portal not done");
|
||||
for (j = 0; j < bitbytes; j++)
|
||||
outbuffer[j] |= portal->visbits[j];
|
||||
compressed[j] |= portal->visbits[j];
|
||||
}
|
||||
|
||||
if (outbuffer[leafnum >> 3] & (1 << (leafnum & 7)))
|
||||
Sys_Error ("Leaf portals saw into leaf");
|
||||
if (compressed[clusternum >> 3] & (1 << (clusternum & 7)))
|
||||
Sys_Error ("Cluster portals saw into cluster");
|
||||
|
||||
outbuffer[leafnum >> 3] |= (1 << (leafnum & 7));
|
||||
compressed[clusternum >> 3] |= (1 << (clusternum & 7));
|
||||
|
||||
numvis = 0;
|
||||
for (i = 0; i < portalleafs; i++)
|
||||
if (outbuffer[i >> 3] & (1 << (i & 3)))
|
||||
for (i = 0; i < portalclusters; i++)
|
||||
if (compressed[i >> 3] & (1 << (i & 3)))
|
||||
numvis++;
|
||||
|
||||
// expand to cluster->leaf PVS
|
||||
ClusterFlowExpand (compressed, outbuffer);
|
||||
|
||||
// compress the bit string
|
||||
if (options.verbosity > 0)
|
||||
printf ("leaf %4i : %4i visible\n", leafnum, numvis);
|
||||
printf ("cluster %4i : %4i visible\n", clusternum, numvis);
|
||||
totalvis += numvis;
|
||||
|
||||
i = CompressRow (outbuffer, compressed);
|
||||
|
||||
bsp->leafs[leafnum + 1].visofs = visdata->size;
|
||||
cluster->visofs = visdata->size;
|
||||
dstring_append (visdata, compressed, i);
|
||||
}
|
||||
|
||||
|
@ -436,11 +460,14 @@ CalcVis (void)
|
|||
CalcPortalVis ();
|
||||
|
||||
// assemble the leaf vis lists by oring and compressing the portal lists
|
||||
for (i = 0; i < portalleafs; i++)
|
||||
LeafFlow (i);
|
||||
for (i = 0; i < portalclusters; i++)
|
||||
ClusterFlow (i);
|
||||
|
||||
for (i = 0; i < numrealleafs; i++) {
|
||||
bsp->leafs[i].visofs = clusters[leafcluster[i]].visofs;
|
||||
}
|
||||
if (options.verbosity >= 0)
|
||||
printf ("average leafs visible: %i\n", totalvis / portalleafs);
|
||||
printf ("average clusters visible: %i\n", totalvis / portalclusters);
|
||||
}
|
||||
#if 0
|
||||
static qboolean
|
||||
|
@ -622,9 +649,9 @@ LoadPortals (char *name)
|
|||
{
|
||||
char magic[80];
|
||||
FILE *f;
|
||||
int leafnums[2];
|
||||
int clusternums[2];
|
||||
int numpoints, i, j;
|
||||
leaf_t *leaf;
|
||||
cluster_t *cluster;
|
||||
plane_t plane;
|
||||
portal_t *portal;
|
||||
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");
|
||||
if (strcmp (magic, PORTALFILE))
|
||||
Sys_Error ("LoadPortals: not a portal file");
|
||||
|
||||
if (options.verbosity >= 0) {
|
||||
printf ("%4i portalleafs\n", portalleafs);
|
||||
printf ("%4i portalclusters\n", portalclusters);
|
||||
printf ("%4i numportals\n", numportals);
|
||||
printf ("%4i numrealleafs\n", numrealleafs);
|
||||
}
|
||||
|
||||
bitbytes = ((portalleafs + 63) & ~63) >> 3;
|
||||
bitbytes = ((portalclusters + 63) & ~63) >> 3;
|
||||
bitlongs = bitbytes / sizeof (long);
|
||||
|
||||
bitbytes_l = ((numrealleafs + 63) & ~63) >> 3;
|
||||
|
||||
// each file portal is split into two memory portals, one for each
|
||||
// direction
|
||||
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++) {
|
||||
if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0],
|
||||
&leafnums[1]) != 3)
|
||||
if (fscanf (f, "%i %i %i ", &numpoints, &clusternums[0],
|
||||
&clusternums[1]) != 3)
|
||||
Sys_Error ("LoadPortals: reading portal %i", i);
|
||||
if (numpoints > MAX_POINTS_ON_WINDING)
|
||||
Sys_Error ("LoadPortals: portal %i has too many points", i);
|
||||
if ((unsigned) leafnums[0] > portalleafs
|
||||
|| (unsigned) leafnums[1] > portalleafs)
|
||||
if ((unsigned) clusternums[0] > portalclusters
|
||||
|| (unsigned) clusternums[1] > portalclusters)
|
||||
Sys_Error ("LoadPortals: reading portal %i", i);
|
||||
|
||||
winding = portal->winding = NewWinding (numpoints);
|
||||
|
@ -693,30 +724,35 @@ LoadPortals (char *name)
|
|||
PlaneFromWinding (winding, &plane);
|
||||
|
||||
// create forward portal
|
||||
leaf = &leafs[leafnums[0]];
|
||||
if (leaf->numportals == MAX_PORTALS_ON_LEAF)
|
||||
Sys_Error ("Leaf with too many portals");
|
||||
leaf->portals[leaf->numportals] = portal;
|
||||
leaf->numportals++;
|
||||
cluster = &clusters[clusternums[0]];
|
||||
if (cluster->numportals == MAX_PORTALS_ON_CLUSTER)
|
||||
Sys_Error ("Cluster with too many portals");
|
||||
cluster->portals[cluster->numportals] = portal;
|
||||
cluster->numportals++;
|
||||
|
||||
portal->winding = winding;
|
||||
VectorSubtract (vec3_origin, plane.normal, portal->plane.normal);
|
||||
portal->plane.dist = -plane.dist;
|
||||
portal->leaf = leafnums[1];
|
||||
portal->cluster = clusternums[1];
|
||||
portal++;
|
||||
|
||||
// create backwards portal
|
||||
leaf = &leafs[leafnums[1]];
|
||||
if (leaf->numportals == MAX_PORTALS_ON_LEAF)
|
||||
Sys_Error ("Leaf with too many portals");
|
||||
leaf->portals[leaf->numportals] = portal;
|
||||
leaf->numportals++;
|
||||
cluster = &clusters[clusternums[1]];
|
||||
if (cluster->numportals == MAX_PORTALS_ON_CLUSTER)
|
||||
Sys_Error ("Cluster with too many portals");
|
||||
cluster->portals[cluster->numportals] = portal;
|
||||
cluster->numportals++;
|
||||
|
||||
portal->winding = winding;
|
||||
portal->plane = plane;
|
||||
portal->leaf = leafnums[0];
|
||||
portal->cluster = clusternums[0];
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -753,7 +789,7 @@ main (int argc, char **argv)
|
|||
dstring_appendstr (portalfile, ".prt");
|
||||
LoadPortals (portalfile->str);
|
||||
|
||||
uncompressed = calloc (bitbytes, portalleafs);
|
||||
uncompressed = calloc (bitbytes_l, portalclusters);
|
||||
|
||||
CalcVis ();
|
||||
|
||||
|
|
|
@ -106,16 +106,16 @@ CalcAmbientSounds (void)
|
|||
texinfo_t *info;
|
||||
miptex_t *miptex;
|
||||
|
||||
for (i = 0; i < portalleafs; i++) {
|
||||
for (i = 0; i < numrealleafs - 1; i++) {
|
||||
leaf = &bsp->leafs[i + 1];
|
||||
|
||||
// clear ambients
|
||||
for (j = 0; j < NUM_AMBIENTS; j++)
|
||||
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))))
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue