287 lines
5 KiB
C++
287 lines
5 KiB
C++
/***
|
|
*
|
|
* Copyright (c) 1996-2002, 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
|
|
{
|
|
if (nummarksurfaces >= MAX_MAP_MARKSURFACES)
|
|
Error("nummarksurfaces == MAX_MAP_MARKSURFACES");
|
|
|
|
dmarksurfaces[nummarksurfaces] = f->outputnumber;
|
|
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;
|
|
|
|
// 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)
|
|
{
|
|
qprintf("--- FinishBSPFile ---\n");
|
|
|
|
if (verbose)
|
|
PrintBSPFileSizes();
|
|
WriteBSPFile(g_bspfilename);
|
|
}
|