REGION.C 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. // region.h
  2. #include "bsp5.h"
  3. /*
  4. input
  5. -----
  6. vertexes
  7. edges
  8. faces
  9. output
  10. ------
  11. smaller set of vertexes
  12. smaller set of edges
  13. regions
  14. ? triangulated regions
  15. face to region mapping numbers
  16. */
  17. #define MAX_EDGES_IN_REGION 32
  18. int firstedge;
  19. vec3_t region_mins, region_maxs;
  20. void AddPointToRegion (vec3_t p)
  21. {
  22. int i;
  23. for (i=0 ; i<3 ; i++)
  24. {
  25. if (p[i] < region_mins[i])
  26. region_mins[i] = p[i];
  27. if (p[i] > region_maxs[i])
  28. region_maxs[i] = p[i];
  29. }
  30. }
  31. void ClearRegionSize (void)
  32. {
  33. region_mins[0] = region_mins[1] = region_mins[2] = 9999;
  34. region_maxs[0] = region_maxs[1] = region_maxs[2] = -9999;
  35. }
  36. void AddFaceToRegionSize (face_t *f)
  37. {
  38. int i;
  39. for (i=0 ; i<f->numpoints ; i++)
  40. AddPointToRegion (f->pts[i]);
  41. }
  42. /*
  43. ==============
  44. CanJoinFaces
  45. ==============
  46. */
  47. qboolean CanJoinFaces (face_t *f, face_t *f2)
  48. {
  49. vec3_t oldmins, oldmaxs;
  50. int i;
  51. if (f2->planenum != f->planenum
  52. || f2->planeside != f->planeside
  53. || f2->texturenum != f->texturenum)
  54. return false;
  55. if (f2->outputnumber != -1)
  56. return false;
  57. if (f2->contents[0] != f->contents[0])
  58. { // does this ever happen? theyy shouldn't share.
  59. printf ("CanJoinFaces: edge with different contents");
  60. return false;
  61. }
  62. // check size constraints
  63. if ( ! (texinfo[f->texturenum].flags & TEX_SPECIAL) )
  64. {
  65. VectorCopy (region_mins, oldmins);
  66. VectorCopy (region_maxs, oldmaxs);
  67. AddFaceToRegionSize (f2);
  68. for (i=0 ; i<3 ; i++)
  69. {
  70. if (region_maxs[i] - region_mins[i] > 240)
  71. {
  72. VectorCopy (oldmins, region_mins);
  73. VectorCopy (oldmaxs, region_maxs);
  74. return false;
  75. }
  76. }
  77. }
  78. else
  79. {
  80. if (numsurfedges - firstedge + f2->numpoints > MAX_EDGES_IN_REGION)
  81. return false; // a huge water or sky polygon
  82. }
  83. // check edge count constraints
  84. return true;
  85. }
  86. /*
  87. ==============
  88. RecursiveGrowRegion
  89. ==============
  90. */
  91. void RecursiveGrowRegion (dface_t *r, face_t *f)
  92. {
  93. int e;
  94. face_t *f2;
  95. int i;
  96. if (f->outputnumber == numfaces)
  97. return;
  98. if (f->outputnumber != -1)
  99. Error ("RecursiveGrowRegion: region collision");
  100. f->outputnumber = numfaces;
  101. // add edges
  102. for (i=0 ; i<f->numpoints ; i++)
  103. {
  104. e = f->edges[i];
  105. if (!edgefaces[abs(e)][0])
  106. continue; // edge has allready been removed
  107. if (e > 0)
  108. f2 = edgefaces[e][1];
  109. else
  110. f2 = edgefaces[-e][0];
  111. if (f2 && f2->outputnumber == numfaces)
  112. {
  113. edgefaces[abs(e)][0] = NULL;
  114. edgefaces[abs(e)][1] = NULL;
  115. continue; // allready merged
  116. }
  117. if (f2 && CanJoinFaces (f, f2))
  118. { // remove the edge and merge the faces
  119. edgefaces[abs(e)][0] = NULL;
  120. edgefaces[abs(e)][1] = NULL;
  121. RecursiveGrowRegion (r, f2);
  122. }
  123. else
  124. {
  125. // emit a surfedge
  126. if (numsurfedges == MAX_MAP_SURFEDGES)
  127. Error ("numsurfedges == MAX_MAP_SURFEDGES");
  128. dsurfedges[numsurfedges] = e;
  129. numsurfedges++;
  130. }
  131. }
  132. }
  133. void PrintDface (int f)
  134. { // for debugging
  135. dface_t *df;
  136. dedge_t *e;
  137. int i, n;
  138. df = &dfaces[f];
  139. for (i=0 ; i<df->numedges ; i++)
  140. {
  141. n = dsurfedges[df->firstedge+i];
  142. e = &dedges[abs(n)];
  143. if (n < 0)
  144. printf ("%5i = %5i : %5i\n", n, e->v[1], e->v[0]);
  145. else
  146. printf ("%5i = %5i : %5i\n", n, e->v[0], e->v[1]);
  147. }
  148. }
  149. void FindVertexUse (int v)
  150. { // for debugging
  151. int i, j, n;
  152. dface_t *df;
  153. dedge_t *e;
  154. for (i=firstmodelface ; i<numfaces ; i++)
  155. {
  156. df = &dfaces[i];
  157. for (j=0 ; j<df->numedges ; j++)
  158. {
  159. n = dsurfedges[df->firstedge+j];
  160. e = &dedges[abs(n)];
  161. if (e->v[0] == v || e->v[1] == v)
  162. {
  163. printf ("on face %i\n", i);
  164. break;
  165. }
  166. }
  167. }
  168. }
  169. void FindEdgeUse (int v)
  170. { // for debugging
  171. int i, j, n;
  172. dface_t *df;
  173. for (i=firstmodelface ; i<numfaces ; i++)
  174. {
  175. df = &dfaces[i];
  176. for (j=0 ; j<df->numedges ; j++)
  177. {
  178. n = dsurfedges[df->firstedge+j];
  179. if (n == v || -n == v)
  180. {
  181. printf ("on face %i\n", i);
  182. break;
  183. }
  184. }
  185. }
  186. }
  187. /*
  188. ================
  189. HealEdges
  190. Extends e1 so that it goes all the way to e2, and removes all references
  191. to e2
  192. ================
  193. */
  194. int edgemapping[MAX_MAP_EDGES];
  195. void HealEdges (int e1, int e2)
  196. {
  197. int i, j, n, saved;
  198. dface_t *df;
  199. dedge_t *ed, *ed2;
  200. vec3_t v1, v2;
  201. dface_t *found[2];
  202. int foundj[2];
  203. return;
  204. e1 = edgemapping[e1];
  205. e2 = edgemapping[e2];
  206. // extend e1 to e2
  207. ed = &dedges[e1];
  208. ed2 = &dedges[e2];
  209. VectorSubtract (dvertexes[ed->v[1]].point, dvertexes[ed->v[0]].point, v1);
  210. VectorNormalize (v1);
  211. if (ed->v[0] == ed2->v[0])
  212. ed->v[0] = ed2->v[1];
  213. else if (ed->v[0] == ed2->v[1])
  214. ed->v[0] = ed2->v[0];
  215. else if (ed->v[1] == ed2->v[0])
  216. ed->v[1] = ed2->v[1];
  217. else if (ed->v[1] == ed2->v[1])
  218. ed->v[1] = ed2->v[0];
  219. else
  220. Error ("HealEdges: edges don't meet");
  221. VectorSubtract (dvertexes[ed->v[1]].point, dvertexes[ed->v[0]].point, v2);
  222. VectorNormalize (v2);
  223. if (!VectorCompare (v1, v2))
  224. Error ("HealEdges: edges not colinear");
  225. edgemapping[e2] = e1;
  226. saved = 0;
  227. // remove all uses of e2
  228. for (i=firstmodelface ; i<numfaces ; i++)
  229. {
  230. df = &dfaces[i];
  231. for (j=0 ; j<df->numedges ; j++)
  232. {
  233. n = dsurfedges[df->firstedge+j];
  234. if (n == e2 || n == -e2)
  235. {
  236. found[saved] = df;
  237. foundj[saved] = j;
  238. saved++;
  239. break;
  240. }
  241. }
  242. }
  243. if (saved != 2)
  244. printf ("WARNING: didn't find both faces for a saved edge\n");
  245. else
  246. {
  247. for (i=0 ; i<2 ; i++)
  248. { // remove this edge
  249. df = found[i];
  250. j = foundj[i];
  251. for (j++ ; j<df->numedges ; j++)
  252. dsurfedges[df->firstedge+j-1] =
  253. dsurfedges[df->firstedge+j];
  254. dsurfedges[df->firstedge+j-1] = 0;
  255. df->numedges--;
  256. }
  257. edgefaces[e2][0] = edgefaces[e2][1] = NULL;
  258. }
  259. }
  260. typedef struct
  261. {
  262. int numedges;
  263. int edges[2];
  264. } checkpoint_t;
  265. checkpoint_t checkpoints[MAX_MAP_VERTS];
  266. /*
  267. ==============
  268. RemoveColinearEdges
  269. ==============
  270. */
  271. void RemoveColinearEdges (void)
  272. {
  273. int i,j, v;
  274. int c0, c1, c2, c3;
  275. checkpoint_t *cp;
  276. // no edges remapped yet
  277. for (i=0 ; i<numedges ; i++)
  278. edgemapping[i] = i;
  279. // find vertexes that only have two edges
  280. memset (checkpoints, 0, sizeof(checkpoints));
  281. for (i=firstmodeledge ; i<numedges ; i++)
  282. {
  283. if (!edgefaces[i][0])
  284. continue; // removed
  285. for (j=0 ; j<2 ; j++)
  286. {
  287. v = dedges[i].v[j];
  288. cp = &checkpoints[v];
  289. if (cp->numedges<2)
  290. cp->edges[cp->numedges] = i;
  291. cp->numedges++;
  292. }
  293. }
  294. // if a vertex only has two edges and they are colinear, it can be removed
  295. c0 = c1 = c2 = c3 = 0;
  296. for (i=0 ; i<numvertexes ; i++)
  297. {
  298. cp = &checkpoints[i];
  299. switch (cp->numedges)
  300. {
  301. case 0:
  302. c0++;
  303. break;
  304. case 1:
  305. c1++;
  306. break;
  307. case 2:
  308. c2++;
  309. HealEdges (cp->edges[0], cp->edges[1]);
  310. break;
  311. default:
  312. c3++;
  313. break;
  314. }
  315. }
  316. // qprintf ("%5i c0\n", c0);
  317. // qprintf ("%5i c1\n", c1);
  318. // qprintf ("%5i c2\n", c2);
  319. // qprintf ("%5i c3+\n", c3);
  320. qprintf ("%5i deges removed by tjunction healing\n", c2);
  321. }
  322. /*
  323. ==============
  324. CountRealNumbers
  325. ==============
  326. */
  327. void CountRealNumbers (void)
  328. {
  329. int i;
  330. int c;
  331. qprintf ("%5i regions\n", numfaces-firstmodelface);
  332. c = 0;
  333. for (i=firstmodelface ; i<numfaces ; i++)
  334. c += dfaces[i].numedges;
  335. qprintf ("%5i real marksurfaces\n", c);
  336. c = 0;
  337. for (i=firstmodeledge ; i<numedges ; i++)
  338. if (edgefaces[i][0])
  339. c++; // not removed
  340. qprintf ("%5i real edges\n", c);
  341. }
  342. //=============================================================================
  343. /*
  344. ==============
  345. GrowNodeRegion_r
  346. ==============
  347. */
  348. void GrowNodeRegion_r (node_t *node)
  349. {
  350. dface_t *r;
  351. face_t *f;
  352. int i;
  353. if (node->planenum == PLANENUM_LEAF)
  354. return;
  355. node->firstface = numfaces;
  356. for (f=node->faces ; f ; f=f->next)
  357. {
  358. // if (f->outputnumber != -1)
  359. // continue; // allready grown into an earlier region
  360. // emit a region
  361. if (numfaces == MAX_MAP_FACES)
  362. Error ("MAX_MAP_FACES");
  363. f->outputnumber = numfaces;
  364. r = &dfaces[numfaces];
  365. r->planenum = node->outputplanenum;
  366. r->side = f->planeside;
  367. r->texinfo = f->texturenum;
  368. for (i=0 ; i<MAXLIGHTMAPS ; i++)
  369. r->styles[i] = 255;
  370. r->lightofs = -1;
  371. // add the face and mergable neighbors to it
  372. #if 0
  373. ClearRegionSize ();
  374. AddFaceToRegionSize (f);
  375. RecursiveGrowRegion (r, f);
  376. #endif
  377. r->firstedge = firstedge = numsurfedges;
  378. for (i=0 ; i<f->numpoints ; i++)
  379. {
  380. if (numsurfedges == MAX_MAP_SURFEDGES)
  381. Error ("numsurfedges == MAX_MAP_SURFEDGES");
  382. dsurfedges[numsurfedges] = f->edges[i];
  383. numsurfedges++;
  384. }
  385. r->numedges = numsurfedges - r->firstedge;
  386. numfaces++;
  387. }
  388. node->numfaces = numfaces - node->firstface;
  389. GrowNodeRegion_r (node->children[0]);
  390. GrowNodeRegion_r (node->children[1]);
  391. }
  392. /*
  393. ==============
  394. GrowNodeRegions
  395. ==============
  396. */
  397. void GrowNodeRegions (node_t *headnode)
  398. {
  399. qprintf ("---- GrowRegions ----\n");
  400. GrowNodeRegion_r (headnode);
  401. //RemoveColinearEdges ();
  402. CountRealNumbers ();
  403. }
  404. /*
  405. ===============================================================================
  406. Turn the faces on a plane into optimal non-convex regions
  407. The edges may still be split later as a result of tjunctions
  408. typedef struct
  409. {
  410. vec3_t dir;
  411. vec3_t origin;
  412. vec3_t p[2];
  413. }
  414. for all faces
  415. for all edges
  416. for all edges so far
  417. if overlap
  418. split
  419. ===============================================================================
  420. */