tjunc.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. #include "bsp5.h"
  2. typedef struct wvert_s
  3. {
  4. vec_t t;
  5. struct wvert_s* prev;
  6. struct wvert_s* next;
  7. }
  8. wvert_t;
  9. typedef struct wedge_s
  10. {
  11. struct wedge_s* next;
  12. vec3_t dir;
  13. vec3_t origin;
  14. wvert_t head;
  15. }
  16. wedge_t;
  17. static int numwedges;
  18. static int numwverts;
  19. static int tjuncs;
  20. static int tjuncfaces;
  21. #define MAX_WVERTS 0x40000
  22. #define MAX_WEDGES 0x20000
  23. static wvert_t wverts[MAX_WVERTS];
  24. static wedge_t wedges[MAX_WEDGES];
  25. //============================================================================
  26. #define NUM_HASH 1024
  27. wedge_t* wedge_hash[NUM_HASH];
  28. static vec3_t hash_min;
  29. static vec3_t hash_scale;
  30. static void InitHash(const vec3_t mins, const vec3_t maxs)
  31. {
  32. vec3_t size;
  33. vec_t volume;
  34. vec_t scale;
  35. int newsize[2];
  36. VectorCopy(mins, hash_min);
  37. VectorSubtract(maxs, mins, size);
  38. memset(wedge_hash, 0, sizeof(wedge_hash));
  39. volume = size[0] * size[1];
  40. scale = sqrt(volume / NUM_HASH);
  41. newsize[0] = size[0] / scale;
  42. newsize[1] = size[1] / scale;
  43. hash_scale[0] = newsize[0] / size[0];
  44. hash_scale[1] = newsize[1] / size[1];
  45. hash_scale[2] = newsize[1];
  46. }
  47. static unsigned HashVec(const vec3_t vec)
  48. {
  49. unsigned h;
  50. h = hash_scale[0] * (vec[0] - hash_min[0]) * hash_scale[2] + hash_scale[1] * (vec[1] - hash_min[1]);
  51. if (h >= NUM_HASH)
  52. {
  53. return NUM_HASH - 1;
  54. }
  55. return h;
  56. }
  57. //============================================================================
  58. static bool CanonicalVector(vec3_t vec)
  59. {
  60. if (VectorNormalize(vec))
  61. {
  62. if (vec[0] > NORMAL_EPSILON )
  63. {
  64. return true;
  65. }
  66. else if (vec[0] < -NORMAL_EPSILON )
  67. {
  68. VectorSubtract(vec3_origin, vec, vec);
  69. return true;
  70. }
  71. else
  72. {
  73. vec[0] = 0;
  74. }
  75. if (vec[1] > NORMAL_EPSILON )
  76. {
  77. return true;
  78. }
  79. else if (vec[1] < -NORMAL_EPSILON )
  80. {
  81. VectorSubtract(vec3_origin, vec, vec);
  82. return true;
  83. }
  84. else
  85. {
  86. vec[1] = 0;
  87. }
  88. if (vec[2] > NORMAL_EPSILON )
  89. {
  90. return true;
  91. }
  92. else if (vec[2] < -NORMAL_EPSILON )
  93. {
  94. VectorSubtract(vec3_origin, vec, vec);
  95. return true;
  96. }
  97. else
  98. {
  99. vec[2] = 0;
  100. }
  101. // hlassert(false);
  102. return false;
  103. }
  104. // hlassert(false);
  105. return false;
  106. }
  107. static wedge_t *FindEdge(const vec3_t p1, const vec3_t p2, vec_t* t1, vec_t* t2)
  108. {
  109. vec3_t origin;
  110. vec3_t dir;
  111. wedge_t* w;
  112. vec_t temp;
  113. int h;
  114. VectorSubtract(p2, p1, dir);
  115. if (!CanonicalVector(dir))
  116. {
  117. #if _DEBUG
  118. Warning("CanonicalVector: degenerate @ (%4.3f %4.3f %4.3f )\n", p1[0], p1[1], p1[2]);
  119. #endif
  120. }
  121. *t1 = DotProduct(p1, dir);
  122. *t2 = DotProduct(p2, dir);
  123. VectorMA(p1, -*t1, dir, origin);
  124. if (*t1 > *t2)
  125. {
  126. temp = *t1;
  127. *t1 = *t2;
  128. *t2 = temp;
  129. }
  130. h = HashVec(origin);
  131. for (w = wedge_hash[h]; w; w = w->next)
  132. {
  133. temp = w->origin[0] - origin[0];
  134. if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
  135. {
  136. continue;
  137. }
  138. temp = w->origin[1] - origin[1];
  139. if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
  140. {
  141. continue;
  142. }
  143. temp = w->origin[2] - origin[2];
  144. if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
  145. {
  146. continue;
  147. }
  148. temp = w->dir[0] - dir[0];
  149. if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
  150. {
  151. continue;
  152. }
  153. temp = w->dir[1] - dir[1];
  154. if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
  155. {
  156. continue;
  157. }
  158. temp = w->dir[2] - dir[2];
  159. if (temp < -EQUAL_EPSILON || temp > EQUAL_EPSILON)
  160. {
  161. continue;
  162. }
  163. return w;
  164. }
  165. hlassume(numwedges < MAX_WEDGES, assume_MAX_WEDGES);
  166. w = &wedges[numwedges];
  167. numwedges++;
  168. w->next = wedge_hash[h];
  169. wedge_hash[h] = w;
  170. VectorCopy(origin, w->origin);
  171. VectorCopy(dir, w->dir);
  172. w->head.next = w->head.prev = &w->head;
  173. w->head.t = 99999;
  174. return w;
  175. }
  176. /*
  177. * ===============
  178. * AddVert
  179. *
  180. * ===============
  181. */
  182. #define T_EPSILON ON_EPSILON
  183. static void AddVert(const wedge_t* const w, const vec_t t)
  184. {
  185. wvert_t* v;
  186. wvert_t* newv;
  187. v = w->head.next;
  188. do
  189. {
  190. if (fabs(v->t - t) < T_EPSILON)
  191. {
  192. return;
  193. }
  194. if (v->t > t)
  195. {
  196. break;
  197. }
  198. v = v->next;
  199. }
  200. while (1);
  201. // insert a new wvert before v
  202. hlassume(numwverts < MAX_WVERTS, assume_MAX_WVERTS);
  203. newv = &wverts[numwverts];
  204. numwverts++;
  205. newv->t = t;
  206. newv->next = v;
  207. newv->prev = v->prev;
  208. v->prev->next = newv;
  209. v->prev = newv;
  210. }
  211. /*
  212. * ===============
  213. * AddEdge
  214. * ===============
  215. */
  216. static void AddEdge(const vec3_t p1, const vec3_t p2)
  217. {
  218. wedge_t* w;
  219. vec_t t1;
  220. vec_t t2;
  221. w = FindEdge(p1, p2, &t1, &t2);
  222. AddVert(w, t1);
  223. AddVert(w, t2);
  224. }
  225. /*
  226. * ===============
  227. * AddFaceEdges
  228. *
  229. * ===============
  230. */
  231. static void AddFaceEdges(const face_t* const f)
  232. {
  233. int i, j;
  234. for (i = 0; i < f->numpoints; i++)
  235. {
  236. j = (i + 1) % f->numpoints;
  237. AddEdge(f->pts[i], f->pts[j]);
  238. }
  239. }
  240. //============================================================================
  241. static byte superfacebuf[1024 * 16];
  242. static face_t* superface = (face_t*)superfacebuf;
  243. static int MAX_SUPERFACEEDGES = (sizeof(superfacebuf) - sizeof(face_t) + sizeof(superface->pts)) / sizeof(vec3_t);
  244. static face_t* newlist;
  245. static void SplitFaceForTjunc(face_t* f, face_t* original)
  246. {
  247. int i;
  248. face_t* newface;
  249. face_t* chain;
  250. vec3_t dir, test;
  251. vec_t v;
  252. int firstcorner, lastcorner;
  253. #ifdef _DEBUG
  254. static int counter = 0;
  255. Log("SplitFaceForTjunc %d\n", counter++);
  256. #endif
  257. chain = NULL;
  258. do
  259. {
  260. hlassume(f->original == NULL, assume_ValidPointer); // "SplitFaceForTjunc: f->original"
  261. if (f->numpoints <= MAXPOINTS)
  262. { // the face is now small enough without more cutting
  263. // so copy it back to the original
  264. *original = *f;
  265. original->original = chain;
  266. original->next = newlist;
  267. newlist = original;
  268. return;
  269. }
  270. tjuncfaces++;
  271. restart:
  272. // find the last corner
  273. VectorSubtract(f->pts[f->numpoints - 1], f->pts[0], dir);
  274. VectorNormalize(dir);
  275. for (lastcorner = f->numpoints - 1; lastcorner > 0; lastcorner--)
  276. {
  277. VectorSubtract(f->pts[lastcorner - 1], f->pts[lastcorner], test);
  278. VectorNormalize(test);
  279. v = DotProduct(test, dir);
  280. if (v < 1.0 - ON_EPSILON || v > 1.0 + ON_EPSILON)
  281. {
  282. break;
  283. }
  284. }
  285. // find the first corner
  286. VectorSubtract(f->pts[1], f->pts[0], dir);
  287. VectorNormalize(dir);
  288. for (firstcorner = 1; firstcorner < f->numpoints - 1; firstcorner++)
  289. {
  290. VectorSubtract(f->pts[firstcorner + 1], f->pts[firstcorner], test);
  291. VectorNormalize(test);
  292. v = DotProduct(test, dir);
  293. if (v < 1.0 - ON_EPSILON || v > 1.0 + ON_EPSILON)
  294. {
  295. break;
  296. }
  297. }
  298. if (firstcorner + 2 >= MAXPOINTS)
  299. {
  300. // rotate the point winding
  301. VectorCopy(f->pts[0], test);
  302. for (i = 1; i < f->numpoints; i++)
  303. {
  304. VectorCopy(f->pts[i], f->pts[i - 1]);
  305. }
  306. VectorCopy(test, f->pts[f->numpoints - 1]);
  307. goto restart;
  308. }
  309. // cut off as big a piece as possible, less than MAXPOINTS, and not
  310. // past lastcorner
  311. newface = NewFaceFromFace(f);
  312. hlassume(f->original == NULL, assume_ValidPointer); // "SplitFaceForTjunc: f->original"
  313. newface->original = chain;
  314. chain = newface;
  315. newface->next = newlist;
  316. newlist = newface;
  317. if (f->numpoints - firstcorner <= MAXPOINTS)
  318. {
  319. newface->numpoints = firstcorner + 2;
  320. }
  321. else if (lastcorner + 2 < MAXPOINTS && f->numpoints - lastcorner <= MAXPOINTS)
  322. {
  323. newface->numpoints = lastcorner + 2;
  324. }
  325. else
  326. {
  327. newface->numpoints = MAXPOINTS;
  328. }
  329. for (i = 0; i < newface->numpoints; i++)
  330. {
  331. VectorCopy(f->pts[i], newface->pts[i]);
  332. }
  333. for (i = newface->numpoints - 1; i < f->numpoints; i++)
  334. {
  335. VectorCopy(f->pts[i], f->pts[i - (newface->numpoints - 2)]);
  336. }
  337. f->numpoints -= (newface->numpoints - 2);
  338. }
  339. while (1);
  340. }
  341. /*
  342. * ===============
  343. * FixFaceEdges
  344. *
  345. * ===============
  346. */
  347. static void FixFaceEdges(face_t* f)
  348. {
  349. int i;
  350. int j;
  351. int k;
  352. wedge_t* w;
  353. wvert_t* v;
  354. vec_t t1;
  355. vec_t t2;
  356. *superface = *f;
  357. restart:
  358. for (i = 0; i < superface->numpoints; i++)
  359. {
  360. j = (i + 1) % superface->numpoints;
  361. w = FindEdge(superface->pts[i], superface->pts[j], &t1, &t2);
  362. for (v = w->head.next; v->t < t1 + T_EPSILON; v = v->next)
  363. {
  364. }
  365. if (v->t < t2 - T_EPSILON)
  366. {
  367. tjuncs++;
  368. // insert a new vertex here
  369. for (k = superface->numpoints; k > j; k--)
  370. {
  371. VectorCopy(superface->pts[k - 1], superface->pts[k]);
  372. }
  373. VectorMA(w->origin, v->t, w->dir, superface->pts[j]);
  374. superface->numpoints++;
  375. hlassume(superface->numpoints < MAX_SUPERFACEEDGES, assume_MAX_SUPERFACEEDGES);
  376. goto restart;
  377. }
  378. }
  379. if (superface->numpoints <= MAXPOINTS)
  380. {
  381. *f = *superface;
  382. f->next = newlist;
  383. newlist = f;
  384. return;
  385. }
  386. // the face needs to be split into multiple faces because of too many edges
  387. SplitFaceForTjunc(superface, f);
  388. }
  389. //============================================================================
  390. static void tjunc_find_r(node_t* node)
  391. {
  392. face_t* f;
  393. if (node->planenum == PLANENUM_LEAF)
  394. {
  395. return;
  396. }
  397. for (f = node->faces; f; f = f->next)
  398. {
  399. AddFaceEdges(f);
  400. }
  401. tjunc_find_r(node->children[0]);
  402. tjunc_find_r(node->children[1]);
  403. }
  404. static void tjunc_fix_r(node_t* node)
  405. {
  406. face_t* f;
  407. face_t* next;
  408. if (node->planenum == PLANENUM_LEAF)
  409. {
  410. return;
  411. }
  412. newlist = NULL;
  413. for (f = node->faces; f; f = next)
  414. {
  415. next = f->next;
  416. FixFaceEdges(f);
  417. }
  418. node->faces = newlist;
  419. tjunc_fix_r(node->children[0]);
  420. tjunc_fix_r(node->children[1]);
  421. }
  422. /*
  423. * ===========
  424. * tjunc
  425. *
  426. * ===========
  427. */
  428. void tjunc(node_t* headnode)
  429. {
  430. vec3_t maxs, mins;
  431. int i;
  432. Verbose("---- tjunc ----\n");
  433. if (g_notjunc)
  434. {
  435. return;
  436. }
  437. //
  438. // identify all points on common edges
  439. //
  440. // origin points won't allways be inside the map, so extend the hash area
  441. for (i = 0; i < 3; i++)
  442. {
  443. if (fabs(headnode->maxs[i]) > fabs(headnode->mins[i]))
  444. {
  445. maxs[i] = fabs(headnode->maxs[i]);
  446. }
  447. else
  448. {
  449. maxs[i] = fabs(headnode->mins[i]);
  450. }
  451. }
  452. VectorSubtract(vec3_origin, maxs, mins);
  453. InitHash(mins, maxs);
  454. numwedges = numwverts = 0;
  455. tjunc_find_r(headnode);
  456. Verbose("%i world edges %i edge points\n", numwedges, numwverts);
  457. //
  458. // add extra vertexes on edges where needed
  459. //
  460. tjuncs = tjuncfaces = 0;
  461. tjunc_fix_r(headnode);
  462. Verbose("%i edges added by tjunctions\n", tjuncs);
  463. Verbose("%i faces added by tjunctions\n", tjuncfaces);
  464. }