flow.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1997-2006 Id Software, Inc.
  4. This file is part of Quake 2 Tools source code.
  5. Quake 2 Tools 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 2 Tools 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 Quake 2 Tools source code; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "vis.h"
  19. /*
  20. each portal will have a list of all possible to see from first portal
  21. if (!thread->portalmightsee[portalnum])
  22. portal mightsee
  23. for p2 = all other portals in leaf
  24. get sperating planes
  25. for all portals that might be seen by p2
  26. mark as unseen if not present in seperating plane
  27. flood fill a new mightsee
  28. save as passagemightsee
  29. void CalcMightSee (leaf_t *leaf,
  30. */
  31. int CountBits (byte *bits, int numbits)
  32. {
  33. int i;
  34. int c;
  35. c = 0;
  36. for (i=0 ; i<numbits ; i++)
  37. if (bits[i>>3] & (1<<(i&7)) )
  38. c++;
  39. return c;
  40. }
  41. int c_fullskip;
  42. int c_portalskip, c_leafskip;
  43. int c_vistest, c_mighttest;
  44. int c_chop, c_nochop;
  45. int active;
  46. void CheckStack (leaf_t *leaf, threaddata_t *thread)
  47. {
  48. pstack_t *p, *p2;
  49. for (p=thread->pstack_head.next ; p ; p=p->next)
  50. {
  51. // printf ("=");
  52. if (p->leaf == leaf)
  53. Error ("CheckStack: leaf recursion");
  54. for (p2=thread->pstack_head.next ; p2 != p ; p2=p2->next)
  55. if (p2->leaf == p->leaf)
  56. Error ("CheckStack: late leaf recursion");
  57. }
  58. // printf ("\n");
  59. }
  60. winding_t *AllocStackWinding (pstack_t *stack)
  61. {
  62. int i;
  63. for (i=0 ; i<3 ; i++)
  64. {
  65. if (stack->freewindings[i])
  66. {
  67. stack->freewindings[i] = 0;
  68. return &stack->windings[i];
  69. }
  70. }
  71. Error ("AllocStackWinding: failed");
  72. return NULL;
  73. }
  74. void FreeStackWinding (winding_t *w, pstack_t *stack)
  75. {
  76. int i;
  77. i = w - stack->windings;
  78. if (i<0 || i>2)
  79. return; // not from local
  80. if (stack->freewindings[i])
  81. Error ("FreeStackWinding: allready free");
  82. stack->freewindings[i] = 1;
  83. }
  84. /*
  85. ==============
  86. ChopWinding
  87. ==============
  88. */
  89. winding_t *ChopWinding (winding_t *in, pstack_t *stack, plane_t *split)
  90. {
  91. vec_t dists[128];
  92. int sides[128];
  93. int counts[3];
  94. vec_t dot;
  95. int i, j;
  96. vec_t *p1, *p2;
  97. vec3_t mid;
  98. winding_t *neww;
  99. counts[0] = counts[1] = counts[2] = 0;
  100. // determine sides for each point
  101. for (i=0 ; i<in->numpoints ; i++)
  102. {
  103. dot = DotProduct (in->points[i], split->normal);
  104. dot -= split->dist;
  105. dists[i] = dot;
  106. if (dot > ON_EPSILON)
  107. sides[i] = SIDE_FRONT;
  108. else if (dot < -ON_EPSILON)
  109. sides[i] = SIDE_BACK;
  110. else
  111. {
  112. sides[i] = SIDE_ON;
  113. }
  114. counts[sides[i]]++;
  115. }
  116. if (!counts[1])
  117. return in; // completely on front side
  118. if (!counts[0])
  119. {
  120. FreeStackWinding (in, stack);
  121. return NULL;
  122. }
  123. sides[i] = sides[0];
  124. dists[i] = dists[0];
  125. neww = AllocStackWinding (stack);
  126. neww->numpoints = 0;
  127. for (i=0 ; i<in->numpoints ; i++)
  128. {
  129. p1 = in->points[i];
  130. if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
  131. {
  132. FreeStackWinding (neww, stack);
  133. return in; // can't chop -- fall back to original
  134. }
  135. if (sides[i] == SIDE_ON)
  136. {
  137. VectorCopy (p1, neww->points[neww->numpoints]);
  138. neww->numpoints++;
  139. continue;
  140. }
  141. if (sides[i] == SIDE_FRONT)
  142. {
  143. VectorCopy (p1, neww->points[neww->numpoints]);
  144. neww->numpoints++;
  145. }
  146. if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  147. continue;
  148. if (neww->numpoints == MAX_POINTS_ON_FIXED_WINDING)
  149. {
  150. FreeStackWinding (neww, stack);
  151. return in; // can't chop -- fall back to original
  152. }
  153. // generate a split point
  154. p2 = in->points[(i+1)%in->numpoints];
  155. dot = dists[i] / (dists[i]-dists[i+1]);
  156. for (j=0 ; j<3 ; j++)
  157. { // avoid round off error when possible
  158. if (split->normal[j] == 1)
  159. mid[j] = split->dist;
  160. else if (split->normal[j] == -1)
  161. mid[j] = -split->dist;
  162. else
  163. mid[j] = p1[j] + dot*(p2[j]-p1[j]);
  164. }
  165. VectorCopy (mid, neww->points[neww->numpoints]);
  166. neww->numpoints++;
  167. }
  168. // free the original winding
  169. FreeStackWinding (in, stack);
  170. return neww;
  171. }
  172. /*
  173. ==============
  174. ClipToSeperators
  175. Source, pass, and target are an ordering of portals.
  176. Generates seperating planes canidates by taking two points from source and one
  177. point from pass, and clips target by them.
  178. If target is totally clipped away, that portal can not be seen through.
  179. Normal clip keeps target on the same side as pass, which is correct if the
  180. order goes source, pass, target. If the order goes pass, source, target then
  181. flipclip should be set.
  182. ==============
  183. */
  184. winding_t *ClipToSeperators (winding_t *source, winding_t *pass, winding_t *target, qboolean flipclip, pstack_t *stack)
  185. {
  186. int i, j, k, l;
  187. plane_t plane;
  188. vec3_t v1, v2;
  189. float d;
  190. vec_t length;
  191. int counts[3];
  192. qboolean fliptest;
  193. // check all combinations
  194. for (i=0 ; i<source->numpoints ; i++)
  195. {
  196. l = (i+1)%source->numpoints;
  197. VectorSubtract (source->points[l] , source->points[i], v1);
  198. // fing a vertex of pass that makes a plane that puts all of the
  199. // vertexes of pass on the front side and all of the vertexes of
  200. // source on the back side
  201. for (j=0 ; j<pass->numpoints ; j++)
  202. {
  203. VectorSubtract (pass->points[j], source->points[i], v2);
  204. plane.normal[0] = v1[1]*v2[2] - v1[2]*v2[1];
  205. plane.normal[1] = v1[2]*v2[0] - v1[0]*v2[2];
  206. plane.normal[2] = v1[0]*v2[1] - v1[1]*v2[0];
  207. // if points don't make a valid plane, skip it
  208. length = plane.normal[0] * plane.normal[0]
  209. + plane.normal[1] * plane.normal[1]
  210. + plane.normal[2] * plane.normal[2];
  211. if (length < ON_EPSILON)
  212. continue;
  213. length = 1/sqrt(length);
  214. plane.normal[0] *= length;
  215. plane.normal[1] *= length;
  216. plane.normal[2] *= length;
  217. plane.dist = DotProduct (pass->points[j], plane.normal);
  218. //
  219. // find out which side of the generated seperating plane has the
  220. // source portal
  221. //
  222. #if 1
  223. fliptest = false;
  224. for (k=0 ; k<source->numpoints ; k++)
  225. {
  226. if (k == i || k == l)
  227. continue;
  228. d = DotProduct (source->points[k], plane.normal) - plane.dist;
  229. if (d < -ON_EPSILON)
  230. { // source is on the negative side, so we want all
  231. // pass and target on the positive side
  232. fliptest = false;
  233. break;
  234. }
  235. else if (d > ON_EPSILON)
  236. { // source is on the positive side, so we want all
  237. // pass and target on the negative side
  238. fliptest = true;
  239. break;
  240. }
  241. }
  242. if (k == source->numpoints)
  243. continue; // planar with source portal
  244. #else
  245. fliptest = flipclip;
  246. #endif
  247. //
  248. // flip the normal if the source portal is backwards
  249. //
  250. if (fliptest)
  251. {
  252. VectorSubtract (vec3_origin, plane.normal, plane.normal);
  253. plane.dist = -plane.dist;
  254. }
  255. #if 1
  256. //
  257. // if all of the pass portal points are now on the positive side,
  258. // this is the seperating plane
  259. //
  260. counts[0] = counts[1] = counts[2] = 0;
  261. for (k=0 ; k<pass->numpoints ; k++)
  262. {
  263. if (k==j)
  264. continue;
  265. d = DotProduct (pass->points[k], plane.normal) - plane.dist;
  266. if (d < -ON_EPSILON)
  267. break;
  268. else if (d > ON_EPSILON)
  269. counts[0]++;
  270. else
  271. counts[2]++;
  272. }
  273. if (k != pass->numpoints)
  274. continue; // points on negative side, not a seperating plane
  275. if (!counts[0])
  276. continue; // planar with seperating plane
  277. #else
  278. k = (j+1)%pass->numpoints;
  279. d = DotProduct (pass->points[k], plane.normal) - plane.dist;
  280. if (d < -ON_EPSILON)
  281. continue;
  282. k = (j+pass->numpoints-1)%pass->numpoints;
  283. d = DotProduct (pass->points[k], plane.normal) - plane.dist;
  284. if (d < -ON_EPSILON)
  285. continue;
  286. #endif
  287. //
  288. // flip the normal if we want the back side
  289. //
  290. if (flipclip)
  291. {
  292. VectorSubtract (vec3_origin, plane.normal, plane.normal);
  293. plane.dist = -plane.dist;
  294. }
  295. //
  296. // clip target by the seperating plane
  297. //
  298. target = ChopWinding (target, stack, &plane);
  299. if (!target)
  300. return NULL; // target is not visible
  301. }
  302. }
  303. return target;
  304. }
  305. /*
  306. ==================
  307. RecursiveLeafFlow
  308. Flood fill through the leafs
  309. If src_portal is NULL, this is the originating leaf
  310. ==================
  311. */
  312. void RecursiveLeafFlow (int leafnum, threaddata_t *thread, pstack_t *prevstack)
  313. {
  314. pstack_t stack;
  315. portal_t *p;
  316. plane_t backplane;
  317. leaf_t *leaf;
  318. int i, j;
  319. long *test, *might, *vis, more;
  320. int pnum;
  321. thread->c_chains++;
  322. leaf = &leafs[leafnum];
  323. // CheckStack (leaf, thread);
  324. prevstack->next = &stack;
  325. stack.next = NULL;
  326. stack.leaf = leaf;
  327. stack.portal = NULL;
  328. might = (long *)stack.mightsee;
  329. vis = (long *)thread->base->portalvis;
  330. // check all portals for flowing into other leafs
  331. for (i=0 ; i<leaf->numportals ; i++)
  332. {
  333. p = leaf->portals[i];
  334. pnum = p - portals;
  335. if ( ! (prevstack->mightsee[pnum >> 3] & (1<<(pnum&7)) ) )
  336. {
  337. continue; // can't possibly see it
  338. }
  339. // if the portal can't see anything we haven't allready seen, skip it
  340. if (p->status == stat_done)
  341. {
  342. test = (long *)p->portalvis;
  343. }
  344. else
  345. {
  346. test = (long *)p->portalflood;
  347. }
  348. more = 0;
  349. for (j=0 ; j<portallongs ; j++)
  350. {
  351. might[j] = ((long *)prevstack->mightsee)[j] & test[j];
  352. more |= (might[j] & ~vis[j]);
  353. }
  354. if (!more &&
  355. (thread->base->portalvis[pnum>>3] & (1<<(pnum&7))) )
  356. { // can't see anything new
  357. continue;
  358. }
  359. // get plane of portal, point normal into the neighbor leaf
  360. stack.portalplane = p->plane;
  361. VectorSubtract (vec3_origin, p->plane.normal, backplane.normal);
  362. backplane.dist = -p->plane.dist;
  363. // c_portalcheck++;
  364. stack.portal = p;
  365. stack.next = NULL;
  366. stack.freewindings[0] = 1;
  367. stack.freewindings[1] = 1;
  368. stack.freewindings[2] = 1;
  369. #if 1
  370. {
  371. float d;
  372. d = DotProduct (p->origin, thread->pstack_head.portalplane.normal);
  373. d -= thread->pstack_head.portalplane.dist;
  374. if (d < -p->radius)
  375. {
  376. continue;
  377. }
  378. else if (d > p->radius)
  379. {
  380. stack.pass = p->winding;
  381. }
  382. else
  383. {
  384. stack.pass = ChopWinding (p->winding, &stack, &thread->pstack_head.portalplane);
  385. if (!stack.pass)
  386. continue;
  387. }
  388. }
  389. #else
  390. stack.pass = ChopWinding (p->winding, &stack, &thread->pstack_head.portalplane);
  391. if (!stack.pass)
  392. continue;
  393. #endif
  394. #if 1
  395. {
  396. float d;
  397. d = DotProduct (thread->base->origin, p->plane.normal);
  398. d -= p->plane.dist;
  399. if (d > p->radius)
  400. {
  401. continue;
  402. }
  403. else if (d < -p->radius)
  404. {
  405. stack.source = prevstack->source;
  406. }
  407. else
  408. {
  409. stack.source = ChopWinding (prevstack->source, &stack, &backplane);
  410. if (!stack.source)
  411. continue;
  412. }
  413. }
  414. #else
  415. stack.source = ChopWinding (prevstack->source, &stack, &backplane);
  416. if (!stack.source)
  417. continue;
  418. #endif
  419. if (!prevstack->pass)
  420. { // the second leaf can only be blocked if coplanar
  421. // mark the portal as visible
  422. thread->base->portalvis[pnum>>3] |= (1<<(pnum&7));
  423. RecursiveLeafFlow (p->leaf, thread, &stack);
  424. continue;
  425. }
  426. stack.pass = ClipToSeperators (stack.source, prevstack->pass, stack.pass, false, &stack);
  427. if (!stack.pass)
  428. continue;
  429. stack.pass = ClipToSeperators (prevstack->pass, stack.source, stack.pass, true, &stack);
  430. if (!stack.pass)
  431. continue;
  432. // mark the portal as visible
  433. thread->base->portalvis[pnum>>3] |= (1<<(pnum&7));
  434. // flow through it for real
  435. RecursiveLeafFlow (p->leaf, thread, &stack);
  436. }
  437. }
  438. /*
  439. ===============
  440. PortalFlow
  441. generates the portalvis bit vector
  442. ===============
  443. */
  444. void PortalFlow (int portalnum)
  445. {
  446. threaddata_t data;
  447. int i;
  448. portal_t *p;
  449. int c_might, c_can;
  450. p = sorted_portals[portalnum];
  451. p->status = stat_working;
  452. c_might = CountBits (p->portalflood, numportals*2);
  453. memset (&data, 0, sizeof(data));
  454. data.base = p;
  455. data.pstack_head.portal = p;
  456. data.pstack_head.source = p->winding;
  457. data.pstack_head.portalplane = p->plane;
  458. for (i=0 ; i<portallongs ; i++)
  459. ((long *)data.pstack_head.mightsee)[i] = ((long *)p->portalflood)[i];
  460. RecursiveLeafFlow (p->leaf, &data, &data.pstack_head);
  461. p->status = stat_done;
  462. c_can = CountBits (p->portalvis, numportals*2);
  463. qprintf ("portal:%4i mightsee:%4i cansee:%4i (%i chains)\n",
  464. (int)(p - portals), c_might, c_can, data.c_chains);
  465. }
  466. /*
  467. ===============================================================================
  468. This is a rough first-order aproximation that is used to trivially reject some
  469. of the final calculations.
  470. Calculates portalfront and portalflood bit vectors
  471. thinking about:
  472. typedef struct passage_s
  473. {
  474. struct passage_s *next;
  475. struct portal_s *to;
  476. stryct sep_s *seperators;
  477. byte *mightsee;
  478. } passage_t;
  479. typedef struct portal_s
  480. {
  481. struct passage_s *passages;
  482. int leaf; // leaf portal faces into
  483. } portal_s;
  484. leaf = portal->leaf
  485. clear
  486. for all portals
  487. calc portal visibility
  488. clear bit vector
  489. for all passages
  490. passage visibility
  491. for a portal to be visible to a passage, it must be on the front of
  492. all seperating planes, and both portals must be behind the mew portal
  493. ===============================================================================
  494. */
  495. int c_flood, c_vis;
  496. /*
  497. ==================
  498. SimpleFlood
  499. ==================
  500. */
  501. void SimpleFlood (portal_t *srcportal, int leafnum)
  502. {
  503. int i;
  504. leaf_t *leaf;
  505. portal_t *p;
  506. int pnum;
  507. leaf = &leafs[leafnum];
  508. for (i=0 ; i<leaf->numportals ; i++)
  509. {
  510. p = leaf->portals[i];
  511. pnum = p - portals;
  512. if ( ! (srcportal->portalfront[pnum>>3] & (1<<(pnum&7)) ) )
  513. continue;
  514. if (srcportal->portalflood[pnum>>3] & (1<<(pnum&7)) )
  515. continue;
  516. srcportal->portalflood[pnum>>3] |= (1<<(pnum&7));
  517. SimpleFlood (srcportal, p->leaf);
  518. }
  519. }
  520. /*
  521. ==============
  522. BasePortalVis
  523. ==============
  524. */
  525. void BasePortalVis (int portalnum)
  526. {
  527. int j, k;
  528. portal_t *tp, *p;
  529. float d;
  530. winding_t *w;
  531. p = portals+portalnum;
  532. p->portalfront = malloc (portalbytes);
  533. memset (p->portalfront, 0, portalbytes);
  534. p->portalflood = malloc (portalbytes);
  535. memset (p->portalflood, 0, portalbytes);
  536. p->portalvis = malloc (portalbytes);
  537. memset (p->portalvis, 0, portalbytes);
  538. for (j=0, tp = portals ; j<numportals*2 ; j++, tp++)
  539. {
  540. if (j == portalnum)
  541. continue;
  542. w = tp->winding;
  543. for (k=0 ; k<w->numpoints ; k++)
  544. {
  545. d = DotProduct (w->points[k], p->plane.normal)
  546. - p->plane.dist;
  547. if (d > ON_EPSILON)
  548. break;
  549. }
  550. if (k == w->numpoints)
  551. continue; // no points on front
  552. w = p->winding;
  553. for (k=0 ; k<w->numpoints ; k++)
  554. {
  555. d = DotProduct (w->points[k], tp->plane.normal)
  556. - tp->plane.dist;
  557. if (d < -ON_EPSILON)
  558. break;
  559. }
  560. if (k == w->numpoints)
  561. continue; // no points on front
  562. p->portalfront[j>>3] |= (1<<(j&7));
  563. }
  564. SimpleFlood (p, p->leaf);
  565. p->nummightsee = CountBits (p->portalflood, numportals*2);
  566. // printf ("portal %i: %i mightsee\n", portalnum, p->nummightsee);
  567. c_flood += p->nummightsee;
  568. }
  569. /*
  570. ===============================================================================
  571. This is a second order aproximation
  572. Calculates portalvis bit vector
  573. WAAAAAAY too slow.
  574. ===============================================================================
  575. */
  576. /*
  577. ==================
  578. RecursiveLeafBitFlow
  579. ==================
  580. */
  581. void RecursiveLeafBitFlow (int leafnum, byte *mightsee, byte *cansee)
  582. {
  583. portal_t *p;
  584. leaf_t *leaf;
  585. int i, j;
  586. long more;
  587. int pnum;
  588. byte newmight[MAX_PORTALS/8];
  589. leaf = &leafs[leafnum];
  590. // check all portals for flowing into other leafs
  591. for (i=0 ; i<leaf->numportals ; i++)
  592. {
  593. p = leaf->portals[i];
  594. pnum = p - portals;
  595. // if some previous portal can't see it, skip
  596. if (! (mightsee[pnum>>3] & (1<<(pnum&7)) ) )
  597. continue;
  598. // if this portal can see some portals we mightsee, recurse
  599. more = 0;
  600. for (j=0 ; j<portallongs ; j++)
  601. {
  602. ((long *)newmight)[j] = ((long *)mightsee)[j]
  603. & ((long *)p->portalflood)[j];
  604. more |= ((long *)newmight)[j] & ~((long *)cansee)[j];
  605. }
  606. if (!more)
  607. continue; // can't see anything new
  608. cansee[pnum>>3] |= (1<<(pnum&7));
  609. RecursiveLeafBitFlow (p->leaf, newmight, cansee);
  610. }
  611. }
  612. /*
  613. ==============
  614. BetterPortalVis
  615. ==============
  616. */
  617. void BetterPortalVis (int portalnum)
  618. {
  619. portal_t *p;
  620. p = portals+portalnum;
  621. RecursiveLeafBitFlow (p->leaf, p->portalflood, p->portalvis);
  622. // build leaf vis information
  623. p->nummightsee = CountBits (p->portalvis, numportals*2);
  624. c_vis += p->nummightsee;
  625. }