cm_test.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  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 "cm_local.h"
  19. /*
  20. ==================
  21. CM_PointLeafnum_r
  22. ==================
  23. */
  24. int CM_PointLeafnum_r( const vec3_t p, int num ) {
  25. float d;
  26. cNode_t *node;
  27. cplane_t *plane;
  28. while (num >= 0)
  29. {
  30. node = cm.nodes + num;
  31. plane = node->plane;
  32. if (plane->type < 3)
  33. d = p[plane->type] - plane->dist;
  34. else
  35. d = DotProduct (plane->normal, p) - plane->dist;
  36. if (d < 0)
  37. num = node->children[1];
  38. else
  39. num = node->children[0];
  40. }
  41. c_pointcontents++; // optimize counter
  42. return -1 - num;
  43. }
  44. int CM_PointLeafnum( const vec3_t p ) {
  45. if ( !cm.numNodes ) { // map not loaded
  46. return 0;
  47. }
  48. return CM_PointLeafnum_r (p, 0);
  49. }
  50. /*
  51. ======================================================================
  52. LEAF LISTING
  53. ======================================================================
  54. */
  55. void CM_StoreLeafs( leafList_t *ll, int nodenum ) {
  56. int leafNum;
  57. leafNum = -1 - nodenum;
  58. // store the lastLeaf even if the list is overflowed
  59. if ( cm.leafs[ leafNum ].cluster != -1 ) {
  60. ll->lastLeaf = leafNum;
  61. }
  62. if ( ll->count >= ll->maxcount) {
  63. ll->overflowed = qtrue;
  64. return;
  65. }
  66. ll->list[ ll->count++ ] = leafNum;
  67. }
  68. void CM_StoreBrushes( leafList_t *ll, int nodenum ) {
  69. int i, k;
  70. int leafnum;
  71. int brushnum;
  72. cLeaf_t *leaf;
  73. cbrush_t *b;
  74. leafnum = -1 - nodenum;
  75. leaf = &cm.leafs[leafnum];
  76. for ( k = 0 ; k < leaf->numLeafBrushes ; k++ ) {
  77. brushnum = cm.leafbrushes[leaf->firstLeafBrush+k];
  78. b = &cm.brushes[brushnum];
  79. if ( b->checkcount == cm.checkcount ) {
  80. continue; // already checked this brush in another leaf
  81. }
  82. b->checkcount = cm.checkcount;
  83. for ( i = 0 ; i < 3 ; i++ ) {
  84. if ( b->bounds[0][i] >= ll->bounds[1][i] || b->bounds[1][i] <= ll->bounds[0][i] ) {
  85. break;
  86. }
  87. }
  88. if ( i != 3 ) {
  89. continue;
  90. }
  91. if ( ll->count >= ll->maxcount) {
  92. ll->overflowed = qtrue;
  93. return;
  94. }
  95. ((cbrush_t **)ll->list)[ ll->count++ ] = b;
  96. }
  97. #if 0
  98. // store patches?
  99. for ( k = 0 ; k < leaf->numLeafSurfaces ; k++ ) {
  100. patch = cm.surfaces[ cm.leafsurfaces[ leaf->firstleafsurface + k ] ];
  101. if ( !patch ) {
  102. continue;
  103. }
  104. }
  105. #endif
  106. }
  107. /*
  108. =============
  109. CM_BoxLeafnums
  110. Fills in a list of all the leafs touched
  111. =============
  112. */
  113. void CM_BoxLeafnums_r( leafList_t *ll, int nodenum ) {
  114. cplane_t *plane;
  115. cNode_t *node;
  116. int s;
  117. while (1) {
  118. if (nodenum < 0) {
  119. ll->storeLeafs( ll, nodenum );
  120. return;
  121. }
  122. node = &cm.nodes[nodenum];
  123. plane = node->plane;
  124. s = BoxOnPlaneSide( ll->bounds[0], ll->bounds[1], plane );
  125. if (s == 1) {
  126. nodenum = node->children[0];
  127. } else if (s == 2) {
  128. nodenum = node->children[1];
  129. } else {
  130. // go down both
  131. CM_BoxLeafnums_r( ll, node->children[0] );
  132. nodenum = node->children[1];
  133. }
  134. }
  135. }
  136. /*
  137. ==================
  138. CM_BoxLeafnums
  139. ==================
  140. */
  141. int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsize, int *lastLeaf) {
  142. leafList_t ll;
  143. cm.checkcount++;
  144. VectorCopy( mins, ll.bounds[0] );
  145. VectorCopy( maxs, ll.bounds[1] );
  146. ll.count = 0;
  147. ll.maxcount = listsize;
  148. ll.list = list;
  149. ll.storeLeafs = CM_StoreLeafs;
  150. ll.lastLeaf = 0;
  151. ll.overflowed = qfalse;
  152. CM_BoxLeafnums_r( &ll, 0 );
  153. *lastLeaf = ll.lastLeaf;
  154. return ll.count;
  155. }
  156. /*
  157. ==================
  158. CM_BoxBrushes
  159. ==================
  160. */
  161. int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int listsize ) {
  162. leafList_t ll;
  163. cm.checkcount++;
  164. VectorCopy( mins, ll.bounds[0] );
  165. VectorCopy( maxs, ll.bounds[1] );
  166. ll.count = 0;
  167. ll.maxcount = listsize;
  168. ll.list = (void *)list;
  169. ll.storeLeafs = CM_StoreBrushes;
  170. ll.lastLeaf = 0;
  171. ll.overflowed = qfalse;
  172. CM_BoxLeafnums_r( &ll, 0 );
  173. return ll.count;
  174. }
  175. //====================================================================
  176. /*
  177. ==================
  178. CM_PointContents
  179. ==================
  180. */
  181. int CM_PointContents( const vec3_t p, clipHandle_t model ) {
  182. int leafnum;
  183. int i, k;
  184. int brushnum;
  185. cLeaf_t *leaf;
  186. cbrush_t *b;
  187. int contents;
  188. float d;
  189. cmodel_t *clipm;
  190. if (!cm.numNodes) { // map not loaded
  191. return 0;
  192. }
  193. if ( model ) {
  194. clipm = CM_ClipHandleToModel( model );
  195. leaf = &clipm->leaf;
  196. } else {
  197. leafnum = CM_PointLeafnum_r (p, 0);
  198. leaf = &cm.leafs[leafnum];
  199. }
  200. contents = 0;
  201. for (k=0 ; k<leaf->numLeafBrushes ; k++) {
  202. brushnum = cm.leafbrushes[leaf->firstLeafBrush+k];
  203. b = &cm.brushes[brushnum];
  204. // see if the point is in the brush
  205. for ( i = 0 ; i < b->numsides ; i++ ) {
  206. d = DotProduct( p, b->sides[i].plane->normal );
  207. // FIXME test for Cash
  208. // if ( d >= b->sides[i].plane->dist ) {
  209. if ( d > b->sides[i].plane->dist ) {
  210. break;
  211. }
  212. }
  213. if ( i == b->numsides ) {
  214. contents |= b->contents;
  215. }
  216. }
  217. return contents;
  218. }
  219. /*
  220. ==================
  221. CM_TransformedPointContents
  222. Handles offseting and rotation of the end points for moving and
  223. rotating entities
  224. ==================
  225. */
  226. int CM_TransformedPointContents( const vec3_t p, clipHandle_t model, const vec3_t origin, const vec3_t angles) {
  227. vec3_t p_l;
  228. vec3_t temp;
  229. vec3_t forward, right, up;
  230. // subtract origin offset
  231. VectorSubtract (p, origin, p_l);
  232. // rotate start and end into the models frame of reference
  233. if ( model != BOX_MODEL_HANDLE &&
  234. (angles[0] || angles[1] || angles[2]) )
  235. {
  236. AngleVectors (angles, forward, right, up);
  237. VectorCopy (p_l, temp);
  238. p_l[0] = DotProduct (temp, forward);
  239. p_l[1] = -DotProduct (temp, right);
  240. p_l[2] = DotProduct (temp, up);
  241. }
  242. return CM_PointContents( p_l, model );
  243. }
  244. /*
  245. ===============================================================================
  246. PVS
  247. ===============================================================================
  248. */
  249. byte *CM_ClusterPVS (int cluster) {
  250. if (cluster < 0 || cluster >= cm.numClusters || !cm.vised ) {
  251. return cm.visibility;
  252. }
  253. return cm.visibility + cluster * cm.clusterBytes;
  254. }
  255. /*
  256. ===============================================================================
  257. AREAPORTALS
  258. ===============================================================================
  259. */
  260. void CM_FloodArea_r( int areaNum, int floodnum) {
  261. int i;
  262. cArea_t *area;
  263. int *con;
  264. area = &cm.areas[ areaNum ];
  265. if ( area->floodvalid == cm.floodvalid ) {
  266. if (area->floodnum == floodnum)
  267. return;
  268. Com_Error (ERR_DROP, "FloodArea_r: reflooded");
  269. }
  270. area->floodnum = floodnum;
  271. area->floodvalid = cm.floodvalid;
  272. con = cm.areaPortals + areaNum * cm.numAreas;
  273. for ( i=0 ; i < cm.numAreas ; i++ ) {
  274. if ( con[i] > 0 ) {
  275. CM_FloodArea_r( i, floodnum );
  276. }
  277. }
  278. }
  279. /*
  280. ====================
  281. CM_FloodAreaConnections
  282. ====================
  283. */
  284. void CM_FloodAreaConnections( void ) {
  285. int i;
  286. cArea_t *area;
  287. int floodnum;
  288. // all current floods are now invalid
  289. cm.floodvalid++;
  290. floodnum = 0;
  291. for (i = 0 ; i < cm.numAreas ; i++) {
  292. area = &cm.areas[i];
  293. if (area->floodvalid == cm.floodvalid) {
  294. continue; // already flooded into
  295. }
  296. floodnum++;
  297. CM_FloodArea_r (i, floodnum);
  298. }
  299. }
  300. /*
  301. ====================
  302. CM_AdjustAreaPortalState
  303. ====================
  304. */
  305. void CM_AdjustAreaPortalState( int area1, int area2, qboolean open ) {
  306. if ( area1 < 0 || area2 < 0 ) {
  307. return;
  308. }
  309. if ( area1 >= cm.numAreas || area2 >= cm.numAreas ) {
  310. Com_Error (ERR_DROP, "CM_ChangeAreaPortalState: bad area number");
  311. }
  312. if ( open ) {
  313. cm.areaPortals[ area1 * cm.numAreas + area2 ]++;
  314. cm.areaPortals[ area2 * cm.numAreas + area1 ]++;
  315. } else {
  316. cm.areaPortals[ area1 * cm.numAreas + area2 ]--;
  317. cm.areaPortals[ area2 * cm.numAreas + area1 ]--;
  318. if ( cm.areaPortals[ area2 * cm.numAreas + area1 ] < 0 ) {
  319. Com_Error (ERR_DROP, "CM_AdjustAreaPortalState: negative reference count");
  320. }
  321. }
  322. CM_FloodAreaConnections ();
  323. }
  324. /*
  325. ====================
  326. CM_AreasConnected
  327. ====================
  328. */
  329. qboolean CM_AreasConnected( int area1, int area2 ) {
  330. #ifndef BSPC
  331. if ( cm_noAreas->integer ) {
  332. return qtrue;
  333. }
  334. #endif
  335. if ( area1 < 0 || area2 < 0 ) {
  336. return qfalse;
  337. }
  338. if (area1 >= cm.numAreas || area2 >= cm.numAreas) {
  339. Com_Error (ERR_DROP, "area >= cm.numAreas");
  340. }
  341. if (cm.areas[area1].floodnum == cm.areas[area2].floodnum) {
  342. return qtrue;
  343. }
  344. return qfalse;
  345. }
  346. /*
  347. =================
  348. CM_WriteAreaBits
  349. Writes a bit vector of all the areas
  350. that are in the same flood as the area parameter
  351. Returns the number of bytes needed to hold all the bits.
  352. The bits are OR'd in, so you can CM_WriteAreaBits from multiple
  353. viewpoints and get the union of all visible areas.
  354. This is used to cull non-visible entities from snapshots
  355. =================
  356. */
  357. int CM_WriteAreaBits (byte *buffer, int area)
  358. {
  359. int i;
  360. int floodnum;
  361. int bytes;
  362. bytes = (cm.numAreas+7)>>3;
  363. #ifndef BSPC
  364. if (cm_noAreas->integer || area == -1)
  365. #else
  366. if ( area == -1)
  367. #endif
  368. { // for debugging, send everything
  369. Com_Memset (buffer, 255, bytes);
  370. }
  371. else
  372. {
  373. floodnum = cm.areas[area].floodnum;
  374. for (i=0 ; i<cm.numAreas ; i++)
  375. {
  376. if (cm.areas[i].floodnum == floodnum || area == -1)
  377. buffer[i>>3] |= 1<<(i&7);
  378. }
  379. }
  380. return bytes;
  381. }