halflife-thewastes-sdk/utils/qbsp2/writebsp.c
2001-11-08 00:00:00 +00:00

289 lines
5.4 KiB
C

/***
*
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "bsp5.h"
//===========================================================================
/*
==================
WriteClipNodes_r
==================
*/
int WriteClipNodes_r (node_t *node)
{
int i, c;
dclipnode_t *cn;
int num;
if (node->planenum == -1)
{
num = node->contents;
free (node->markfaces);
free (node);
return num;
}
// emit a clipnode
if (numclipnodes == MAX_MAP_CLIPNODES)
Error ("MAX_MAP_CLIPNODES");
c = numclipnodes;
cn = &dclipnodes[numclipnodes];
numclipnodes++;
if (node->planenum & 1)
Error ("WriteClipNodes_r: odd planenum");
cn->planenum = node->planenum;
for (i=0 ; i<2 ; i++)
cn->children[i] = WriteClipNodes_r(node->children[i]);
free (node);
return c;
}
/*
==================
WriteClipNodes
Called after the clipping hull is completed. Generates a disk format
representation and frees the original memory.
==================
*/
void WriteClipNodes (node_t *nodes)
{
WriteClipNodes_r (nodes);
}
//===========================================================================
/*
==================
WriteDrawLeaf
==================
*/
void WriteDrawLeaf (node_t *node)
{
face_t **fp, *f;
dleaf_t *leaf_p;
// emit a leaf
leaf_p = &dleafs[numleafs];
numleafs++;
leaf_p->contents = node->contents;
//
// write bounding box info
//
VectorCopy (node->mins, leaf_p->mins);
VectorCopy (node->maxs, leaf_p->maxs);
leaf_p->visofs = -1; // no vis info yet
//
// write the marksurfaces
//
leaf_p->firstmarksurface = nummarksurfaces;
for (fp=node->markfaces ; *fp ; fp++)
{
// emit a marksurface
f = *fp;
do
{
dmarksurfaces[nummarksurfaces] = f->outputnumber;
if (nummarksurfaces >= MAX_MAP_MARKSURFACES)
Error ("nummarksurfaces == MAX_MAP_MARKSURFACES");
nummarksurfaces++;
f=f->original; // grab tjunction split faces
} while (f);
}
free (node->markfaces);
leaf_p->nummarksurfaces = nummarksurfaces - leaf_p->firstmarksurface;
}
/*
==================
WriteFace
==================
*/
void WriteFace (face_t *f)
{
dface_t *df;
int i;
int e;
f->outputnumber = numfaces;
df = &dfaces[numfaces];
if (numfaces >= MAX_MAP_FACES)
Error ("numfaces == MAX_MAP_FACES");
numfaces++;
df->planenum = f->planenum & (~1);
df->side = f->planenum & 1;
df->firstedge = numsurfedges;
df->numedges = f->numpoints;
df->texinfo = f->texturenum;
for (i=0 ; i<f->numpoints ; i++)
{
e = GetEdge (f->pts[i], f->pts[(i+1)%f->numpoints], f);
if (numsurfedges >= MAX_MAP_SURFEDGES)
Error ("numsurfedges == MAX_MAP_SURFEDGES");
dsurfedges[numsurfedges] = e;
numsurfedges++;
}
}
/*
==================
WriteDrawNodes_r
==================
*/
void WriteDrawNodes_r (node_t *node)
{
dnode_t *n;
int i;
face_t *f, *next;
// emit a node
if (numnodes == MAX_MAP_NODES)
Error ("numnodes == MAX_MAP_NODES");
n = &dnodes[numnodes];
numnodes++;
VectorCopy (node->mins, n->mins);
VectorCopy (node->maxs, n->maxs);
if (node->planenum & 1)
Error ("WriteDrawNodes_r: odd planenum");
n->planenum = node->planenum;
n->firstface = numfaces;
for (f=node->faces ; f ; f=f->next)
WriteFace (f);
n->numfaces = numfaces - n->firstface;
//
// recursively output the other nodes
//
for (i=0 ; i<2 ; i++)
{
if (node->children[i]->planenum == -1)
{
if (node->children[i]->contents == CONTENTS_SOLID)
n->children[i] = -1;
else
{
n->children[i] = -(numleafs + 1);
WriteDrawLeaf (node->children[i]);
}
}
else
{
n->children[i] = numnodes;
WriteDrawNodes_r (node->children[i]);
}
}
}
/*
===========
FreeDrawNodes_r
===========
*/
void FreeDrawNodes_r (node_t *node)
{
int i;
face_t *f, *next;
for (i=0 ; i<2 ; i++)
if (node->children[i]->planenum != -1)
FreeDrawNodes_r (node->children[i]);
//
// free the faces on the node
//
for (f=node->faces ; f ; f=next)
{
next = f->next;
FreeFace (f);
}
free (node);
}
/*
==================
WriteDrawNodes
Called after a drawing hull is completed
Frees all nodes and faces.
==================
*/
void WriteDrawNodes (node_t *headnode)
{
if (headnode->contents < 0)
WriteDrawLeaf (headnode);
else
{
WriteDrawNodes_r (headnode);
FreeDrawNodes_r (headnode);
}
}
//===========================================================================
/*
==================
BeginBSPFile
==================
*/
void BeginBSPFile (void)
{
// these values may actually be initialized
// if the file existed when loaded, so clear them explicitly
nummodels = 0;
numfaces = 0;
numnodes = 0;
numclipnodes = 0;
numvertexes = 0;
nummarksurfaces = 0;
numsurfedges = 0;
// edge 0 is not used, because 0 can't be negated
numedges = 1;
// leaf 0 is common solid with no faces
numleafs = 1;
dleafs[0].contents = CONTENTS_SOLID;
}
/*
==================
FinishBSPFile
==================
*/
void FinishBSPFile (void)
{
int i;
qprintf ("--- FinishBSPFile ---\n");
if (verbose)
PrintBSPFileSizes ();
WriteBSPFile (bspfilename);
}