map_q2.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163
  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. //===========================================================================
  19. // ANSI, Area Navigational System Interface
  20. // AAS, Area Awareness System
  21. //===========================================================================
  22. #include "qbsp.h"
  23. #include "l_mem.h"
  24. #include "../botlib/aasfile.h" //aas_bbox_t
  25. #include "aas_store.h" //AAS_MAX_BBOXES
  26. #include "aas_cfg.h"
  27. #include "aas_map.h" //AAS_CreateMapBrushes
  28. #include "l_bsp_q2.h"
  29. #ifdef ME
  30. #define NODESTACKSIZE 1024
  31. int nodestack[NODESTACKSIZE];
  32. int *nodestackptr;
  33. int nodestacksize = 0;
  34. int brushmodelnumbers[MAX_MAPFILE_BRUSHES];
  35. int dbrushleafnums[MAX_MAPFILE_BRUSHES];
  36. int dplanes2mapplanes[MAX_MAPFILE_PLANES];
  37. #endif //ME
  38. //====================================================================
  39. //===========================================================================
  40. //
  41. // Parameter: -
  42. // Returns: -
  43. // Changes Globals: -
  44. //===========================================================================
  45. void Q2_CreateMapTexinfo(void)
  46. {
  47. int i;
  48. for (i = 0; i < numtexinfo; i++)
  49. {
  50. memcpy(map_texinfo[i].vecs, texinfo[i].vecs, sizeof(float) * 2 * 4);
  51. map_texinfo[i].flags = texinfo[i].flags;
  52. map_texinfo[i].value = texinfo[i].value;
  53. strcpy(map_texinfo[i].texture, texinfo[i].texture);
  54. map_texinfo[i].nexttexinfo = 0;
  55. } //end for
  56. } //end of the function Q2_CreateMapTexinfo
  57. /*
  58. ===========
  59. Q2_BrushContents
  60. ===========
  61. */
  62. int Q2_BrushContents (mapbrush_t *b)
  63. {
  64. int contents;
  65. side_t *s;
  66. int i;
  67. int trans;
  68. s = &b->original_sides[0];
  69. contents = s->contents;
  70. trans = texinfo[s->texinfo].flags;
  71. for (i = 1; i < b->numsides; i++, s++)
  72. {
  73. s = &b->original_sides[i];
  74. trans |= texinfo[s->texinfo].flags;
  75. if (s->contents != contents)
  76. {
  77. Log_Print("Entity %i, Brush %i: mixed face contents\n"
  78. , b->entitynum, b->brushnum);
  79. Log_Print("texture name = %s\n", texinfo[s->texinfo].texture);
  80. break;
  81. }
  82. }
  83. // if any side is translucent, mark the contents
  84. // and change solid to window
  85. if ( trans & (SURF_TRANS33|SURF_TRANS66) )
  86. {
  87. contents |= CONTENTS_Q2TRANSLUCENT;
  88. if (contents & CONTENTS_SOLID)
  89. {
  90. contents &= ~CONTENTS_SOLID;
  91. contents |= CONTENTS_WINDOW;
  92. }
  93. }
  94. return contents;
  95. }
  96. #ifdef ME
  97. #define BBOX_NORMAL_EPSILON 0.0001
  98. //===========================================================================
  99. //
  100. // Parameter: -
  101. // Returns: -
  102. // Changes Globals: -
  103. //===========================================================================
  104. void MakeAreaPortalBrush(mapbrush_t *brush)
  105. {
  106. int sn;
  107. side_t *s;
  108. brush->contents = CONTENTS_AREAPORTAL;
  109. for (sn = 0; sn < brush->numsides; sn++)
  110. {
  111. s = brush->original_sides + sn;
  112. //make sure the surfaces are not hint or skip
  113. s->surf &= ~(SURF_HINT|SURF_SKIP);
  114. //
  115. s->texinfo = 0;
  116. s->contents = CONTENTS_AREAPORTAL;
  117. } //end for
  118. } //end of the function MakeAreaPortalBrush
  119. //===========================================================================
  120. //
  121. // Parameter: -
  122. // Returns: -
  123. // Changes Globals: -
  124. //===========================================================================
  125. void DPlanes2MapPlanes(void)
  126. {
  127. int i;
  128. for (i = 0; i < numplanes; i++)
  129. {
  130. dplanes2mapplanes[i] = FindFloatPlane(dplanes[i].normal, dplanes[i].dist);
  131. } //end for
  132. } //end of the function DPlanes2MapPlanes
  133. //===========================================================================
  134. //
  135. // Parameter: -
  136. // Returns: -
  137. // Changes Globals: -
  138. //===========================================================================
  139. void MarkVisibleBrushSides(mapbrush_t *brush)
  140. {
  141. int n, i, planenum;
  142. side_t *side;
  143. dface_t *face;
  144. //
  145. for (n = 0; n < brush->numsides; n++)
  146. {
  147. side = brush->original_sides + n;
  148. //if this side is a bevel or the leaf number of the brush is unknown
  149. if ((side->flags & SFL_BEVEL) || brush->leafnum < 0)
  150. {
  151. //this side is a valid splitter
  152. side->flags |= SFL_VISIBLE;
  153. continue;
  154. } //end if
  155. //assum this side will not be used as a splitter
  156. side->flags &= ~SFL_VISIBLE;
  157. //check if the side plane is used by a visible face
  158. for (i = 0; i < numfaces; i++)
  159. {
  160. face = &dfaces[i];
  161. planenum = dplanes2mapplanes[face->planenum];
  162. if ((planenum & ~1) == (side->planenum & ~1))
  163. {
  164. //this side is a valid splitter
  165. side->flags |= SFL_VISIBLE;
  166. } //end if
  167. } //end for
  168. } //end for
  169. } //end of the function MarkVisibleBrushSides
  170. #endif //ME
  171. /*
  172. =================
  173. Q2_ParseBrush
  174. =================
  175. */
  176. void Q2_ParseBrush (script_t *script, entity_t *mapent)
  177. {
  178. mapbrush_t *b;
  179. int i, j, k;
  180. int mt;
  181. side_t *side, *s2;
  182. int planenum;
  183. brush_texture_t td;
  184. int planepts[3][3];
  185. token_t token;
  186. if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
  187. Error ("nummapbrushes == MAX_MAPFILE_BRUSHES");
  188. b = &mapbrushes[nummapbrushes];
  189. b->original_sides = &brushsides[nummapbrushsides];
  190. b->entitynum = num_entities-1;
  191. b->brushnum = nummapbrushes - mapent->firstbrush;
  192. b->leafnum = -1;
  193. do
  194. {
  195. if (!PS_ReadToken(script, &token))
  196. break;
  197. if (!strcmp(token.string, "}") )
  198. break;
  199. //IDBUG: mixed use of MAX_MAPFILE_? and MAX_MAP_? this could
  200. // lead to out of bound indexing of the arrays
  201. if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
  202. Error ("MAX_MAPFILE_BRUSHSIDES");
  203. side = &brushsides[nummapbrushsides];
  204. //read the three point plane definition
  205. for (i = 0; i < 3; i++)
  206. {
  207. if (i != 0) PS_ExpectTokenString(script, "(");
  208. for (j = 0; j < 3; j++)
  209. {
  210. PS_ExpectAnyToken(script, &token);
  211. planepts[i][j] = atof(token.string);
  212. } //end for
  213. PS_ExpectTokenString(script, ")");
  214. } //end for
  215. //
  216. //read the texturedef
  217. //
  218. PS_ExpectAnyToken(script, &token);
  219. strcpy(td.name, token.string);
  220. PS_ExpectAnyToken(script, &token);
  221. td.shift[0] = atol(token.string);
  222. PS_ExpectAnyToken(script, &token);
  223. td.shift[1] = atol(token.string);
  224. PS_ExpectAnyToken(script, &token);
  225. td.rotate = atol(token.string);
  226. PS_ExpectAnyToken(script, &token);
  227. td.scale[0] = atof(token.string);
  228. PS_ExpectAnyToken(script, &token);
  229. td.scale[1] = atof(token.string);
  230. //find default flags and values
  231. mt = FindMiptex (td.name);
  232. td.flags = textureref[mt].flags;
  233. td.value = textureref[mt].value;
  234. side->contents = textureref[mt].contents;
  235. side->surf = td.flags = textureref[mt].flags;
  236. //check if there's a number available
  237. if (PS_CheckTokenType(script, TT_NUMBER, 0, &token))
  238. {
  239. side->contents = token.intvalue;
  240. PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
  241. side->surf = td.flags = token.intvalue;
  242. PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
  243. td.value = token.intvalue;
  244. }
  245. // translucent objects are automatically classified as detail
  246. if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
  247. side->contents |= CONTENTS_DETAIL;
  248. if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
  249. side->contents |= CONTENTS_DETAIL;
  250. if (fulldetail)
  251. side->contents &= ~CONTENTS_DETAIL;
  252. if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1)
  253. | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) )
  254. side->contents |= CONTENTS_SOLID;
  255. // hints and skips are never detail, and have no content
  256. if (side->surf & (SURF_HINT|SURF_SKIP) )
  257. {
  258. side->contents = 0;
  259. side->surf &= ~CONTENTS_DETAIL;
  260. }
  261. #ifdef ME
  262. //for creating AAS... this side is textured
  263. side->flags |= SFL_TEXTURED;
  264. #endif //ME
  265. //
  266. // find the plane number
  267. //
  268. planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]);
  269. if (planenum == -1)
  270. {
  271. Log_Print("Entity %i, Brush %i: plane with no normal\n"
  272. , b->entitynum, b->brushnum);
  273. continue;
  274. }
  275. //
  276. // see if the plane has been used already
  277. //
  278. for (k=0 ; k<b->numsides ; k++)
  279. {
  280. s2 = b->original_sides + k;
  281. if (s2->planenum == planenum)
  282. {
  283. Log_Print("Entity %i, Brush %i: duplicate plane\n"
  284. , b->entitynum, b->brushnum);
  285. break;
  286. }
  287. if ( s2->planenum == (planenum^1) )
  288. {
  289. Log_Print("Entity %i, Brush %i: mirrored plane\n"
  290. , b->entitynum, b->brushnum);
  291. break;
  292. }
  293. }
  294. if (k != b->numsides)
  295. continue; // duplicated
  296. //
  297. // keep this side
  298. //
  299. side = b->original_sides + b->numsides;
  300. side->planenum = planenum;
  301. side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum],
  302. &td, vec3_origin);
  303. // save the td off in case there is an origin brush and we
  304. // have to recalculate the texinfo
  305. side_brushtextures[nummapbrushsides] = td;
  306. nummapbrushsides++;
  307. b->numsides++;
  308. } while (1);
  309. // get the content for the entire brush
  310. b->contents = Q2_BrushContents (b);
  311. #ifdef ME
  312. if (BrushExists(b))
  313. {
  314. c_squattbrushes++;
  315. b->numsides = 0;
  316. return;
  317. } //end if
  318. if (create_aas)
  319. {
  320. //create AAS brushes, and add brush bevels
  321. AAS_CreateMapBrushes(b, mapent, true);
  322. //NOTE: if we return here then duplicate plane errors occur for the non world entities
  323. return;
  324. } //end if
  325. #endif //ME
  326. // allow detail brushes to be removed
  327. if (nodetail && (b->contents & CONTENTS_DETAIL) )
  328. {
  329. b->numsides = 0;
  330. return;
  331. }
  332. // allow water brushes to be removed
  333. if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
  334. {
  335. b->numsides = 0;
  336. return;
  337. }
  338. // create windings for sides and bounds for brush
  339. MakeBrushWindings (b);
  340. // brushes that will not be visible at all will never be
  341. // used as bsp splitters
  342. if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
  343. {
  344. c_clipbrushes++;
  345. for (i=0 ; i<b->numsides ; i++)
  346. b->original_sides[i].texinfo = TEXINFO_NODE;
  347. }
  348. //
  349. // origin brushes are removed, but they set
  350. // the rotation origin for the rest of the brushes
  351. // in the entity. After the entire entity is parsed,
  352. // the planenums and texinfos will be adjusted for
  353. // the origin brush
  354. //
  355. if (b->contents & CONTENTS_ORIGIN)
  356. {
  357. char string[32];
  358. vec3_t origin;
  359. if (num_entities == 1)
  360. {
  361. Error ("Entity %i, Brush %i: origin brushes not allowed in world"
  362. , b->entitynum, b->brushnum);
  363. return;
  364. }
  365. VectorAdd (b->mins, b->maxs, origin);
  366. VectorScale (origin, 0.5, origin);
  367. sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
  368. SetKeyValue (&entities[b->entitynum], "origin", string);
  369. VectorCopy (origin, entities[b->entitynum].origin);
  370. // don't keep this brush
  371. b->numsides = 0;
  372. return;
  373. }
  374. AddBrushBevels(b);
  375. nummapbrushes++;
  376. mapent->numbrushes++;
  377. }
  378. /*
  379. ================
  380. Q2_MoveBrushesToWorld
  381. Takes all of the brushes from the current entity and
  382. adds them to the world's brush list.
  383. Used by func_group and func_areaportal
  384. ================
  385. */
  386. void Q2_MoveBrushesToWorld (entity_t *mapent)
  387. {
  388. int newbrushes;
  389. int worldbrushes;
  390. mapbrush_t *temp;
  391. int i;
  392. // this is pretty gross, because the brushes are expected to be
  393. // in linear order for each entity
  394. newbrushes = mapent->numbrushes;
  395. worldbrushes = entities[0].numbrushes;
  396. temp = GetMemory(newbrushes*sizeof(mapbrush_t));
  397. memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(mapbrush_t));
  398. #if 0 // let them keep their original brush numbers
  399. for (i=0 ; i<newbrushes ; i++)
  400. temp[i].entitynum = 0;
  401. #endif
  402. // make space to move the brushes (overlapped copy)
  403. memmove (mapbrushes + worldbrushes + newbrushes,
  404. mapbrushes + worldbrushes,
  405. sizeof(mapbrush_t) * (nummapbrushes - worldbrushes - newbrushes) );
  406. // copy the new brushes down
  407. memcpy (mapbrushes + worldbrushes, temp, sizeof(mapbrush_t) * newbrushes);
  408. // fix up indexes
  409. entities[0].numbrushes += newbrushes;
  410. for (i=1 ; i<num_entities ; i++)
  411. entities[i].firstbrush += newbrushes;
  412. FreeMemory(temp);
  413. mapent->numbrushes = 0;
  414. }
  415. /*
  416. ================
  417. Q2_ParseMapEntity
  418. ================
  419. */
  420. qboolean Q2_ParseMapEntity(script_t *script)
  421. {
  422. entity_t *mapent;
  423. epair_t *e;
  424. side_t *s;
  425. int i, j;
  426. int startbrush, startsides;
  427. vec_t newdist;
  428. mapbrush_t *b;
  429. token_t token;
  430. if (!PS_ReadToken(script, &token)) return false;
  431. if (strcmp(token.string, "{") )
  432. Error ("ParseEntity: { not found");
  433. if (num_entities == MAX_MAP_ENTITIES)
  434. Error ("num_entities == MAX_MAP_ENTITIES");
  435. startbrush = nummapbrushes;
  436. startsides = nummapbrushsides;
  437. mapent = &entities[num_entities];
  438. num_entities++;
  439. memset (mapent, 0, sizeof(*mapent));
  440. mapent->firstbrush = nummapbrushes;
  441. mapent->numbrushes = 0;
  442. // mapent->portalareas[0] = -1;
  443. // mapent->portalareas[1] = -1;
  444. do
  445. {
  446. if (!PS_ReadToken(script, &token))
  447. {
  448. Error("ParseEntity: EOF without closing brace");
  449. } //end if
  450. if (!strcmp(token.string, "}")) break;
  451. if (!strcmp(token.string, "{"))
  452. {
  453. Q2_ParseBrush(script, mapent);
  454. } //end if
  455. else
  456. {
  457. PS_UnreadLastToken(script);
  458. e = ParseEpair(script);
  459. e->next = mapent->epairs;
  460. mapent->epairs = e;
  461. } //end else
  462. } while(1);
  463. GetVectorForKey(mapent, "origin", mapent->origin);
  464. //
  465. // if there was an origin brush, offset all of the planes and texinfo
  466. //
  467. if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
  468. {
  469. for (i=0 ; i<mapent->numbrushes ; i++)
  470. {
  471. b = &mapbrushes[mapent->firstbrush + i];
  472. for (j=0 ; j<b->numsides ; j++)
  473. {
  474. s = &b->original_sides[j];
  475. newdist = mapplanes[s->planenum].dist -
  476. DotProduct (mapplanes[s->planenum].normal, mapent->origin);
  477. s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist);
  478. s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum],
  479. &side_brushtextures[s-brushsides], mapent->origin);
  480. }
  481. MakeBrushWindings (b);
  482. }
  483. }
  484. // group entities are just for editor convenience
  485. // toss all brushes into the world entity
  486. if (!strcmp ("func_group", ValueForKey (mapent, "classname")))
  487. {
  488. Q2_MoveBrushesToWorld (mapent);
  489. mapent->numbrushes = 0;
  490. return true;
  491. }
  492. // areaportal entities move their brushes, but don't eliminate
  493. // the entity
  494. if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
  495. {
  496. char str[128];
  497. if (mapent->numbrushes != 1)
  498. Error ("Entity %i: func_areaportal can only be a single brush", num_entities-1);
  499. b = &mapbrushes[nummapbrushes-1];
  500. b->contents = CONTENTS_AREAPORTAL;
  501. c_areaportals++;
  502. mapent->areaportalnum = c_areaportals;
  503. // set the portal number as "style"
  504. sprintf (str, "%i", c_areaportals);
  505. SetKeyValue (mapent, "style", str);
  506. Q2_MoveBrushesToWorld (mapent);
  507. return true;
  508. }
  509. return true;
  510. }
  511. //===================================================================
  512. /*
  513. ================
  514. LoadMapFile
  515. ================
  516. */
  517. void Q2_LoadMapFile(char *filename)
  518. {
  519. int i;
  520. script_t *script;
  521. Log_Print("-- Q2_LoadMapFile --\n");
  522. #ifdef ME
  523. //loaded map type
  524. loadedmaptype = MAPTYPE_QUAKE2;
  525. //reset the map loading
  526. ResetMapLoading();
  527. #endif //ME
  528. script = LoadScriptFile(filename);
  529. if (!script)
  530. {
  531. Log_Print("couldn't open %s\n", filename);
  532. return;
  533. } //end if
  534. //white spaces and escape characters inside a string are not allowed
  535. SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
  536. SCFL_NOSTRINGESCAPECHARS |
  537. SCFL_PRIMITIVE);
  538. nummapbrushsides = 0;
  539. num_entities = 0;
  540. while (Q2_ParseMapEntity(script))
  541. {
  542. }
  543. ClearBounds (map_mins, map_maxs);
  544. for (i=0 ; i<entities[0].numbrushes ; i++)
  545. {
  546. if (mapbrushes[i].mins[0] > 4096)
  547. continue; // no valid points
  548. AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
  549. AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
  550. } //end for
  551. PrintMapInfo();
  552. //free the script
  553. FreeScript(script);
  554. // TestExpandBrushes ();
  555. //
  556. Q2_CreateMapTexinfo();
  557. } //end of the function Q2_LoadMapFile
  558. #ifdef ME //Begin MAP loading from BSP file
  559. //===========================================================================
  560. //
  561. // Parameter: -
  562. // Returns: -
  563. // Changes Globals: -
  564. //===========================================================================
  565. void Q2_SetLeafBrushesModelNumbers(int leafnum, int modelnum)
  566. {
  567. int i, brushnum;
  568. dleaf_t *leaf;
  569. leaf = &dleafs[leafnum];
  570. for (i = 0; i < leaf->numleafbrushes; i++)
  571. {
  572. brushnum = dleafbrushes[leaf->firstleafbrush + i];
  573. brushmodelnumbers[brushnum] = modelnum;
  574. dbrushleafnums[brushnum] = leafnum;
  575. } //end for
  576. } //end of the function Q2_SetLeafBrushesModelNumbers
  577. //===========================================================================
  578. //
  579. // Parameter: -
  580. // Returns: -
  581. // Changes Globals: -
  582. //===========================================================================
  583. void Q2_InitNodeStack(void)
  584. {
  585. nodestackptr = nodestack;
  586. nodestacksize = 0;
  587. } //end of the function Q2_InitNodeStack
  588. //===========================================================================
  589. //
  590. // Parameter: -
  591. // Returns: -
  592. // Changes Globals: -
  593. //===========================================================================
  594. void Q2_PushNodeStack(int num)
  595. {
  596. *nodestackptr = num;
  597. nodestackptr++;
  598. nodestacksize++;
  599. //
  600. if (nodestackptr >= &nodestack[NODESTACKSIZE])
  601. {
  602. Error("Q2_PushNodeStack: stack overflow\n");
  603. } //end if
  604. } //end of the function Q2_PushNodeStack
  605. //===========================================================================
  606. //
  607. // Parameter: -
  608. // Returns: -
  609. // Changes Globals: -
  610. //===========================================================================
  611. int Q2_PopNodeStack(void)
  612. {
  613. //if the stack is empty
  614. if (nodestackptr <= nodestack) return -1;
  615. //decrease stack pointer
  616. nodestackptr--;
  617. nodestacksize--;
  618. //return the top value from the stack
  619. return *nodestackptr;
  620. } //end of the function Q2_PopNodeStack
  621. //===========================================================================
  622. //
  623. // Parameter: -
  624. // Returns: -
  625. // Changes Globals: -
  626. //===========================================================================
  627. void Q2_SetBrushModelNumbers(entity_t *mapent)
  628. {
  629. int n, pn;
  630. int leafnum;
  631. //
  632. Q2_InitNodeStack();
  633. //head node (root) of the bsp tree
  634. n = dmodels[mapent->modelnum].headnode;
  635. pn = 0;
  636. do
  637. {
  638. //if we are in a leaf (negative node number)
  639. if (n < 0)
  640. {
  641. //number of the leaf
  642. leafnum = (-n) - 1;
  643. //set the brush numbers
  644. Q2_SetLeafBrushesModelNumbers(leafnum, mapent->modelnum);
  645. //walk back into the tree to find a second child to continue with
  646. for (pn = Q2_PopNodeStack(); pn >= 0; n = pn, pn = Q2_PopNodeStack())
  647. {
  648. //if we took the first child at the parent node
  649. if (dnodes[pn].children[0] == n) break;
  650. } //end for
  651. //if the stack wasn't empty (if not processed whole tree)
  652. if (pn >= 0)
  653. {
  654. //push the parent node again
  655. Q2_PushNodeStack(pn);
  656. //we proceed with the second child of the parent node
  657. n = dnodes[pn].children[1];
  658. } //end if
  659. } //end if
  660. else
  661. {
  662. //push the current node onto the stack
  663. Q2_PushNodeStack(n);
  664. //walk forward into the tree to the first child
  665. n = dnodes[n].children[0];
  666. } //end else
  667. } while(pn >= 0);
  668. } //end of the function Q2_SetBrushModelNumbers
  669. //===========================================================================
  670. //
  671. // Parameter: -
  672. // Returns: -
  673. // Changes Globals: -
  674. //===========================================================================
  675. void Q2_BSPBrushToMapBrush(dbrush_t *bspbrush, entity_t *mapent)
  676. {
  677. mapbrush_t *b;
  678. int i, k, n;
  679. side_t *side, *s2;
  680. int planenum;
  681. dbrushside_t *bspbrushside;
  682. dplane_t *bspplane;
  683. if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
  684. Error ("nummapbrushes >= MAX_MAPFILE_BRUSHES");
  685. b = &mapbrushes[nummapbrushes];
  686. b->original_sides = &brushsides[nummapbrushsides];
  687. b->entitynum = mapent-entities;
  688. b->brushnum = nummapbrushes - mapent->firstbrush;
  689. b->leafnum = dbrushleafnums[bspbrush - dbrushes];
  690. for (n = 0; n < bspbrush->numsides; n++)
  691. {
  692. //pointer to the bsp brush side
  693. bspbrushside = &dbrushsides[bspbrush->firstside + n];
  694. if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
  695. {
  696. Error ("MAX_MAPFILE_BRUSHSIDES");
  697. } //end if
  698. //pointer to the map brush side
  699. side = &brushsides[nummapbrushsides];
  700. //if the BSP brush side is textured
  701. if (brushsidetextured[bspbrush->firstside + n]) side->flags |= SFL_TEXTURED;
  702. else side->flags &= ~SFL_TEXTURED;
  703. //ME: can get side contents and surf directly from BSP file
  704. side->contents = bspbrush->contents;
  705. //if the texinfo is TEXINFO_NODE
  706. if (bspbrushside->texinfo < 0) side->surf = 0;
  707. else side->surf = texinfo[bspbrushside->texinfo].flags;
  708. // translucent objects are automatically classified as detail
  709. if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
  710. side->contents |= CONTENTS_DETAIL;
  711. if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
  712. side->contents |= CONTENTS_DETAIL;
  713. if (fulldetail)
  714. side->contents &= ~CONTENTS_DETAIL;
  715. if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1)
  716. | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) )
  717. side->contents |= CONTENTS_SOLID;
  718. // hints and skips are never detail, and have no content
  719. if (side->surf & (SURF_HINT|SURF_SKIP) )
  720. {
  721. side->contents = 0;
  722. side->surf &= ~CONTENTS_DETAIL;
  723. }
  724. //ME: get a plane for this side
  725. bspplane = &dplanes[bspbrushside->planenum];
  726. planenum = FindFloatPlane(bspplane->normal, bspplane->dist);
  727. //
  728. // see if the plane has been used already
  729. //
  730. //ME: this really shouldn't happen!!!
  731. //ME: otherwise the bsp file is corrupted??
  732. //ME: still it seems to happen, maybe Johny Boy's
  733. //ME: brush bevel adding is crappy ?
  734. for (k = 0; k < b->numsides; k++)
  735. {
  736. s2 = b->original_sides + k;
  737. // if (DotProduct (mapplanes[s2->planenum].normal, mapplanes[planenum].normal) > 0.999
  738. // && fabs(mapplanes[s2->planenum].dist - mapplanes[planenum].dist) < 0.01 )
  739. if (s2->planenum == planenum)
  740. {
  741. Log_Print("Entity %i, Brush %i: duplicate plane\n"
  742. , b->entitynum, b->brushnum);
  743. break;
  744. }
  745. if ( s2->planenum == (planenum^1) )
  746. {
  747. Log_Print("Entity %i, Brush %i: mirrored plane\n"
  748. , b->entitynum, b->brushnum);
  749. break;
  750. }
  751. }
  752. if (k != b->numsides)
  753. continue; // duplicated
  754. //
  755. // keep this side
  756. //
  757. //ME: reset pointer to side, why? hell I dunno (pointer is set above already)
  758. side = b->original_sides + b->numsides;
  759. //ME: store the plane number
  760. side->planenum = planenum;
  761. //ME: texinfo is already stored when bsp is loaded
  762. //NOTE: check for TEXINFO_NODE, otherwise crash in Q2_BrushContents
  763. if (bspbrushside->texinfo < 0) side->texinfo = 0;
  764. else side->texinfo = bspbrushside->texinfo;
  765. // save the td off in case there is an origin brush and we
  766. // have to recalculate the texinfo
  767. // ME: don't need to recalculate because it's already done
  768. // (for non-world entities) in the BSP file
  769. // side_brushtextures[nummapbrushsides] = td;
  770. nummapbrushsides++;
  771. b->numsides++;
  772. } //end for
  773. // get the content for the entire brush
  774. b->contents = bspbrush->contents;
  775. Q2_BrushContents(b);
  776. if (BrushExists(b))
  777. {
  778. c_squattbrushes++;
  779. b->numsides = 0;
  780. return;
  781. } //end if
  782. //if we're creating AAS
  783. if (create_aas)
  784. {
  785. //create the AAS brushes from this brush, don't add brush bevels
  786. AAS_CreateMapBrushes(b, mapent, false);
  787. return;
  788. } //end if
  789. // allow detail brushes to be removed
  790. if (nodetail && (b->contents & CONTENTS_DETAIL) )
  791. {
  792. b->numsides = 0;
  793. return;
  794. } //end if
  795. // allow water brushes to be removed
  796. if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) )
  797. {
  798. b->numsides = 0;
  799. return;
  800. } //end if
  801. // create windings for sides and bounds for brush
  802. MakeBrushWindings(b);
  803. //mark brushes without winding or with a tiny window as bevels
  804. MarkBrushBevels(b);
  805. // brushes that will not be visible at all will never be
  806. // used as bsp splitters
  807. if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) )
  808. {
  809. c_clipbrushes++;
  810. for (i = 0; i < b->numsides; i++)
  811. b->original_sides[i].texinfo = TEXINFO_NODE;
  812. } //end for
  813. //
  814. // origin brushes are removed, but they set
  815. // the rotation origin for the rest of the brushes
  816. // in the entity. After the entire entity is parsed,
  817. // the planenums and texinfos will be adjusted for
  818. // the origin brush
  819. //
  820. //ME: not needed because the entities in the BSP file already
  821. // have an origin set
  822. // if (b->contents & CONTENTS_ORIGIN)
  823. // {
  824. // char string[32];
  825. // vec3_t origin;
  826. //
  827. // if (num_entities == 1)
  828. // {
  829. // Error ("Entity %i, Brush %i: origin brushes not allowed in world"
  830. // , b->entitynum, b->brushnum);
  831. // return;
  832. // }
  833. //
  834. // VectorAdd (b->mins, b->maxs, origin);
  835. // VectorScale (origin, 0.5, origin);
  836. //
  837. // sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
  838. // SetKeyValue (&entities[b->entitynum], "origin", string);
  839. //
  840. // VectorCopy (origin, entities[b->entitynum].origin);
  841. //
  842. // // don't keep this brush
  843. // b->numsides = 0;
  844. //
  845. // return;
  846. // }
  847. //ME: the bsp brushes already have bevels, so we won't try to
  848. // add them again (especially since Johny Boy's bevel adding might
  849. // be crappy)
  850. // AddBrushBevels(b);
  851. nummapbrushes++;
  852. mapent->numbrushes++;
  853. } //end of the function Q2_BSPBrushToMapBrush
  854. //===========================================================================
  855. //===========================================================================
  856. void Q2_ParseBSPBrushes(entity_t *mapent)
  857. {
  858. int i;
  859. //give all the brushes that belong to this entity the number of the
  860. //BSP model used by this entity
  861. Q2_SetBrushModelNumbers(mapent);
  862. //now parse all the brushes with the correct mapent->modelnum
  863. for (i = 0; i < numbrushes; i++)
  864. {
  865. if (brushmodelnumbers[i] == mapent->modelnum)
  866. {
  867. Q2_BSPBrushToMapBrush(&dbrushes[i], mapent);
  868. } //end if
  869. } //end for
  870. } //end of the function Q2_ParseBSPBrushes
  871. //===========================================================================
  872. //===========================================================================
  873. qboolean Q2_ParseBSPEntity(int entnum)
  874. {
  875. entity_t *mapent;
  876. char *model;
  877. int startbrush, startsides;
  878. startbrush = nummapbrushes;
  879. startsides = nummapbrushsides;
  880. mapent = &entities[entnum];//num_entities];
  881. mapent->firstbrush = nummapbrushes;
  882. mapent->numbrushes = 0;
  883. mapent->modelnum = -1; //-1 = no model
  884. model = ValueForKey(mapent, "model");
  885. if (model && strlen(model))
  886. {
  887. if (*model != '*')
  888. {
  889. Error("Q2_ParseBSPEntity: model number without leading *");
  890. } //end if
  891. //get the model number of this entity (skip the leading *)
  892. mapent->modelnum = atoi(&model[1]);
  893. } //end if
  894. GetVectorForKey(mapent, "origin", mapent->origin);
  895. //if this is the world entity it has model number zero
  896. //the world entity has no model key
  897. if (!strcmp("worldspawn", ValueForKey(mapent, "classname")))
  898. {
  899. mapent->modelnum = 0;
  900. } //end if
  901. //if the map entity has a BSP model (a modelnum of -1 is used for
  902. //entities that aren't using a BSP model)
  903. if (mapent->modelnum >= 0)
  904. {
  905. //parse the bsp brushes
  906. Q2_ParseBSPBrushes(mapent);
  907. } //end if
  908. //
  909. //the origin of the entity is already taken into account
  910. //
  911. //func_group entities can't be in the bsp file
  912. //
  913. //check out the func_areaportal entities
  914. if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname")))
  915. {
  916. c_areaportals++;
  917. mapent->areaportalnum = c_areaportals;
  918. return true;
  919. } //end if
  920. return true;
  921. } //end of the function Q2_ParseBSPEntity
  922. //===========================================================================
  923. //
  924. // Parameter: -
  925. // Returns: -
  926. // Changes Globals: -
  927. //===========================================================================
  928. void Q2_LoadMapFromBSP(char *filename, int offset, int length)
  929. {
  930. int i;
  931. Log_Print("-- Q2_LoadMapFromBSP --\n");
  932. //loaded map type
  933. loadedmaptype = MAPTYPE_QUAKE2;
  934. Log_Print("Loading map from %s...\n", filename);
  935. //load the bsp file
  936. Q2_LoadBSPFile(filename, offset, length);
  937. //create an index from bsp planes to map planes
  938. //DPlanes2MapPlanes();
  939. //clear brush model numbers
  940. for (i = 0; i < MAX_MAPFILE_BRUSHES; i++)
  941. brushmodelnumbers[i] = -1;
  942. nummapbrushsides = 0;
  943. num_entities = 0;
  944. Q2_ParseEntities();
  945. //
  946. for (i = 0; i < num_entities; i++)
  947. {
  948. Q2_ParseBSPEntity(i);
  949. } //end for
  950. //get the map mins and maxs from the world model
  951. ClearBounds(map_mins, map_maxs);
  952. for (i = 0; i < entities[0].numbrushes; i++)
  953. {
  954. if (mapbrushes[i].mins[0] > 4096)
  955. continue; //no valid points
  956. AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs);
  957. AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs);
  958. } //end for
  959. PrintMapInfo();
  960. //
  961. Q2_CreateMapTexinfo();
  962. } //end of the function Q2_LoadMapFromBSP
  963. void Q2_ResetMapLoading(void)
  964. {
  965. //reset for map loading from bsp
  966. memset(nodestack, 0, NODESTACKSIZE * sizeof(int));
  967. nodestackptr = NULL;
  968. nodestacksize = 0;
  969. memset(brushmodelnumbers, 0, MAX_MAPFILE_BRUSHES * sizeof(int));
  970. } //end of the function Q2_ResetMapLoading
  971. //End MAP loading from BSP file
  972. #endif //ME
  973. //====================================================================
  974. /*
  975. ================
  976. TestExpandBrushes
  977. Expands all the brush planes and saves a new map out
  978. ================
  979. */
  980. void TestExpandBrushes (void)
  981. {
  982. FILE *f;
  983. side_t *s;
  984. int i, j, bn;
  985. winding_t *w;
  986. char *name = "expanded.map";
  987. mapbrush_t *brush;
  988. vec_t dist;
  989. Log_Print("writing %s\n", name);
  990. f = fopen (name, "wb");
  991. if (!f)
  992. Error ("Can't write %s\n", name);
  993. fprintf (f, "{\n\"classname\" \"worldspawn\"\n");
  994. for (bn=0 ; bn<nummapbrushes ; bn++)
  995. {
  996. brush = &mapbrushes[bn];
  997. fprintf (f, "{\n");
  998. for (i=0 ; i<brush->numsides ; i++)
  999. {
  1000. s = brush->original_sides + i;
  1001. dist = mapplanes[s->planenum].dist;
  1002. for (j=0 ; j<3 ; j++)
  1003. dist += fabs( 16 * mapplanes[s->planenum].normal[j] );
  1004. w = BaseWindingForPlane (mapplanes[s->planenum].normal, dist);
  1005. fprintf (f,"( %i %i %i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]);
  1006. fprintf (f,"( %i %i %i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]);
  1007. fprintf (f,"( %i %i %i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]);
  1008. fprintf (f, "%s 0 0 0 1 1\n", texinfo[s->texinfo].texture);
  1009. FreeWinding (w);
  1010. }
  1011. fprintf (f, "}\n");
  1012. }
  1013. fprintf (f, "}\n");
  1014. fclose (f);
  1015. Error ("can't proceed after expanding brushes");
  1016. } //end of the function TestExpandBrushes