00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "bsp.h"
00026
00027 static int c_nofaces;
00028 static int c_facenodes;
00029
00030
00031
00032
00033
00034
00035
00041 void EmitPlanes (void)
00042 {
00043 int i;
00044 const plane_t *mp = mapplanes;
00045
00046 for (i = 0; i < nummapplanes; i++, mp++) {
00047 dBspPlane_t *dp = &curTile->planes[curTile->numplanes];
00048 VectorCopy(mp->normal, dp->normal);
00049 dp->dist = mp->dist;
00050 dp->type = mp->type;
00051 curTile->numplanes++;
00052 }
00053 }
00054
00058 static void EmitLeaf (const node_t *node)
00059 {
00060 dBspLeaf_t *leaf_p;
00061 int i, brushnum;
00062 const bspbrush_t *b;
00063
00064
00065 if (curTile->numleafs >= MAX_MAP_LEAFS)
00066 Sys_Error("MAX_MAP_LEAFS (%i)", curTile->numleafs);
00067
00068 leaf_p = &curTile->leafs[curTile->numleafs];
00069 curTile->numleafs++;
00070
00071 leaf_p->contentFlags = node->contentFlags;
00072 leaf_p->area = node->area;
00073
00074
00075 VectorCopy((short)node->mins, leaf_p->mins);
00076 VectorCopy((short)node->maxs, leaf_p->maxs);
00077
00078
00079 leaf_p->firstleafbrush = curTile->numleafbrushes;
00080 for (b = node->brushlist; b; b = b->next) {
00081 if (curTile->numleafbrushes >= MAX_MAP_LEAFBRUSHES)
00082 Sys_Error("MAX_MAP_LEAFBRUSHES (%i)", curTile->numleafbrushes);
00083
00084 brushnum = b->original - mapbrushes;
00085 for (i = leaf_p->firstleafbrush; i < curTile->numleafbrushes; i++)
00086 if (curTile->leafbrushes[i] == brushnum)
00087 break;
00088 if (i == curTile->numleafbrushes) {
00089 Verb_Printf(VERB_DUMP, "EmitLeaf: adding brush %i to leaf %i\n", brushnum, curTile->numleafs - 1);
00090 curTile->leafbrushes[curTile->numleafbrushes] = brushnum;
00091 curTile->numleafbrushes++;
00092 }
00093 }
00094 leaf_p->numleafbrushes = curTile->numleafbrushes - leaf_p->firstleafbrush;
00095 }
00096
00097
00102 static void EmitFace (const face_t *f)
00103 {
00104 dBspSurface_t *df;
00105 int i;
00106
00107 if (f->numpoints < 3) {
00108 return;
00109 }
00110 if (f->merged || f->split[0] || f->split[1]) {
00111 return;
00112 }
00113
00114 if (curTile->numfaces >= MAX_MAP_FACES)
00115 Sys_Error("numfaces >= MAX_MAP_FACES (%i)", curTile->numfaces);
00116 df = &curTile->faces[curTile->numfaces];
00117 curTile->numfaces++;
00118
00119
00120 df->planenum = f->planenum & (~1);
00121 df->side = f->planenum & 1;
00122
00123 df->firstedge = curTile->numsurfedges;
00124 df->numedges = f->numpoints;
00125 df->texinfo = f->texinfo;
00126 for (i = 0; i < f->numpoints; i++) {
00127 const int e = GetEdge(f->vertexnums[i], f->vertexnums[(i + 1) % f->numpoints], f);
00128 if (curTile->numsurfedges >= MAX_MAP_SURFEDGES)
00129 Sys_Error("numsurfedges >= MAX_MAP_SURFEDGES (%i)", curTile->numsurfedges);
00130 curTile->surfedges[curTile->numsurfedges] = e;
00131 curTile->numsurfedges++;
00132 }
00133 for (i = 0; i < LIGHTMAP_MAX; i++)
00134 df->lightofs[i] = -1;
00135 }
00136
00141 static int EmitDrawNode_r (node_t *node)
00142 {
00143 const char* side[2] = {"front", "back"};
00144 dBspNode_t *n;
00145 const face_t *f;
00146 int i;
00147
00148 if (node->planenum == PLANENUM_LEAF) {
00149 Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating singleton leaf.\n");
00150 EmitLeaf(node);
00151 return -curTile->numleafs;
00152 }
00153
00154
00155 if (curTile->numnodes >= MAX_MAP_NODES)
00156 Sys_Error("MAX_MAP_NODES (%i)", curTile->numnodes);
00157 n = &curTile->nodes[curTile->numnodes];
00158 Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating bsp node %i\n", curTile->numnodes);
00159 curTile->numnodes++;
00160
00161 VectorCopy((short)node->mins, n->mins);
00162 VectorCopy((short)node->maxs, n->maxs);
00163
00164 if (node->planenum & 1)
00165 Sys_Error("EmitDrawNode_r: odd planenum: %i", node->planenum);
00166 n->planenum = node->planenum;
00167 n->firstface = curTile->numfaces;
00168
00169 if (!node->faces)
00170 c_nofaces++;
00171 else
00172 c_facenodes++;
00173
00174 for (f = node->faces; f; f = f->next)
00175 EmitFace(f);
00176
00177 n->numfaces = curTile->numfaces - n->firstface;
00178
00179
00180 for (i = 0; i < 2; i++) {
00181 if (node->children[i]->planenum == PLANENUM_LEAF) {
00182 Verb_Printf(VERB_DUMP, "EmitDrawNode_r: creating child leaf for %s of bsp node "UFO_SIZE_T".\n", side[i], n - curTile->nodes);
00183 n->children[i] = -(curTile->numleafs + 1);
00184 EmitLeaf(node->children[i]);
00185 } else {
00186 Verb_Printf(VERB_DUMP, "EmitDrawNode_r: adding child node for bsp node "UFO_SIZE_T".\n", n - curTile->nodes);
00187 n->children[i] = curTile->numnodes;
00188 EmitDrawNode_r(node->children[i]);
00189 }
00190 }
00191
00192 return n - curTile->nodes;
00193 }
00194
00195
00201 int WriteBSP (node_t *headnode)
00202 {
00203 int oldfaces, emittedHeadnode;
00204
00205 c_nofaces = 0;
00206 c_facenodes = 0;
00207
00208 Verb_Printf(VERB_EXTRA, "--- WriteBSP ---\n");
00209
00210 oldfaces = curTile->numfaces;
00211 emittedHeadnode = EmitDrawNode_r(headnode);
00212
00213 Verb_Printf(VERB_EXTRA, "%5i nodes with faces\n", c_facenodes);
00214 Verb_Printf(VERB_EXTRA, "%5i nodes without faces\n", c_nofaces);
00215 Verb_Printf(VERB_EXTRA, "%5i faces\n", curTile->numfaces - oldfaces);
00216
00217 return emittedHeadnode;
00218 }
00219
00223 void SetModelNumbers (void)
00224 {
00225 int i;
00226 char value[10];
00227
00228
00229 int models = 1;
00230 for (i = 1; i < num_entities; i++) {
00231 if (entities[i].numbrushes) {
00232 Com_sprintf(value, sizeof(value), "*%i", models);
00233 models++;
00234 SetKeyValue(&entities[i], "model", value);
00235 }
00236 }
00237 }
00238
00242 void EmitBrushes (void)
00243 {
00244 int i, j, bnum, s, x;
00245 vec3_t normal;
00246 vec_t dist;
00247 int planenum;
00248
00249 curTile->numbrushsides = 0;
00250 curTile->numbrushes = nummapbrushes;
00251
00252 memset(curTile->brushes, 0, MAX_MAP_BRUSHES * sizeof(cBspBrush_t));
00253
00254 for (bnum = 0; bnum < nummapbrushes; bnum++) {
00255 const mapbrush_t *b = &mapbrushes[bnum];
00256 dBspBrush_t *db = &curTile->dbrushes[bnum];
00257 cBspBrush_t *cb = &curTile->brushes[bnum];
00258
00259 db->contentFlags = b->contentFlags;
00260 db->firstbrushside = curTile->numbrushsides;
00261 db->numsides = b->numsides;
00262 cb->contentFlags = b->contentFlags;
00263 cb->firstbrushside = curTile->numbrushsides;
00264 cb->numsides = b->numsides;
00265 cb->checkcount = 0;
00266 for (j = 0; j < b->numsides; j++) {
00267 if (curTile->numbrushsides == MAX_MAP_BRUSHSIDES) {
00268 Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);
00269 } else {
00270 dBspBrushSide_t *cp = &curTile->brushsides[curTile->numbrushsides];
00271 curTile->numbrushsides++;
00272 cp->planenum = b->original_sides[j].planenum;
00273 cp->texinfo = b->original_sides[j].texinfo;
00274 }
00275 }
00276
00277
00278 for (x = 0; x < 3; x++)
00279 for (s = -1; s <= 1; s += 2) {
00280
00281 VectorCopy(vec3_origin, normal);
00282 normal[x] = (float)s;
00283 if (s == -1)
00284 dist = -b->mins[x];
00285 else
00286 dist = b->maxs[x];
00287 planenum = FindOrCreateFloatPlane(normal, dist);
00288 for (i = 0; i < b->numsides; i++)
00289 if (b->original_sides[i].planenum == planenum)
00290 break;
00291 if (i == b->numsides) {
00292 if (curTile->numbrushsides >= MAX_MAP_BRUSHSIDES)
00293 Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);
00294
00295 curTile->brushsides[curTile->numbrushsides].planenum = planenum;
00296 curTile->brushsides[curTile->numbrushsides].texinfo = curTile->brushsides[curTile->numbrushsides - 1].texinfo;
00297 curTile->numbrushsides++;
00298 db->numsides++;
00299 cb->numsides++;
00300 }
00301 }
00302 }
00303 }
00304
00309 void BeginBSPFile (void)
00310 {
00311
00312 curTile = &mapTiles.mapTiles[0];
00313
00314 mapTiles.numTiles = 1;
00315
00316
00317
00318 curTile->nummodels = 0;
00319 curTile->numfaces = 0;
00320 curTile->numbrushsides = 0;
00321 curTile->numleafbrushes = 0;
00322 curTile->numsurfedges = 0;
00323 curTile->numnodes = 0;
00324
00325
00326 curTile->numedges = 1;
00327
00328
00329 curTile->numvertexes = 1;
00330 curTile->numnormals = 1;
00331
00332
00333 curTile->numleafs = 1;
00334 curTile->leafs[0].contentFlags = CONTENTS_SOLID;
00335 }
00336
00337
00342 void EndBSPFile (const char *filename)
00343 {
00344 EmitBrushes();
00345 EmitPlanes();
00346 UnparseEntities();
00347
00348
00349 Verb_Printf(VERB_LESS, "Writing %s\n", filename);
00350 WriteBSPFile(filename);
00351 }
00352
00353 extern int firstmodeledge;
00354
00359 void BeginModel (int entityNum)
00360 {
00361 dBspModel_t *mod;
00362 int start, end;
00363 int j;
00364 const entity_t *e;
00365 vec3_t mins, maxs;
00366
00367 if (curTile->nummodels == MAX_MAP_MODELS)
00368 Sys_Error("MAX_MAP_MODELS (%i)", curTile->nummodels);
00369 mod = &curTile->models[curTile->nummodels];
00370
00371 mod->firstface = curTile->numfaces;
00372
00373 firstmodeledge = curTile->numedges;
00374
00375
00376 e = &entities[entityNum];
00377
00378 start = e->firstbrush;
00379 end = start + e->numbrushes;
00380 ClearBounds(mins, maxs);
00381
00382 for (j = start; j < end; j++) {
00383 mapbrush_t *b = &mapbrushes[j];
00384
00385 if (!b->numsides)
00386 continue;
00387 AddPointToBounds(b->mins, mins, maxs);
00388 AddPointToBounds(b->maxs, mins, maxs);
00389 }
00390
00391 VectorCopy(mins, mod->mins);
00392 VectorCopy(maxs, mod->maxs);
00393 }
00394
00395
00400 void EndModel (void)
00401 {
00402 dBspModel_t *mod;
00403
00404
00405 mod = &curTile->models[curTile->nummodels];
00406 mod->numfaces = curTile->numfaces - mod->firstface;
00407
00408
00409 curTile->nummodels++;
00410 }