writebsp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake 2 Tools source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qbsp.h"
  19. int c_nofaces;
  20. int c_facenodes;
  21. /*
  22. =========================================================
  23. ONLY SAVE OUT PLANES THAT ARE ACTUALLY USED AS NODES
  24. =========================================================
  25. */
  26. int planeused[MAX_MAP_PLANES];
  27. /*
  28. ============
  29. EmitPlanes
  30. There is no oportunity to discard planes, because all of the original
  31. brushes will be saved in the map.
  32. ============
  33. */
  34. void EmitPlanes (void)
  35. {
  36. int i;
  37. dplane_t *dp;
  38. plane_t *mp;
  39. int planetranslate[MAX_MAP_PLANES];
  40. mp = mapplanes;
  41. for (i=0 ; i<nummapplanes ; i++, mp++)
  42. {
  43. dp = &dplanes[numplanes];
  44. planetranslate[i] = numplanes;
  45. VectorCopy ( mp->normal, dp->normal);
  46. dp->dist = mp->dist;
  47. dp->type = mp->type;
  48. numplanes++;
  49. }
  50. }
  51. //========================================================
  52. void EmitMarkFace (dleaf_t *leaf_p, face_t *f)
  53. {
  54. int i;
  55. int facenum;
  56. while (f->merged)
  57. f = f->merged;
  58. if (f->split[0])
  59. {
  60. EmitMarkFace (leaf_p, f->split[0]);
  61. EmitMarkFace (leaf_p, f->split[1]);
  62. return;
  63. }
  64. facenum = f->outputnumber;
  65. if (facenum == -1)
  66. return; // degenerate face
  67. if (facenum < 0 || facenum >= numfaces)
  68. Error ("Bad leafface");
  69. for (i=leaf_p->firstleafface ; i<numleaffaces ; i++)
  70. if (dleaffaces[i] == facenum)
  71. break; // merged out face
  72. if (i == numleaffaces)
  73. {
  74. if (numleaffaces >= MAX_MAP_LEAFFACES)
  75. Error ("MAX_MAP_LEAFFACES");
  76. dleaffaces[numleaffaces] = facenum;
  77. numleaffaces++;
  78. }
  79. }
  80. /*
  81. ==================
  82. EmitLeaf
  83. ==================
  84. */
  85. void EmitLeaf (node_t *node)
  86. {
  87. dleaf_t *leaf_p;
  88. portal_t *p;
  89. int s;
  90. face_t *f;
  91. bspbrush_t *b;
  92. int i;
  93. int brushnum;
  94. // emit a leaf
  95. if (numleafs >= MAX_MAP_LEAFS)
  96. Error ("MAX_MAP_LEAFS");
  97. leaf_p = &dleafs[numleafs];
  98. numleafs++;
  99. leaf_p->contents = node->contents;
  100. leaf_p->cluster = node->cluster;
  101. leaf_p->area = node->area;
  102. //
  103. // write bounding box info
  104. //
  105. VectorCopy (node->mins, leaf_p->mins);
  106. VectorCopy (node->maxs, leaf_p->maxs);
  107. //
  108. // write the leafbrushes
  109. //
  110. leaf_p->firstleafbrush = numleafbrushes;
  111. for (b=node->brushlist ; b ; b=b->next)
  112. {
  113. if (numleafbrushes >= MAX_MAP_LEAFBRUSHES)
  114. Error ("MAX_MAP_LEAFBRUSHES");
  115. brushnum = b->original - mapbrushes;
  116. for (i=leaf_p->firstleafbrush ; i<numleafbrushes ; i++)
  117. if (dleafbrushes[i] == brushnum)
  118. break;
  119. if (i == numleafbrushes)
  120. {
  121. dleafbrushes[numleafbrushes] = brushnum;
  122. numleafbrushes++;
  123. }
  124. }
  125. leaf_p->numleafbrushes = numleafbrushes - leaf_p->firstleafbrush;
  126. //
  127. // write the leaffaces
  128. //
  129. if (leaf_p->contents & CONTENTS_SOLID)
  130. return; // no leaffaces in solids
  131. leaf_p->firstleafface = numleaffaces;
  132. for (p = node->portals ; p ; p = p->next[s])
  133. {
  134. s = (p->nodes[1] == node);
  135. f = p->face[s];
  136. if (!f)
  137. continue; // not a visible portal
  138. EmitMarkFace (leaf_p, f);
  139. }
  140. leaf_p->numleaffaces = numleaffaces - leaf_p->firstleafface;
  141. }
  142. /*
  143. ==================
  144. EmitFace
  145. ==================
  146. */
  147. void EmitFace (face_t *f)
  148. {
  149. dface_t *df;
  150. int i;
  151. int e;
  152. f->outputnumber = -1;
  153. if (f->numpoints < 3)
  154. {
  155. return; // degenerated
  156. }
  157. if (f->merged || f->split[0] || f->split[1])
  158. {
  159. return; // not a final face
  160. }
  161. // save output number so leaffaces can use
  162. f->outputnumber = numfaces;
  163. if (numfaces >= MAX_MAP_FACES)
  164. Error ("numfaces == MAX_MAP_FACES");
  165. df = &dfaces[numfaces];
  166. numfaces++;
  167. // planenum is used by qlight, but not quake
  168. df->planenum = f->planenum & (~1);
  169. df->side = f->planenum & 1;
  170. df->firstedge = numsurfedges;
  171. df->numedges = f->numpoints;
  172. df->texinfo = f->texinfo;
  173. for (i=0 ; i<f->numpoints ; i++)
  174. {
  175. // e = GetEdge (f->pts[i], f->pts[(i+1)%f->numpoints], f);
  176. e = GetEdge2 (f->vertexnums[i], f->vertexnums[(i+1)%f->numpoints], f);
  177. if (numsurfedges >= MAX_MAP_SURFEDGES)
  178. Error ("numsurfedges == MAX_MAP_SURFEDGES");
  179. dsurfedges[numsurfedges] = e;
  180. numsurfedges++;
  181. }
  182. }
  183. /*
  184. ============
  185. EmitDrawingNode_r
  186. ============
  187. */
  188. int EmitDrawNode_r (node_t *node)
  189. {
  190. dnode_t *n;
  191. face_t *f;
  192. int i;
  193. if (node->planenum == PLANENUM_LEAF)
  194. {
  195. EmitLeaf (node);
  196. return -numleafs;
  197. }
  198. // emit a node
  199. if (numnodes == MAX_MAP_NODES)
  200. Error ("MAX_MAP_NODES");
  201. n = &dnodes[numnodes];
  202. numnodes++;
  203. VectorCopy (node->mins, n->mins);
  204. VectorCopy (node->maxs, n->maxs);
  205. planeused[node->planenum]++;
  206. planeused[node->planenum^1]++;
  207. if (node->planenum & 1)
  208. Error ("WriteDrawNodes_r: odd planenum");
  209. n->planenum = node->planenum;
  210. n->firstface = numfaces;
  211. if (!node->faces)
  212. c_nofaces++;
  213. else
  214. c_facenodes++;
  215. for (f=node->faces ; f ; f=f->next)
  216. EmitFace (f);
  217. n->numfaces = numfaces - n->firstface;
  218. //
  219. // recursively output the other nodes
  220. //
  221. for (i=0 ; i<2 ; i++)
  222. {
  223. if (node->children[i]->planenum == PLANENUM_LEAF)
  224. {
  225. n->children[i] = -(numleafs + 1);
  226. EmitLeaf (node->children[i]);
  227. }
  228. else
  229. {
  230. n->children[i] = numnodes;
  231. EmitDrawNode_r (node->children[i]);
  232. }
  233. }
  234. return n - dnodes;
  235. }
  236. //=========================================================
  237. /*
  238. ============
  239. WriteBSP
  240. ============
  241. */
  242. void WriteBSP (node_t *headnode)
  243. {
  244. int oldfaces;
  245. c_nofaces = 0;
  246. c_facenodes = 0;
  247. qprintf ("--- WriteBSP ---\n");
  248. oldfaces = numfaces;
  249. dmodels[nummodels].headnode = EmitDrawNode_r (headnode);
  250. EmitAreaPortals (headnode);
  251. qprintf ("%5i nodes with faces\n", c_facenodes);
  252. qprintf ("%5i nodes without faces\n", c_nofaces);
  253. qprintf ("%5i faces\n", numfaces-oldfaces);
  254. }
  255. //===========================================================
  256. /*
  257. ============
  258. SetModelNumbers
  259. ============
  260. */
  261. void SetModelNumbers (void)
  262. {
  263. int i;
  264. int models;
  265. char value[10];
  266. models = 1;
  267. for (i=1 ; i<num_entities ; i++)
  268. {
  269. if (entities[i].numbrushes)
  270. {
  271. sprintf (value, "*%i", models);
  272. models++;
  273. SetKeyValue (&entities[i], "model", value);
  274. }
  275. }
  276. }
  277. /*
  278. ============
  279. SetLightStyles
  280. ============
  281. */
  282. #define MAX_SWITCHED_LIGHTS 32
  283. void SetLightStyles (void)
  284. {
  285. int stylenum;
  286. char *t;
  287. entity_t *e;
  288. int i, j;
  289. char value[10];
  290. char lighttargets[MAX_SWITCHED_LIGHTS][64];
  291. // any light that is controlled (has a targetname)
  292. // must have a unique style number generated for it
  293. stylenum = 0;
  294. for (i=1 ; i<num_entities ; i++)
  295. {
  296. e = &entities[i];
  297. t = ValueForKey (e, "classname");
  298. if (Q_strncasecmp (t, "light", 5))
  299. continue;
  300. t = ValueForKey (e, "targetname");
  301. if (!t[0])
  302. continue;
  303. // find this targetname
  304. for (j=0 ; j<stylenum ; j++)
  305. if (!strcmp (lighttargets[j], t))
  306. break;
  307. if (j == stylenum)
  308. {
  309. if (stylenum == MAX_SWITCHED_LIGHTS)
  310. Error ("stylenum == MAX_SWITCHED_LIGHTS");
  311. strcpy (lighttargets[j], t);
  312. stylenum++;
  313. }
  314. sprintf (value, "%i", 32 + j);
  315. SetKeyValue (e, "style", value);
  316. }
  317. }
  318. //===========================================================
  319. /*
  320. ============
  321. EmitBrushes
  322. ============
  323. */
  324. void EmitBrushes (void)
  325. {
  326. int i, j, bnum, s, x;
  327. dbrush_t *db;
  328. mapbrush_t *b;
  329. dbrushside_t *cp;
  330. vec3_t normal;
  331. vec_t dist;
  332. int planenum;
  333. numbrushsides = 0;
  334. numbrushes = nummapbrushes;
  335. for (bnum=0 ; bnum<nummapbrushes ; bnum++)
  336. {
  337. b = &mapbrushes[bnum];
  338. db = &dbrushes[bnum];
  339. db->contents = b->contents;
  340. db->firstside = numbrushsides;
  341. db->numsides = b->numsides;
  342. for (j=0 ; j<b->numsides ; j++)
  343. {
  344. if (numbrushsides == MAX_MAP_BRUSHSIDES)
  345. Error ("MAX_MAP_BRUSHSIDES");
  346. cp = &dbrushsides[numbrushsides];
  347. numbrushsides++;
  348. cp->planenum = b->original_sides[j].planenum;
  349. cp->texinfo = b->original_sides[j].texinfo;
  350. }
  351. // add any axis planes not contained in the brush to bevel off corners
  352. for (x=0 ; x<3 ; x++)
  353. for (s=-1 ; s<=1 ; s+=2)
  354. {
  355. // add the plane
  356. VectorCopy (vec3_origin, normal);
  357. normal[x] = s;
  358. if (s == -1)
  359. dist = -b->mins[x];
  360. else
  361. dist = b->maxs[x];
  362. planenum = FindFloatPlane (normal, dist);
  363. for (i=0 ; i<b->numsides ; i++)
  364. if (b->original_sides[i].planenum == planenum)
  365. break;
  366. if (i == b->numsides)
  367. {
  368. if (numbrushsides >= MAX_MAP_BRUSHSIDES)
  369. Error ("MAX_MAP_BRUSHSIDES");
  370. dbrushsides[numbrushsides].planenum = planenum;
  371. dbrushsides[numbrushsides].texinfo =
  372. dbrushsides[numbrushsides-1].texinfo;
  373. numbrushsides++;
  374. db->numsides++;
  375. }
  376. }
  377. }
  378. }
  379. //===========================================================
  380. /*
  381. ==================
  382. BeginBSPFile
  383. ==================
  384. */
  385. void BeginBSPFile (void)
  386. {
  387. // these values may actually be initialized
  388. // if the file existed when loaded, so clear them explicitly
  389. nummodels = 0;
  390. numfaces = 0;
  391. numnodes = 0;
  392. numbrushsides = 0;
  393. numvertexes = 0;
  394. numleaffaces = 0;
  395. numleafbrushes = 0;
  396. numsurfedges = 0;
  397. // edge 0 is not used, because 0 can't be negated
  398. numedges = 1;
  399. // leave vertex 0 as an error
  400. numvertexes = 1;
  401. // leave leaf 0 as an error
  402. numleafs = 1;
  403. dleafs[0].contents = CONTENTS_SOLID;
  404. }
  405. /*
  406. ============
  407. EndBSPFile
  408. ============
  409. */
  410. void EndBSPFile (void)
  411. {
  412. char path[1024];
  413. int len;
  414. byte *buf;
  415. EmitBrushes ();
  416. EmitPlanes ();
  417. UnparseEntities ();
  418. // load the pop
  419. #if 0
  420. sprintf (path, "%s/pics/pop.lmp", gamedir);
  421. len = LoadFile (path, &buf);
  422. memcpy (dpop, buf, sizeof(dpop));
  423. free (buf);
  424. #endif
  425. // write the map
  426. sprintf (path, "%s.bsp", source);
  427. printf ("Writing %s\n", path);
  428. WriteBSPFile (path);
  429. }
  430. /*
  431. ==================
  432. BeginModel
  433. ==================
  434. */
  435. int firstmodleaf;
  436. extern int firstmodeledge;
  437. extern int firstmodelface;
  438. void BeginModel (void)
  439. {
  440. dmodel_t *mod;
  441. int start, end;
  442. mapbrush_t *b;
  443. int j;
  444. entity_t *e;
  445. vec3_t mins, maxs;
  446. if (nummodels == MAX_MAP_MODELS)
  447. Error ("MAX_MAP_MODELS");
  448. mod = &dmodels[nummodels];
  449. mod->firstface = numfaces;
  450. firstmodleaf = numleafs;
  451. firstmodeledge = numedges;
  452. firstmodelface = numfaces;
  453. //
  454. // bound the brushes
  455. //
  456. e = &entities[entity_num];
  457. start = e->firstbrush;
  458. end = start + e->numbrushes;
  459. ClearBounds (mins, maxs);
  460. for (j=start ; j<end ; j++)
  461. {
  462. b = &mapbrushes[j];
  463. if (!b->numsides)
  464. continue; // not a real brush (origin brush)
  465. AddPointToBounds (b->mins, mins, maxs);
  466. AddPointToBounds (b->maxs, mins, maxs);
  467. }
  468. VectorCopy (mins, mod->mins);
  469. VectorCopy (maxs, mod->maxs);
  470. }
  471. /*
  472. ==================
  473. EndModel
  474. ==================
  475. */
  476. void EndModel (void)
  477. {
  478. dmodel_t *mod;
  479. mod = &dmodels[nummodels];
  480. mod->numfaces = numfaces - mod->firstface;
  481. nummodels++;
  482. }