writebsp.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena 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 III Arena 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 Foobar; 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. /*
  20. ============
  21. EmitShader
  22. ============
  23. */
  24. int EmitShader( const char *shader ) {
  25. int i;
  26. shaderInfo_t *si;
  27. if ( !shader ) {
  28. shader = "noshader";
  29. }
  30. for ( i = 0 ; i < numShaders ; i++ ) {
  31. if ( !Q_stricmp( shader, dshaders[i].shader ) ) {
  32. return i;
  33. }
  34. }
  35. if ( i == MAX_MAP_SHADERS ) {
  36. Error( "MAX_MAP_SHADERS" );
  37. }
  38. numShaders++;
  39. strcpy( dshaders[i].shader, shader );
  40. si = ShaderInfoForShader( shader );
  41. dshaders[i].surfaceFlags = si->surfaceFlags;
  42. dshaders[i].contentFlags = si->contents;
  43. return i;
  44. }
  45. /*
  46. ============
  47. EmitPlanes
  48. There is no oportunity to discard planes, because all of the original
  49. brushes will be saved in the map.
  50. ============
  51. */
  52. void EmitPlanes (void)
  53. {
  54. int i;
  55. dplane_t *dp;
  56. plane_t *mp;
  57. mp = mapplanes;
  58. for (i=0 ; i<nummapplanes ; i++, mp++)
  59. {
  60. dp = &dplanes[numplanes];
  61. VectorCopy ( mp->normal, dp->normal);
  62. dp->dist = mp->dist;
  63. numplanes++;
  64. }
  65. }
  66. /*
  67. ==================
  68. EmitLeaf
  69. ==================
  70. */
  71. void EmitLeaf (node_t *node)
  72. {
  73. dleaf_t *leaf_p;
  74. bspbrush_t *b;
  75. drawSurfRef_t *dsr;
  76. // emit a leaf
  77. if (numleafs >= MAX_MAP_LEAFS)
  78. Error ("MAX_MAP_LEAFS");
  79. leaf_p = &dleafs[numleafs];
  80. numleafs++;
  81. leaf_p->cluster = node->cluster;
  82. leaf_p->area = node->area;
  83. //
  84. // write bounding box info
  85. //
  86. VectorCopy (node->mins, leaf_p->mins);
  87. VectorCopy (node->maxs, leaf_p->maxs);
  88. //
  89. // write the leafbrushes
  90. //
  91. leaf_p->firstLeafBrush = numleafbrushes;
  92. for ( b = node->brushlist ; b ; b = b->next ) {
  93. if ( numleafbrushes >= MAX_MAP_LEAFBRUSHES ) {
  94. Error( "MAX_MAP_LEAFBRUSHES" );
  95. }
  96. dleafbrushes[numleafbrushes] = b->original->outputNumber;
  97. numleafbrushes++;
  98. }
  99. leaf_p->numLeafBrushes = numleafbrushes - leaf_p->firstLeafBrush;
  100. //
  101. // write the surfaces visible in this leaf
  102. //
  103. if ( node->opaque ) {
  104. return; // no leaffaces in solids
  105. }
  106. // add the drawSurfRef_t drawsurfs
  107. leaf_p->firstLeafSurface = numleafsurfaces;
  108. for ( dsr = node->drawSurfReferences ; dsr ; dsr = dsr->nextRef ) {
  109. if ( numleafsurfaces >= MAX_MAP_LEAFFACES)
  110. Error ("MAX_MAP_LEAFFACES");
  111. dleafsurfaces[numleafsurfaces] = dsr->outputNumber;
  112. numleafsurfaces++;
  113. }
  114. leaf_p->numLeafSurfaces = numleafsurfaces - leaf_p->firstLeafSurface;
  115. }
  116. /*
  117. ============
  118. EmitDrawNode_r
  119. ============
  120. */
  121. int EmitDrawNode_r (node_t *node)
  122. {
  123. dnode_t *n;
  124. int i;
  125. if (node->planenum == PLANENUM_LEAF)
  126. {
  127. EmitLeaf (node);
  128. return -numleafs;
  129. }
  130. // emit a node
  131. if (numnodes == MAX_MAP_NODES)
  132. Error ("MAX_MAP_NODES");
  133. n = &dnodes[numnodes];
  134. numnodes++;
  135. VectorCopy (node->mins, n->mins);
  136. VectorCopy (node->maxs, n->maxs);
  137. if (node->planenum & 1)
  138. Error ("WriteDrawNodes_r: odd planenum");
  139. n->planeNum = node->planenum;
  140. //
  141. // recursively output the other nodes
  142. //
  143. for (i=0 ; i<2 ; i++)
  144. {
  145. if (node->children[i]->planenum == PLANENUM_LEAF)
  146. {
  147. n->children[i] = -(numleafs + 1);
  148. EmitLeaf (node->children[i]);
  149. }
  150. else
  151. {
  152. n->children[i] = numnodes;
  153. EmitDrawNode_r (node->children[i]);
  154. }
  155. }
  156. return n - dnodes;
  157. }
  158. //=========================================================
  159. /*
  160. ============
  161. SetModelNumbers
  162. ============
  163. */
  164. void SetModelNumbers (void)
  165. {
  166. int i;
  167. int models;
  168. char value[10];
  169. models = 1;
  170. for ( i=1 ; i<num_entities ; i++ ) {
  171. if ( entities[i].brushes || entities[i].patches ) {
  172. sprintf ( value, "*%i", models );
  173. models++;
  174. SetKeyValue (&entities[i], "model", value);
  175. }
  176. }
  177. }
  178. /*
  179. ============
  180. SetLightStyles
  181. ============
  182. */
  183. #define MAX_SWITCHED_LIGHTS 32
  184. void SetLightStyles (void)
  185. {
  186. int stylenum;
  187. const char *t;
  188. entity_t *e;
  189. int i, j;
  190. char value[10];
  191. char lighttargets[MAX_SWITCHED_LIGHTS][64];
  192. // any light that is controlled (has a targetname)
  193. // must have a unique style number generated for it
  194. stylenum = 0;
  195. for (i=1 ; i<num_entities ; i++)
  196. {
  197. e = &entities[i];
  198. t = ValueForKey (e, "classname");
  199. if (Q_strncasecmp (t, "light", 5))
  200. continue;
  201. t = ValueForKey (e, "targetname");
  202. if (!t[0])
  203. continue;
  204. // find this targetname
  205. for (j=0 ; j<stylenum ; j++)
  206. if (!strcmp (lighttargets[j], t))
  207. break;
  208. if (j == stylenum)
  209. {
  210. if (stylenum == MAX_SWITCHED_LIGHTS)
  211. Error ("stylenum == MAX_SWITCHED_LIGHTS");
  212. strcpy (lighttargets[j], t);
  213. stylenum++;
  214. }
  215. sprintf (value, "%i", 32 + j);
  216. SetKeyValue (e, "style", value);
  217. }
  218. }
  219. //===========================================================
  220. /*
  221. ==================
  222. BeginBSPFile
  223. ==================
  224. */
  225. void BeginBSPFile( void ) {
  226. // these values may actually be initialized
  227. // if the file existed when loaded, so clear them explicitly
  228. nummodels = 0;
  229. numnodes = 0;
  230. numbrushsides = 0;
  231. numleafsurfaces = 0;
  232. numleafbrushes = 0;
  233. // leave leaf 0 as an error, because leafs are referenced as
  234. // negative number nodes
  235. numleafs = 1;
  236. }
  237. /*
  238. ============
  239. EndBSPFile
  240. ============
  241. */
  242. void EndBSPFile( void ) {
  243. char path[1024];
  244. EmitPlanes ();
  245. UnparseEntities ();
  246. // write the map
  247. sprintf (path, "%s.bsp", source);
  248. _printf ("Writing %s\n", path);
  249. WriteBSPFile (path);
  250. }
  251. //===========================================================
  252. /*
  253. ============
  254. EmitBrushes
  255. ============
  256. */
  257. void EmitBrushes ( bspbrush_t *brushes ) {
  258. int j;
  259. dbrush_t *db;
  260. bspbrush_t *b;
  261. dbrushside_t *cp;
  262. for ( b = brushes ; b ; b = b->next ) {
  263. if ( numbrushes == MAX_MAP_BRUSHES ) {
  264. Error( "MAX_MAP_BRUSHES" );
  265. }
  266. b->outputNumber = numbrushes;
  267. db = &dbrushes[numbrushes];
  268. numbrushes++;
  269. db->shaderNum = EmitShader( b->contentShader->shader );
  270. db->firstSide = numbrushsides;
  271. // don't emit any generated backSide sides
  272. db->numSides = 0;
  273. for ( j=0 ; j<b->numsides ; j++ ) {
  274. if ( b->sides[j].backSide ) {
  275. continue;
  276. }
  277. if ( numbrushsides == MAX_MAP_BRUSHSIDES ) {
  278. Error( "MAX_MAP_BRUSHSIDES ");
  279. }
  280. cp = &dbrushsides[numbrushsides];
  281. db->numSides++;
  282. numbrushsides++;
  283. cp->planeNum = b->sides[j].planenum;
  284. cp->shaderNum = EmitShader( b->sides[j].shaderInfo->shader );
  285. }
  286. }
  287. }
  288. /*
  289. ==================
  290. BeginModel
  291. ==================
  292. */
  293. void BeginModel( void ) {
  294. dmodel_t *mod;
  295. bspbrush_t *b;
  296. entity_t *e;
  297. vec3_t mins, maxs;
  298. parseMesh_t *p;
  299. int i;
  300. if ( nummodels == MAX_MAP_MODELS ) {
  301. Error( "MAX_MAP_MODELS" );
  302. }
  303. mod = &dmodels[nummodels];
  304. //
  305. // bound the brushes
  306. //
  307. e = &entities[entity_num];
  308. ClearBounds (mins, maxs);
  309. for ( b = e->brushes ; b ; b = b->next ) {
  310. if ( !b->numsides ) {
  311. continue; // not a real brush (origin brush, etc)
  312. }
  313. AddPointToBounds (b->mins, mins, maxs);
  314. AddPointToBounds (b->maxs, mins, maxs);
  315. }
  316. for ( p = e->patches ; p ; p = p->next ) {
  317. for ( i = 0 ; i < p->mesh.width * p->mesh.height ; i++ ) {
  318. AddPointToBounds( p->mesh.verts[i].xyz, mins, maxs );
  319. }
  320. }
  321. VectorCopy (mins, mod->mins);
  322. VectorCopy (maxs, mod->maxs);
  323. mod->firstSurface = numDrawSurfaces;
  324. mod->firstBrush = numbrushes;
  325. EmitBrushes( e->brushes );
  326. }
  327. /*
  328. ==================
  329. EndModel
  330. ==================
  331. */
  332. void EndModel( node_t *headnode ) {
  333. dmodel_t *mod;
  334. qprintf ("--- EndModel ---\n");
  335. mod = &dmodels[nummodels];
  336. EmitDrawNode_r (headnode);
  337. mod->numSurfaces = numDrawSurfaces - mod->firstSurface;
  338. mod->numBrushes = numbrushes - mod->firstBrush;
  339. nummodels++;
  340. }