sv_world.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // world.c -- world query functions
  16. #include "server.h"
  17. /*
  18. ===============================================================================
  19. ENTITY AREA CHECKING
  20. FIXME: this use of "area" is different from the bsp file use
  21. ===============================================================================
  22. */
  23. // (type *)STRUCT_FROM_LINK(link_t *link, type, member)
  24. // ent = STRUCT_FROM_LINK(link,entity_t,order)
  25. // FIXME: remove this mess!
  26. #define STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m)))
  27. #define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
  28. typedef struct areanode_s
  29. {
  30. int axis; // -1 = leaf node
  31. float dist;
  32. struct areanode_s *children[2];
  33. link_t trigger_edicts;
  34. link_t solid_edicts;
  35. } areanode_t;
  36. #define AREA_DEPTH 4
  37. #define AREA_NODES 32
  38. areanode_t sv_areanodes[AREA_NODES];
  39. int sv_numareanodes;
  40. float *area_mins, *area_maxs;
  41. edict_t **area_list;
  42. int area_count, area_maxcount;
  43. int area_type;
  44. int SV_HullForEntity (edict_t *ent);
  45. // ClearLink is used for new headnodes
  46. void ClearLink (link_t *l)
  47. {
  48. l->prev = l->next = l;
  49. }
  50. void RemoveLink (link_t *l)
  51. {
  52. l->next->prev = l->prev;
  53. l->prev->next = l->next;
  54. }
  55. void InsertLinkBefore (link_t *l, link_t *before)
  56. {
  57. l->next = before;
  58. l->prev = before->prev;
  59. l->prev->next = l;
  60. l->next->prev = l;
  61. }
  62. /*
  63. ===============
  64. SV_CreateAreaNode
  65. Builds a uniformly subdivided tree for the given world size
  66. ===============
  67. */
  68. areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
  69. {
  70. areanode_t *anode;
  71. vec3_t size;
  72. vec3_t mins1, maxs1, mins2, maxs2;
  73. anode = &sv_areanodes[sv_numareanodes];
  74. sv_numareanodes++;
  75. ClearLink (&anode->trigger_edicts);
  76. ClearLink (&anode->solid_edicts);
  77. if (depth == AREA_DEPTH)
  78. {
  79. anode->axis = -1;
  80. anode->children[0] = anode->children[1] = NULL;
  81. return anode;
  82. }
  83. VectorSubtract (maxs, mins, size);
  84. if (size[0] > size[1])
  85. anode->axis = 0;
  86. else
  87. anode->axis = 1;
  88. anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]);
  89. VectorCopy (mins, mins1);
  90. VectorCopy (mins, mins2);
  91. VectorCopy (maxs, maxs1);
  92. VectorCopy (maxs, maxs2);
  93. maxs1[anode->axis] = mins2[anode->axis] = anode->dist;
  94. anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2);
  95. anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1);
  96. return anode;
  97. }
  98. /*
  99. ===============
  100. SV_ClearWorld
  101. ===============
  102. */
  103. void SV_ClearWorld (void)
  104. {
  105. memset (sv_areanodes, 0, sizeof(sv_areanodes));
  106. sv_numareanodes = 0;
  107. SV_CreateAreaNode (0, sv.models[1]->mins, sv.models[1]->maxs);
  108. }
  109. /*
  110. ===============
  111. SV_UnlinkEdict
  112. ===============
  113. */
  114. void SV_UnlinkEdict (edict_t *ent)
  115. {
  116. if (!ent->area.prev)
  117. return; // not linked in anywhere
  118. RemoveLink (&ent->area);
  119. ent->area.prev = ent->area.next = NULL;
  120. }
  121. /*
  122. ===============
  123. SV_LinkEdict
  124. ===============
  125. */
  126. #define MAX_TOTAL_ENT_LEAFS 128
  127. void SV_LinkEdict (edict_t *ent)
  128. {
  129. areanode_t *node;
  130. int leafs[MAX_TOTAL_ENT_LEAFS];
  131. int clusters[MAX_TOTAL_ENT_LEAFS];
  132. int num_leafs;
  133. int i, j, k;
  134. int area;
  135. int topnode;
  136. if (ent->area.prev)
  137. SV_UnlinkEdict (ent); // unlink from old position
  138. if (ent == ge->edicts)
  139. return; // don't add the world
  140. if (!ent->inuse)
  141. return;
  142. // set the size
  143. VectorSubtract (ent->maxs, ent->mins, ent->size);
  144. // encode the size into the entity_state for client prediction
  145. if (ent->solid == SOLID_BBOX && !(ent->svflags & SVF_DEADMONSTER))
  146. { // assume that x/y are equal and symetric
  147. i = ent->maxs[0]/8;
  148. if (i<1)
  149. i = 1;
  150. if (i>31)
  151. i = 31;
  152. // z is not symetric
  153. j = (-ent->mins[2])/8;
  154. if (j<1)
  155. j = 1;
  156. if (j>31)
  157. j = 31;
  158. // and z maxs can be negative...
  159. k = (ent->maxs[2]+32)/8;
  160. if (k<1)
  161. k = 1;
  162. if (k>63)
  163. k = 63;
  164. ent->s.solid = (k<<10) | (j<<5) | i;
  165. }
  166. else if (ent->solid == SOLID_BSP)
  167. {
  168. ent->s.solid = 31; // a solid_bbox will never create this value
  169. }
  170. else
  171. ent->s.solid = 0;
  172. // set the abs box
  173. if (ent->solid == SOLID_BSP &&
  174. (ent->s.angles[0] || ent->s.angles[1] || ent->s.angles[2]) )
  175. { // expand for rotation
  176. float max, v;
  177. int i;
  178. max = 0;
  179. for (i=0 ; i<3 ; i++)
  180. {
  181. v =fabs( ent->mins[i]);
  182. if (v > max)
  183. max = v;
  184. v =fabs( ent->maxs[i]);
  185. if (v > max)
  186. max = v;
  187. }
  188. for (i=0 ; i<3 ; i++)
  189. {
  190. ent->absmin[i] = ent->s.origin[i] - max;
  191. ent->absmax[i] = ent->s.origin[i] + max;
  192. }
  193. }
  194. else
  195. { // normal
  196. VectorAdd (ent->s.origin, ent->mins, ent->absmin);
  197. VectorAdd (ent->s.origin, ent->maxs, ent->absmax);
  198. }
  199. // because movement is clipped an epsilon away from an actual edge,
  200. // we must fully check even when bounding boxes don't quite touch
  201. ent->absmin[0] -= 1;
  202. ent->absmin[1] -= 1;
  203. ent->absmin[2] -= 1;
  204. ent->absmax[0] += 1;
  205. ent->absmax[1] += 1;
  206. ent->absmax[2] += 1;
  207. // link to PVS leafs
  208. ent->num_clusters = 0;
  209. ent->areanum = 0;
  210. ent->areanum2 = 0;
  211. //get all leafs, including solids
  212. num_leafs = CM_BoxLeafnums (ent->absmin, ent->absmax,
  213. leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
  214. // set areas
  215. for (i=0 ; i<num_leafs ; i++)
  216. {
  217. clusters[i] = CM_LeafCluster (leafs[i]);
  218. area = CM_LeafArea (leafs[i]);
  219. if (area)
  220. { // doors may legally straggle two areas,
  221. // but nothing should evern need more than that
  222. if (ent->areanum && ent->areanum != area)
  223. {
  224. if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading)
  225. Com_DPrintf ("Object touching 3 areas at %f %f %f\n",
  226. ent->absmin[0], ent->absmin[1], ent->absmin[2]);
  227. ent->areanum2 = area;
  228. }
  229. else
  230. ent->areanum = area;
  231. }
  232. }
  233. if (num_leafs >= MAX_TOTAL_ENT_LEAFS)
  234. { // assume we missed some leafs, and mark by headnode
  235. ent->num_clusters = -1;
  236. ent->headnode = topnode;
  237. }
  238. else
  239. {
  240. ent->num_clusters = 0;
  241. for (i=0 ; i<num_leafs ; i++)
  242. {
  243. if (clusters[i] == -1)
  244. continue; // not a visible leaf
  245. for (j=0 ; j<i ; j++)
  246. if (clusters[j] == clusters[i])
  247. break;
  248. if (j == i)
  249. {
  250. if (ent->num_clusters == MAX_ENT_CLUSTERS)
  251. { // assume we missed some leafs, and mark by headnode
  252. ent->num_clusters = -1;
  253. ent->headnode = topnode;
  254. break;
  255. }
  256. ent->clusternums[ent->num_clusters++] = clusters[i];
  257. }
  258. }
  259. }
  260. // if first time, make sure old_origin is valid
  261. if (!ent->linkcount)
  262. {
  263. VectorCopy (ent->s.origin, ent->s.old_origin);
  264. }
  265. ent->linkcount++;
  266. if (ent->solid == SOLID_NOT)
  267. return;
  268. // find the first node that the ent's box crosses
  269. node = sv_areanodes;
  270. while (1)
  271. {
  272. if (node->axis == -1)
  273. break;
  274. if (ent->absmin[node->axis] > node->dist)
  275. node = node->children[0];
  276. else if (ent->absmax[node->axis] < node->dist)
  277. node = node->children[1];
  278. else
  279. break; // crosses the node
  280. }
  281. // link it in
  282. if (ent->solid == SOLID_TRIGGER)
  283. InsertLinkBefore (&ent->area, &node->trigger_edicts);
  284. else
  285. InsertLinkBefore (&ent->area, &node->solid_edicts);
  286. }
  287. /*
  288. ====================
  289. SV_AreaEdicts_r
  290. ====================
  291. */
  292. void SV_AreaEdicts_r (areanode_t *node)
  293. {
  294. link_t *l, *next, *start;
  295. edict_t *check;
  296. int count;
  297. count = 0;
  298. // touch linked edicts
  299. if (area_type == AREA_SOLID)
  300. start = &node->solid_edicts;
  301. else
  302. start = &node->trigger_edicts;
  303. for (l=start->next ; l != start ; l = next)
  304. {
  305. next = l->next;
  306. check = EDICT_FROM_AREA(l);
  307. if (check->solid == SOLID_NOT)
  308. continue; // deactivated
  309. if (check->absmin[0] > area_maxs[0]
  310. || check->absmin[1] > area_maxs[1]
  311. || check->absmin[2] > area_maxs[2]
  312. || check->absmax[0] < area_mins[0]
  313. || check->absmax[1] < area_mins[1]
  314. || check->absmax[2] < area_mins[2])
  315. continue; // not touching
  316. if (area_count == area_maxcount)
  317. {
  318. Com_Printf ("SV_AreaEdicts: MAXCOUNT\n");
  319. return;
  320. }
  321. area_list[area_count] = check;
  322. area_count++;
  323. }
  324. if (node->axis == -1)
  325. return; // terminal node
  326. // recurse down both sides
  327. if ( area_maxs[node->axis] > node->dist )
  328. SV_AreaEdicts_r ( node->children[0] );
  329. if ( area_mins[node->axis] < node->dist )
  330. SV_AreaEdicts_r ( node->children[1] );
  331. }
  332. /*
  333. ================
  334. SV_AreaEdicts
  335. ================
  336. */
  337. int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list,
  338. int maxcount, int areatype)
  339. {
  340. area_mins = mins;
  341. area_maxs = maxs;
  342. area_list = list;
  343. area_count = 0;
  344. area_maxcount = maxcount;
  345. area_type = areatype;
  346. SV_AreaEdicts_r (sv_areanodes);
  347. return area_count;
  348. }
  349. //===========================================================================
  350. /*
  351. =============
  352. SV_PointContents
  353. =============
  354. */
  355. int SV_PointContents (vec3_t p)
  356. {
  357. edict_t *touch[MAX_EDICTS], *hit;
  358. int i, num;
  359. int contents, c2;
  360. int headnode;
  361. float *angles;
  362. // get base contents from world
  363. contents = CM_PointContents (p, sv.models[1]->headnode);
  364. // or in contents from all the other entities
  365. num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID);
  366. for (i=0 ; i<num ; i++)
  367. {
  368. hit = touch[i];
  369. // might intersect, so do an exact clip
  370. headnode = SV_HullForEntity (hit);
  371. angles = hit->s.angles;
  372. if (hit->solid != SOLID_BSP)
  373. angles = vec3_origin; // boxes don't rotate
  374. c2 = CM_TransformedPointContents (p, headnode, hit->s.origin, hit->s.angles);
  375. contents |= c2;
  376. }
  377. return contents;
  378. }
  379. typedef struct
  380. {
  381. vec3_t boxmins, boxmaxs;// enclose the test object along entire move
  382. float *mins, *maxs; // size of the moving object
  383. vec3_t mins2, maxs2; // size when clipping against mosnters
  384. float *start, *end;
  385. trace_t trace;
  386. edict_t *passedict;
  387. int contentmask;
  388. } moveclip_t;
  389. /*
  390. ================
  391. SV_HullForEntity
  392. Returns a headnode that can be used for testing or clipping an
  393. object of mins/maxs size.
  394. Offset is filled in to contain the adjustment that must be added to the
  395. testing object's origin to get a point to use with the returned hull.
  396. ================
  397. */
  398. int SV_HullForEntity (edict_t *ent)
  399. {
  400. cmodel_t *model;
  401. // decide which clipping hull to use, based on the size
  402. if (ent->solid == SOLID_BSP)
  403. { // explicit hulls in the BSP model
  404. model = sv.models[ ent->s.modelindex ];
  405. if (!model)
  406. Com_Error (ERR_FATAL, "MOVETYPE_PUSH with a non bsp model");
  407. return model->headnode;
  408. }
  409. // create a temp hull from bounding box sizes
  410. return CM_HeadnodeForBox (ent->mins, ent->maxs);
  411. }
  412. //===========================================================================
  413. /*
  414. ====================
  415. SV_ClipMoveToEntities
  416. ====================
  417. */
  418. void SV_ClipMoveToEntities ( moveclip_t *clip )
  419. {
  420. int i, num;
  421. edict_t *touchlist[MAX_EDICTS], *touch;
  422. trace_t trace;
  423. int headnode;
  424. float *angles;
  425. num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist
  426. , MAX_EDICTS, AREA_SOLID);
  427. // be careful, it is possible to have an entity in this
  428. // list removed before we get to it (killtriggered)
  429. for (i=0 ; i<num ; i++)
  430. {
  431. touch = touchlist[i];
  432. if (touch->solid == SOLID_NOT)
  433. continue;
  434. if (touch == clip->passedict)
  435. continue;
  436. if (clip->trace.allsolid)
  437. return;
  438. if (clip->passedict)
  439. {
  440. if (touch->owner == clip->passedict)
  441. continue; // don't clip against own missiles
  442. if (clip->passedict->owner == touch)
  443. continue; // don't clip against owner
  444. }
  445. if ( !(clip->contentmask & CONTENTS_DEADMONSTER)
  446. && (touch->svflags & SVF_DEADMONSTER) )
  447. continue;
  448. // might intersect, so do an exact clip
  449. headnode = SV_HullForEntity (touch);
  450. angles = touch->s.angles;
  451. if (touch->solid != SOLID_BSP)
  452. angles = vec3_origin; // boxes don't rotate
  453. if (touch->svflags & SVF_MONSTER)
  454. trace = CM_TransformedBoxTrace (clip->start, clip->end,
  455. clip->mins2, clip->maxs2, headnode, clip->contentmask,
  456. touch->s.origin, angles);
  457. else
  458. trace = CM_TransformedBoxTrace (clip->start, clip->end,
  459. clip->mins, clip->maxs, headnode, clip->contentmask,
  460. touch->s.origin, angles);
  461. if (trace.allsolid || trace.startsolid ||
  462. trace.fraction < clip->trace.fraction)
  463. {
  464. trace.ent = touch;
  465. if (clip->trace.startsolid)
  466. {
  467. clip->trace = trace;
  468. clip->trace.startsolid = true;
  469. }
  470. else
  471. clip->trace = trace;
  472. }
  473. else if (trace.startsolid)
  474. clip->trace.startsolid = true;
  475. }
  476. }
  477. /*
  478. ==================
  479. SV_TraceBounds
  480. ==================
  481. */
  482. void SV_TraceBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, vec3_t boxmins, vec3_t boxmaxs)
  483. {
  484. #if 0
  485. // debug to test against everything
  486. boxmins[0] = boxmins[1] = boxmins[2] = -9999;
  487. boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999;
  488. #else
  489. int i;
  490. for (i=0 ; i<3 ; i++)
  491. {
  492. if (end[i] > start[i])
  493. {
  494. boxmins[i] = start[i] + mins[i] - 1;
  495. boxmaxs[i] = end[i] + maxs[i] + 1;
  496. }
  497. else
  498. {
  499. boxmins[i] = end[i] + mins[i] - 1;
  500. boxmaxs[i] = start[i] + maxs[i] + 1;
  501. }
  502. }
  503. #endif
  504. }
  505. /*
  506. ==================
  507. SV_Trace
  508. Moves the given mins/maxs volume through the world from start to end.
  509. Passedict and edicts owned by passedict are explicitly not checked.
  510. ==================
  511. */
  512. trace_t SV_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passedict, int contentmask)
  513. {
  514. moveclip_t clip;
  515. if (!mins)
  516. mins = vec3_origin;
  517. if (!maxs)
  518. maxs = vec3_origin;
  519. memset ( &clip, 0, sizeof ( moveclip_t ) );
  520. // clip to world
  521. clip.trace = CM_BoxTrace (start, end, mins, maxs, 0, contentmask);
  522. clip.trace.ent = ge->edicts;
  523. if (clip.trace.fraction == 0)
  524. return clip.trace; // blocked by the world
  525. clip.contentmask = contentmask;
  526. clip.start = start;
  527. clip.end = end;
  528. clip.mins = mins;
  529. clip.maxs = maxs;
  530. clip.passedict = passedict;
  531. VectorCopy (mins, clip.mins2);
  532. VectorCopy (maxs, clip.maxs2);
  533. // create the bounding box of the entire move
  534. SV_TraceBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs );
  535. // clip to other solid entities
  536. SV_ClipMoveToEntities ( &clip );
  537. return clip.trace;
  538. }