#include "qbsp.h"
#define PORTALFILE "PRT1"
extern qboolean use_qbsp;
FILE *pf;
int32_t num_visclusters; int32_t num_visportals;
void WriteFloat(FILE *f, vec_t v) {
if (fabs(v - Q_rint(v)) < 0.001)
fprintf(f, "%i ", (int32_t)Q_rint(v));
else
fprintf(f, "%f ", v);
}
void WritePortalFile_r(node_t *node) {
int32_t i, s;
portal_t *p;
winding_t *w;
vec3_t normal;
vec_t dist;
if (node->planenum != PLANENUM_LEAF && !node->detail_seperator) {
WritePortalFile_r(node->children[0]);
WritePortalFile_r(node->children[1]);
return;
}
if (node->contents & CONTENTS_SOLID)
return;
for (p = node->portals; p; p = p->next[s]) {
w = p->winding;
s = (p->nodes[1] == node);
if (w && p->nodes[0] == node) {
if (!Portal_VisFlood(p))
continue;
WindingPlane(w, normal, &dist);
if (DotProduct(p->plane.normal, normal) < 0.99) {
fprintf(pf, "%i %i %i ", w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster);
} else
fprintf(pf, "%i %i %i ", w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster);
for (i = 0; i < w->numpoints; i++) {
fprintf(pf, "(");
WriteFloat(pf, w->p[i][0]);
WriteFloat(pf, w->p[i][1]);
WriteFloat(pf, w->p[i][2]);
fprintf(pf, ") ");
}
fprintf(pf, "\n");
}
}
}
void FillLeafNumbers_r(node_t *node, int32_t num) {
if (node->planenum == PLANENUM_LEAF) {
if (node->contents & CONTENTS_SOLID)
node->cluster = -1;
else
node->cluster = num;
return;
}
node->cluster = num;
FillLeafNumbers_r(node->children[0], num);
FillLeafNumbers_r(node->children[1], num);
}
void NumberLeafs_r(node_t *node) {
portal_t *p;
if (node->planenum != PLANENUM_LEAF && !node->detail_seperator) {
node->cluster = -99;
NumberLeafs_r(node->children[0]);
NumberLeafs_r(node->children[1]);
return;
}
if (node->contents & CONTENTS_SOLID) {
node->cluster = -1;
return;
}
FillLeafNumbers_r(node, num_visclusters);
num_visclusters++;
for (p = node->portals; p;) {
if (p->nodes[0] == node) {
if (Portal_VisFlood(p))
num_visportals++;
p = p->next[0];
} else
p = p->next[1];
}
}
void CreateVisPortals_r(node_t *node) {
if (node->planenum == PLANENUM_LEAF || node->detail_seperator)
return;
MakeNodePortal(node);
SplitNodePortals(node);
CreateVisPortals_r(node->children[0]);
CreateVisPortals_r(node->children[1]);
}
void FinishVisPortals2_r(node_t *node) {
if (node->planenum == PLANENUM_LEAF)
return;
MakeNodePortal(node);
SplitNodePortals(node);
FinishVisPortals2_r(node->children[0]);
FinishVisPortals2_r(node->children[1]);
}
void FinishVisPortals_r(node_t *node) {
if (node->planenum == PLANENUM_LEAF)
return;
if (node->detail_seperator) {
FinishVisPortals2_r(node);
return;
}
FinishVisPortals_r(node->children[0]);
FinishVisPortals_r(node->children[1]);
}
int32_t clusterleaf;
void SaveClusters_r(node_t *node) {
if (node->planenum == PLANENUM_LEAF) {
if (use_qbsp)
dleafsX[clusterleaf++].cluster = node->cluster;
else
dleafs[clusterleaf++].cluster = node->cluster;
return;
}
SaveClusters_r(node->children[0]);
SaveClusters_r(node->children[1]);
}
void WritePortalFile(tree_t *tree) {
char filename[1030];
node_t *headnode;
qprintf("--- WritePortalFile ---\n");
headnode = tree->headnode;
num_visclusters = 0;
num_visportals = 0;
FreeTreePortals_r(headnode);
MakeHeadnodePortals(tree);
CreateVisPortals_r(headnode);
NumberLeafs_r(headnode);
sprintf(filename, "%s.prt", source);
if (use_qbsp)
printf("\ntexinfo count: %i of %i maximum\n", numtexinfo, MAX_MAP_TEXINFO_QBSP);
else
printf("\ntexinfo count: %i of %i maximum\n", numtexinfo, MAX_MAP_TEXINFO);
if (use_qbsp)
printf("brushsides count: %i of %i maximum\n", nummapbrushsides, MAX_MAP_BRUSHSIDES_QBSP);
else
printf("brushsides count: %i of %i maximum\n", nummapbrushsides, MAX_MAP_BRUSHSIDES);
printf("writing %s\n", filename);
pf = fopen(filename, "w");
if (!pf)
Error("Error opening %s", filename);
fprintf(pf, "%s\n", PORTALFILE);
fprintf(pf, "%i\n", num_visclusters);
fprintf(pf, "%i\n", num_visportals);
qprintf("%5i visclusters\n", num_visclusters);
qprintf("%5i visportals\n", num_visportals);
WritePortalFile_r(headnode);
fclose(pf);
clusterleaf = 1;
SaveClusters_r(headnode);
}