BBOX.C 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867
  1. /*****************************************************************************
  2. * bbox.c
  3. *
  4. * This module implements the bounding box calculations.
  5. * This file was written by Alexander Enzmann. He wrote the code for
  6. * POV-Ray's bounding boxes and generously provided us these enhancements.
  7. * The box intersection code was further hacked by Eric Haines to speed it up.
  8. *
  9. * Just so everyone knows where this came from, the code is VERY heavily
  10. * based on the slab code from Mark VandeWettering's MTV raytracer.
  11. * POV-Ray is just joining the crowd of admirers of Mark's contribution to
  12. * the public domain. [ARE]
  13. *
  14. * from Persistence of Vision(tm) Ray Tracer
  15. * Copyright 1996,1999 Persistence of Vision Team
  16. *---------------------------------------------------------------------------
  17. * NOTICE: This source code file is provided so that users may experiment
  18. * with enhancements to POV-Ray and to port the software to platforms other
  19. * than those supported by the POV-Ray Team. There are strict rules under
  20. * which you are permitted to use this file. The rules are in the file
  21. * named POVLEGAL.DOC which should be distributed with this file.
  22. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  23. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  24. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  25. *
  26. * This program is based on the popular DKB raytracer version 2.12.
  27. * DKBTrace was originally written by David K. Buck.
  28. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  29. *
  30. *****************************************************************************/
  31. #include "frame.h"
  32. #include "vector.h"
  33. #include "povproto.h"
  34. #include "bbox.h"
  35. #include "matrices.h"
  36. #include "objects.h"
  37. #include "povray.h"
  38. #include "render.h"
  39. /*****************************************************************************
  40. * Local preprocessor defines
  41. ******************************************************************************/
  42. #define BUNCHING_FACTOR 4
  43. /* Initial number of entries in a priority queue. */
  44. #define INITIAL_PRIORITY_QUEUE_SIZE 256
  45. /*****************************************************************************
  46. * Local typedefs
  47. ******************************************************************************/
  48. /*****************************************************************************
  49. * Static functions
  50. ******************************************************************************/
  51. static BBOX_TREE *create_bbox_node (int size);
  52. static int find_axis (BBOX_TREE **Finite, long first, long last);
  53. static void calc_bbox (BBOX *BBox, BBOX_TREE **Finite, long first, long last);
  54. static void build_area_table (BBOX_TREE **Finite, long a, long b, DBL *areas);
  55. static int sort_and_split (BBOX_TREE **Root, BBOX_TREE **Finite, long *nFinite, long first, long last);
  56. static void priority_queue_insert (PRIORITY_QUEUE *Queue, DBL Depth, BBOX_TREE *Node);
  57. static int CDECL compboxes (CONST void *in_a, CONST void *in_b);
  58. /*****************************************************************************
  59. * Local variables
  60. ******************************************************************************/
  61. /* Current axis to sort along. */
  62. static int Axis = 0;
  63. /* Number of finite elements. */
  64. static long maxfinitecount = 0;
  65. /* Priority queue used for frame level bouning box hierarchy. */
  66. static PRIORITY_QUEUE *Frame_Queue;
  67. /* Top node of bounding hierarchy. */
  68. BBOX_TREE *Root_Object;
  69. /*****************************************************************************
  70. *
  71. * FUNCTION
  72. *
  73. * Initialize_BBox_Code
  74. *
  75. * INPUT
  76. *
  77. * OUTPUT
  78. *
  79. * RETURNS
  80. *
  81. * AUTHOR
  82. *
  83. * Dieter Bayer
  84. *
  85. * DESCRIPTION
  86. *
  87. * Initialize bbox specific variables.
  88. *
  89. * CHANGES
  90. *
  91. * Jul 1995 : Creation.
  92. *
  93. ******************************************************************************/
  94. void Initialize_BBox_Code()
  95. {
  96. Frame_Queue = Create_Priority_Queue(INITIAL_PRIORITY_QUEUE_SIZE);
  97. }
  98. /*****************************************************************************
  99. *
  100. * FUNCTION
  101. *
  102. * Deinitialize_BBox_Code
  103. *
  104. * INPUT
  105. *
  106. * OUTPUT
  107. *
  108. * RETURNS
  109. *
  110. * AUTHOR
  111. *
  112. * Dieter Bayer
  113. *
  114. * DESCRIPTION
  115. *
  116. * Deinitialize bbox specific variables.
  117. *
  118. * CHANGES
  119. *
  120. * Jul 1995 : Creation.
  121. *
  122. ******************************************************************************/
  123. void Deinitialize_BBox_Code()
  124. {
  125. if (Frame_Queue != NULL)
  126. {
  127. Destroy_Priority_Queue(Frame_Queue);
  128. }
  129. Frame_Queue = NULL;
  130. }
  131. /*****************************************************************************
  132. *
  133. * FUNCTION
  134. *
  135. * Create_Priority_Queue
  136. *
  137. * INPUT
  138. *
  139. * QSize - initial size of priority queue
  140. *
  141. * OUTPUT
  142. *
  143. * RETURNS
  144. *
  145. * PRIORITY_QUEUE * - priority queue
  146. *
  147. * AUTHOR
  148. *
  149. * Dieter Bayer
  150. *
  151. * DESCRIPTION
  152. *
  153. * Create a priority queue.
  154. *
  155. * CHANGES
  156. *
  157. * Feb 1995 : Creation.
  158. *
  159. ******************************************************************************/
  160. PRIORITY_QUEUE *Create_Priority_Queue(unsigned QSize)
  161. {
  162. PRIORITY_QUEUE *New;
  163. New = (PRIORITY_QUEUE *)POV_MALLOC(sizeof(PRIORITY_QUEUE), "priority queue");
  164. New->Queue = (QELEM *)POV_MALLOC(QSize*sizeof(QELEM), "priority queue");
  165. New->QSize = 0;
  166. New->Max_QSize = QSize;
  167. return (New);
  168. }
  169. /*****************************************************************************
  170. *
  171. * FUNCTION
  172. *
  173. * Destroy_Priority_Queue
  174. *
  175. * INPUT
  176. *
  177. * Queue - Priority queue
  178. *
  179. * OUTPUT
  180. *
  181. * RETURNS
  182. *
  183. * AUTHOR
  184. *
  185. * Dieter Bayer
  186. *
  187. * DESCRIPTION
  188. *
  189. * Destroy a priority queue.
  190. *
  191. * CHANGES
  192. *
  193. * Feb 1995 : Creation.
  194. *
  195. ******************************************************************************/
  196. void Destroy_Priority_Queue(PRIORITY_QUEUE *Queue)
  197. {
  198. if (Queue != NULL)
  199. {
  200. POV_FREE(Queue->Queue);
  201. POV_FREE(Queue);
  202. }
  203. }
  204. /*****************************************************************************
  205. *
  206. * FUNCTION
  207. *
  208. * Destroy_BBox_Tree
  209. *
  210. * INPUT
  211. *
  212. * Node - Node to destroy
  213. *
  214. * OUTPUT
  215. *
  216. * RETURNS
  217. *
  218. * AUTHOR
  219. *
  220. * Dieter Bayer
  221. *
  222. * DESCRIPTION
  223. *
  224. * Recursively destroy a bounding box tree.
  225. *
  226. * CHANGES
  227. *
  228. * -
  229. *
  230. ******************************************************************************/
  231. void Destroy_BBox_Tree(BBOX_TREE *Node)
  232. {
  233. short i;
  234. if (Node != NULL)
  235. {
  236. if (Node->Entries > 0)
  237. {
  238. for (i = 0; i < Node->Entries; i++)
  239. {
  240. Destroy_BBox_Tree(Node->Node[i]);
  241. }
  242. POV_FREE(Node->Node);
  243. Node->Entries = 0;
  244. Node->Node = NULL;
  245. }
  246. POV_FREE(Node);
  247. }
  248. }
  249. /*****************************************************************************
  250. *
  251. * FUNCTION
  252. *
  253. * Recompute_BBox
  254. *
  255. * INPUT
  256. *
  257. * trans - Transformation
  258. *
  259. * OUTPUT
  260. *
  261. * bbox - Bounding box
  262. *
  263. * RETURNS
  264. *
  265. * AUTHOR
  266. *
  267. * Alexander Enzmann
  268. *
  269. * DESCRIPTION
  270. *
  271. * Recalculate a bounding box after a transformation.
  272. *
  273. * CHANGES
  274. *
  275. * -
  276. *
  277. ******************************************************************************/
  278. void Recompute_BBox(BBOX *bbox, TRANSFORM *trans)
  279. {
  280. int i;
  281. VECTOR lower_left, lengths, corner;
  282. VECTOR mins, maxs;
  283. if (trans == NULL)
  284. {
  285. return;
  286. }
  287. Assign_BBox_Vect(lower_left, bbox->Lower_Left);
  288. Assign_BBox_Vect(lengths, bbox->Lengths);
  289. Make_Vector(mins, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  290. Make_Vector(maxs, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  291. for (i = 1; i <= 8; i++)
  292. {
  293. Assign_Vector(corner, lower_left);
  294. corner[X] += ((i & 1) ? lengths[X] : 0.0);
  295. corner[Y] += ((i & 2) ? lengths[Y] : 0.0);
  296. corner[Z] += ((i & 4) ? lengths[Z] : 0.0);
  297. MTransPoint(corner, corner, trans);
  298. if (corner[X] < mins[X]) { mins[X] = corner[X]; }
  299. if (corner[X] > maxs[X]) { maxs[X] = corner[X]; }
  300. if (corner[Y] < mins[Y]) { mins[Y] = corner[Y]; }
  301. if (corner[Y] > maxs[Y]) { maxs[Y] = corner[Y]; }
  302. if (corner[Z] < mins[Z]) { mins[Z] = corner[Z]; }
  303. if (corner[Z] > maxs[Z]) { maxs[Z] = corner[Z]; }
  304. }
  305. /* Clip bounding box at the largest allowed bounding box. */
  306. if (mins[X] < -BOUND_HUGE / 2) { mins[X] = -BOUND_HUGE / 2; }
  307. if (mins[Y] < -BOUND_HUGE / 2) { mins[Y] = -BOUND_HUGE / 2; }
  308. if (mins[Z] < -BOUND_HUGE / 2) { mins[Z] = -BOUND_HUGE / 2; }
  309. if (maxs[X] > BOUND_HUGE / 2) { maxs[X] = BOUND_HUGE / 2; }
  310. if (maxs[Y] > BOUND_HUGE / 2) { maxs[Y] = BOUND_HUGE / 2; }
  311. if (maxs[Z] > BOUND_HUGE / 2) { maxs[Z] = BOUND_HUGE / 2; }
  312. Make_BBox_from_min_max(*bbox, mins, maxs);
  313. }
  314. /*****************************************************************************
  315. *
  316. * FUNCTION
  317. *
  318. * Recompute_Inverse_BBox
  319. *
  320. * INPUT
  321. *
  322. * trans - Transformation
  323. *
  324. * OUTPUT
  325. *
  326. * bbox - Bounding box
  327. *
  328. * RETURNS
  329. *
  330. * AUTHOR
  331. *
  332. * Alexander Enzmann
  333. *
  334. * DESCRIPTION
  335. *
  336. * Recalculate a bounding box after a transformation.
  337. *
  338. * CHANGES
  339. *
  340. * -
  341. *
  342. ******************************************************************************/
  343. void Recompute_Inverse_BBox(BBOX *bbox, TRANSFORM *trans)
  344. {
  345. int i;
  346. VECTOR lower_left, lengths, corner;
  347. VECTOR mins, maxs;
  348. if (trans == NULL)
  349. {
  350. return;
  351. }
  352. Assign_BBox_Vect(lower_left, bbox->Lower_Left);
  353. Assign_BBox_Vect(lengths, bbox->Lengths);
  354. Make_Vector(mins, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  355. Make_Vector(maxs, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  356. for (i = 1; i <= 8; i++)
  357. {
  358. Assign_Vector(corner, lower_left);
  359. corner[X] += ((i & 1) ? lengths[X] : 0.0);
  360. corner[Y] += ((i & 2) ? lengths[Y] : 0.0);
  361. corner[Z] += ((i & 4) ? lengths[Z] : 0.0);
  362. MInvTransPoint(corner, corner, trans);
  363. if (corner[X] < mins[X]) { mins[X] = corner[X]; }
  364. if (corner[X] > maxs[X]) { maxs[X] = corner[X]; }
  365. if (corner[Y] < mins[Y]) { mins[Y] = corner[Y]; }
  366. if (corner[Y] > maxs[Y]) { maxs[Y] = corner[Y]; }
  367. if (corner[Z] < mins[Z]) { mins[Z] = corner[Z]; }
  368. if (corner[Z] > maxs[Z]) { maxs[Z] = corner[Z]; }
  369. }
  370. /* Clip bounding box at the largest allowed bounding box. */
  371. if (mins[X] < -BOUND_HUGE / 2) { mins[X] = -BOUND_HUGE / 2; }
  372. if (mins[Y] < -BOUND_HUGE / 2) { mins[Y] = -BOUND_HUGE / 2; }
  373. if (mins[Z] < -BOUND_HUGE / 2) { mins[Z] = -BOUND_HUGE / 2; }
  374. if (maxs[X] > BOUND_HUGE / 2) { maxs[X] = BOUND_HUGE / 2; }
  375. if (maxs[Y] > BOUND_HUGE / 2) { maxs[Y] = BOUND_HUGE / 2; }
  376. if (maxs[Z] > BOUND_HUGE / 2) { maxs[Z] = BOUND_HUGE / 2; }
  377. Make_BBox_from_min_max(*bbox, mins, maxs);
  378. }
  379. /*****************************************************************************
  380. *
  381. * FUNCTION
  382. *
  383. * Build_BBox_Tree
  384. *
  385. * INPUT
  386. *
  387. * OUTPUT
  388. *
  389. * RETURNS
  390. *
  391. * AUTHOR
  392. *
  393. * Dieter Bayer
  394. *
  395. * DESCRIPTION
  396. *
  397. * Create a bounding box hierarchy from a given list of finite and
  398. * infinite elements. Each element consists of
  399. *
  400. * - an infinite flag
  401. * - a bounding box enclosing the element
  402. * - a pointer to the structure representing the element (e.g an object)
  403. *
  404. * CHANGES
  405. *
  406. * Feb 1995 : Creation. (Extracted from Build_Bounding_Slabs)
  407. * Sep 1995 : Changed to allow use of memcpy if memmove isn't available. [AED]
  408. * Jul 1996 : Changed to use POV_MEMMOVE, which can be memmove or pov_memmove
  409. *
  410. ******************************************************************************/
  411. void Build_BBox_Tree(BBOX_TREE **Root, long nFinite, BBOX_TREE **Finite, long nInfinite, BBOX_TREE **Infinite)
  412. {
  413. short i;
  414. long low, high;
  415. BBOX_TREE *cd, *root;
  416. /*
  417. * This is a resonable guess at the number of finites needed.
  418. * This array will be reallocated as needed if it isn't.
  419. */
  420. maxfinitecount = 2 * nFinite;
  421. /*
  422. * Now do a sort on the objects, with the end result being
  423. * a tree of objects sorted along the x, y, and z axes.
  424. */
  425. if (nFinite > 0)
  426. {
  427. low = 0;
  428. high = nFinite;
  429. while (sort_and_split(Root, Finite, &nFinite, low, high) == 0)
  430. {
  431. low = high;
  432. high = nFinite;
  433. }
  434. /* Move infinite objects in the first leaf of Root. */
  435. if (nInfinite > 0)
  436. {
  437. root = (BBOX_TREE *)(*Root);
  438. root->Node = (BBOX_TREE **)POV_REALLOC(root->Node, (root->Entries + 1) * sizeof(BBOX_TREE *), "composite");
  439. POV_MEMMOVE(&(root->Node[1]), &(root->Node[0]), root->Entries * sizeof(BBOX_TREE *));
  440. root->Entries++;
  441. cd = create_bbox_node(nInfinite);
  442. for (i = 0; i < nInfinite; i++)
  443. {
  444. cd->Node[i] = Infinite[i];
  445. }
  446. calc_bbox(&(cd->BBox), Infinite, 0, nInfinite);
  447. root->Node[0] = (BBOX_TREE *)cd;
  448. calc_bbox(&(root->BBox), root->Node, 0, root->Entries);
  449. /* Root and first node are infinite. */
  450. root->Infinite = TRUE;
  451. root->Node[0]->Infinite = TRUE;
  452. }
  453. }
  454. else
  455. {
  456. /*
  457. * There are no finite objects and no Root was created.
  458. * Create it now and put all infinite objects into it.
  459. */
  460. if (nInfinite > 0)
  461. {
  462. cd = create_bbox_node(nInfinite);
  463. for (i = 0; i < nInfinite; i++)
  464. {
  465. cd->Node[i] = Infinite[i];
  466. }
  467. calc_bbox(&(cd->BBox), Infinite, 0, nInfinite);
  468. *Root = (BBOX_TREE *)cd;
  469. (*Root)->Infinite = TRUE;
  470. }
  471. }
  472. }
  473. /*****************************************************************************
  474. *
  475. * FUNCTION
  476. *
  477. * Build_Bounding_Slabs
  478. *
  479. * INPUT
  480. *
  481. * OUTPUT
  482. *
  483. * RETURNS
  484. *
  485. * AUTHOR
  486. *
  487. * Alexander Enzmann
  488. *
  489. * DESCRIPTION
  490. *
  491. * Create the bounding box hierarchy for all objects in the scene.
  492. *
  493. * CHANGES
  494. *
  495. * Sep 1994 : Added allocation of priority queue. [DB]
  496. *
  497. * Sep 1994 : Added code to put all infinite objects in the first node
  498. * of the root. Thus the hierarchy won't be messed up. [DB]
  499. *
  500. * Sep 1994 : Fixed nIfinite=0 bug. [DB]
  501. *
  502. * Feb 1995 : Moved code to actually build the hierarchy. [DB]
  503. *
  504. ******************************************************************************/
  505. void Build_Bounding_Slabs(BBOX_TREE **Root)
  506. {
  507. long i, nFinite, nInfinite, iFinite, iInfinite;
  508. BBOX_TREE **Finite, **Infinite;
  509. OBJECT *Object, *Temp;
  510. /* Count frame level and infinite objects. */
  511. Object = Frame.Objects;
  512. nFinite = nInfinite = 0;
  513. while (Object != NULL)
  514. {
  515. if (Object->Type & LIGHT_SOURCE_OBJECT)
  516. {
  517. Temp = ((LIGHT_SOURCE *)Object)->Children;
  518. }
  519. else
  520. {
  521. Temp = Object;
  522. }
  523. if (Temp != NULL)
  524. {
  525. if (Test_Flag(Temp, INFINITE_FLAG))
  526. {
  527. nInfinite++;
  528. }
  529. else
  530. {
  531. nFinite++;
  532. }
  533. }
  534. Object = Object->Sibling;
  535. }
  536. /* We want to know how many objects there are. */
  537. Render_Info("\nScene contains %ld frame level objects; %ld infinite.\n",
  538. nFinite + nInfinite, nInfinite);
  539. /* If bounding boxes aren't used we can return. */
  540. if (!opts.Use_Slabs || !(nFinite + nInfinite >= opts.BBox_Threshold))
  541. {
  542. opts.Use_Slabs = FALSE;
  543. return;
  544. }
  545. opts.Use_Slabs = TRUE;
  546. /*
  547. * This is a resonable guess at the number of finites needed.
  548. * This array will be reallocated as needed if it isn't.
  549. */
  550. maxfinitecount = 2 * nFinite;
  551. /*
  552. * Now allocate an array to hold references to these finites and
  553. * any new composite objects we may generate.
  554. */
  555. Finite = Infinite = NULL;
  556. if (nFinite > 0)
  557. {
  558. Finite = (BBOX_TREE **)POV_MALLOC(maxfinitecount*sizeof(BBOX_TREE *), "bounding boxes");
  559. }
  560. /* Create array to hold pointers to infinite objects. */
  561. if (nInfinite > 0)
  562. {
  563. Infinite = (BBOX_TREE **)POV_MALLOC(nInfinite*sizeof(BBOX_TREE *), "bounding boxes");
  564. }
  565. /* Init lists. */
  566. for (i = 0; i < nFinite; i++)
  567. {
  568. Finite[i] = create_bbox_node(0);
  569. }
  570. for (i = 0; i < nInfinite; i++)
  571. {
  572. Infinite[i] = create_bbox_node(0);
  573. }
  574. /* Set up finite and infinite object lists. */
  575. iFinite = iInfinite = 0;
  576. for (Object = Frame.Objects; Object != NULL; Object = Object->Sibling)
  577. {
  578. if (Object->Type & LIGHT_SOURCE_OBJECT)
  579. {
  580. Temp = ((LIGHT_SOURCE *)Object)->Children;
  581. }
  582. else
  583. {
  584. Temp = Object;
  585. }
  586. if (Temp != NULL)
  587. {
  588. /* Add object to the appropriate list. */
  589. if (Test_Flag(Temp, INFINITE_FLAG))
  590. {
  591. Infinite[iInfinite]->Infinite = TRUE;
  592. Infinite[iInfinite]->BBox = Temp->BBox;
  593. Infinite[iInfinite]->Node = (BBOX_TREE **)Temp;
  594. iInfinite++;
  595. }
  596. else
  597. {
  598. Finite[iFinite]->BBox = Temp->BBox;
  599. Finite[iFinite]->Node = (BBOX_TREE **)Temp;
  600. iFinite++;
  601. }
  602. }
  603. }
  604. /*
  605. * Now build the bounding box tree.
  606. */
  607. Build_BBox_Tree(Root, nFinite, Finite, nInfinite, Infinite);
  608. /* Get rid of the Finite and Infinite arrays and just use Root. */
  609. if (Finite != NULL)
  610. {
  611. POV_FREE(Finite);
  612. }
  613. if (Infinite != NULL)
  614. {
  615. POV_FREE(Infinite);
  616. }
  617. }
  618. /*****************************************************************************
  619. *
  620. * FUNCTION
  621. *
  622. * Destroy_Bounding_Slabs
  623. *
  624. * INPUT
  625. *
  626. * OUTPUT
  627. *
  628. * RETURNS
  629. *
  630. * AUTHOR
  631. *
  632. * Alexander Enzmann
  633. *
  634. * DESCRIPTION
  635. *
  636. * Destroy the bounding box hierarchy and the priority queue.
  637. *
  638. * CHANGES
  639. *
  640. * Sep 1994 : Added freeing of priority queue. [DB]
  641. *
  642. ******************************************************************************/
  643. void Destroy_Bounding_Slabs()
  644. {
  645. if (Root_Object != NULL)
  646. {
  647. Destroy_BBox_Tree(Root_Object);
  648. Root_Object = NULL;
  649. }
  650. }
  651. /*****************************************************************************
  652. *
  653. * FUNCTION
  654. *
  655. * Intersect_BBox_Tree
  656. *
  657. * INPUT
  658. *
  659. * Root - Root node of the bbox tree
  660. * Ray - Current ray
  661. *
  662. * OUTPUT
  663. *
  664. * Best_Intersection - Nearest intersection found
  665. * Best_Object - Nearest object found
  666. *
  667. * RETURNS
  668. *
  669. * int - TRUE if an intersection was found
  670. *
  671. * AUTHOR
  672. *
  673. * Alexander Enzmann
  674. *
  675. * DESCRIPTION
  676. *
  677. * Intersect a ray with a bounding box tree.
  678. *
  679. * CHANGES
  680. *
  681. * Sep 1994 : Moved priority queue allocation/freeing out of here. [DB]
  682. *
  683. ******************************************************************************/
  684. int Intersect_BBox_Tree(BBOX_TREE *Root, RAY *Ray, INTERSECTION *Best_Intersection, OBJECT **Best_Object)
  685. {
  686. int i, found;
  687. DBL Depth;
  688. BBOX_TREE *Node;
  689. RAYINFO rayinfo;
  690. INTERSECTION New_Intersection;
  691. /* Create the direction vectors for this ray. */
  692. Create_Rayinfo(Ray, &rayinfo);
  693. /* Start with an empty priority queue. */
  694. found = FALSE;
  695. Frame_Queue->QSize = 0;
  696. #ifdef BBOX_EXTRA_STATS
  697. Increase_Counter(stats[totalQueueResets]);
  698. #endif
  699. /* Check top node. */
  700. Check_And_Enqueue(Frame_Queue, Root, &Root->BBox, &rayinfo);
  701. /* Check elements in the priority queue. */
  702. while (Frame_Queue->QSize)
  703. {
  704. Priority_Queue_Delete(Frame_Queue, &Depth, &Node);
  705. /*
  706. * If current intersection is larger than the best intersection found
  707. * so far our task is finished, because all other bounding boxes in
  708. * the priority queue are further away.
  709. */
  710. if (Depth > Best_Intersection->Depth)
  711. {
  712. break;
  713. }
  714. /* Check current node. */
  715. if (Node->Entries)
  716. {
  717. /* This is a node containing leaves to be checked. */
  718. for (i = 0; i < Node->Entries; i++)
  719. {
  720. Check_And_Enqueue(Frame_Queue, Node->Node[i], &Node->Node[i]->BBox, &rayinfo);
  721. }
  722. }
  723. else
  724. {
  725. /* This is a leaf so test contained object. */
  726. if (Intersection(&New_Intersection, (OBJECT *)Node->Node, Ray))
  727. {
  728. if (New_Intersection.Depth < Best_Intersection->Depth)
  729. {
  730. *Best_Intersection = New_Intersection;
  731. *Best_Object = (OBJECT *)Node->Node;
  732. found = TRUE;
  733. }
  734. }
  735. }
  736. }
  737. return (found);
  738. }
  739. /*****************************************************************************
  740. *
  741. * FUNCTION
  742. *
  743. * priority_queue_insert
  744. *
  745. * INPUT
  746. *
  747. * OUTPUT
  748. *
  749. * RETURNS
  750. *
  751. * AUTHOR
  752. *
  753. * Alexander Enzmann
  754. *
  755. * DESCRIPTION
  756. *
  757. * Insert an element in the priority queue.
  758. *
  759. * CHANGES
  760. *
  761. * Sep 1994 : Added code for resizing the priority queue. [DB]
  762. *
  763. ******************************************************************************/
  764. static void priority_queue_insert(PRIORITY_QUEUE *Queue, DBL Depth, BBOX_TREE *Node)
  765. {
  766. unsigned size;
  767. int i;
  768. QELEM tmp, *List;
  769. #ifdef BBOX_EXTRA_STATS
  770. Increase_Counter(stats[totalQueues]);
  771. #endif
  772. Queue->QSize++;
  773. size = Queue->QSize;
  774. /* Reallocate priority queue if it's too small. */
  775. if (size >= Queue->Max_QSize)
  776. {
  777. if (size >= INT_MAX/2)
  778. {
  779. Error("Priority queue overflow.\n");
  780. }
  781. #ifdef BBOX_EXTRA_STATS
  782. Increase_Counter(stats[totalQueueResizes]);
  783. #endif
  784. Queue->Max_QSize *= 2;
  785. Queue->Queue = (QELEM *)POV_REALLOC(Queue->Queue, Queue->Max_QSize*sizeof(QELEM), "priority queue");
  786. }
  787. List = Queue->Queue;
  788. List[size].Depth = Depth;
  789. List[size].Node = Node;
  790. i = size;
  791. while (i > 1 && List[i].Depth < List[i / 2].Depth)
  792. {
  793. tmp = List[i];
  794. List[i] = List[i / 2];
  795. List[i / 2] = tmp;
  796. i = i / 2;
  797. }
  798. }
  799. /*****************************************************************************
  800. *
  801. * FUNCTION
  802. *
  803. * Priority_Queue_Delete
  804. *
  805. * INPUT
  806. *
  807. * OUTPUT
  808. *
  809. * RETURNS
  810. *
  811. * AUTHOR
  812. *
  813. * Alexander Enzmann
  814. *
  815. * DESCRIPTION
  816. *
  817. * Get an element from the priority queue.
  818. *
  819. * NOTE: This element will always be the one closest to the ray origin.
  820. *
  821. * CHANGES
  822. *
  823. * -
  824. *
  825. ******************************************************************************/
  826. void Priority_Queue_Delete(PRIORITY_QUEUE *Queue, DBL *Depth, BBOX_TREE **Node)
  827. {
  828. QELEM tmp, *List;
  829. int i, j;
  830. unsigned size;
  831. if (Queue->QSize == 0)
  832. {
  833. Error("priority queue is empty.\n");
  834. }
  835. List = Queue->Queue;
  836. *Depth = List[1].Depth;
  837. *Node = List[1].Node;
  838. List[1] = List[Queue->QSize];
  839. Queue->QSize--;
  840. size = Queue->QSize;
  841. i = 1;
  842. while (2 * i <= (int)size)
  843. {
  844. if (2 * i == (int)size)
  845. {
  846. j = 2 * i;
  847. }
  848. else
  849. {
  850. if (List[2*i].Depth < List[2*i+1].Depth)
  851. {
  852. j = 2 * i;
  853. }
  854. else
  855. {
  856. j = 2 * i + 1;
  857. }
  858. }
  859. if (List[i].Depth > List[j].Depth)
  860. {
  861. tmp = List[i];
  862. List[i] = List[j];
  863. List[j] = tmp;
  864. i = j;
  865. }
  866. else
  867. {
  868. break;
  869. }
  870. }
  871. }
  872. /*****************************************************************************
  873. *
  874. * FUNCTION
  875. *
  876. * Check_And_Enqueue
  877. *
  878. * INPUT
  879. *
  880. * OUTPUT
  881. *
  882. * RETURNS
  883. *
  884. * AUTHOR
  885. *
  886. * Alexander Enzmann
  887. *
  888. * DESCRIPTION
  889. *
  890. * If a given ray intersect the object's bounding box then add it
  891. * to the priority queue.
  892. *
  893. * CHANGES
  894. *
  895. * Sep 1994 : Pass bounding box seperately.
  896. * This is needed for the vista/light buffer. [DB]
  897. *
  898. * Sep 1994 : Added code to insert infinte objects without testing. [DB]
  899. *
  900. ******************************************************************************/
  901. void Check_And_Enqueue(PRIORITY_QUEUE *Queue, BBOX_TREE *Node, BBOX *BBox, RAYINFO *rayinfo)
  902. {
  903. DBL tmin, tmax;
  904. DBL dmin, dmax;
  905. if (Node->Infinite)
  906. {
  907. /* Set intersection depth to -Max_Distance. */
  908. dmin = -Max_Distance;
  909. }
  910. else
  911. {
  912. Increase_Counter(stats[nChecked]);
  913. if (rayinfo->nonzero[X])
  914. {
  915. if (rayinfo->positive[X])
  916. {
  917. dmin = (BBox->Lower_Left[X] - rayinfo->slab_num[X]) * rayinfo->slab_den[X];
  918. dmax = dmin + (BBox->Lengths[X] * rayinfo->slab_den[X]);
  919. if (dmax < EPSILON) return;
  920. }
  921. else
  922. {
  923. dmax = (BBox->Lower_Left[X] - rayinfo->slab_num[X]) * rayinfo->slab_den[X];
  924. if (dmax < EPSILON) return;
  925. dmin = dmax + (BBox->Lengths[X] * rayinfo->slab_den[X]);
  926. }
  927. if (dmin > dmax) return;
  928. }
  929. else
  930. {
  931. if ((rayinfo->slab_num[X] < BBox->Lower_Left[X]) ||
  932. (rayinfo->slab_num[X] > BBox->Lengths[X] + BBox->Lower_Left[X]))
  933. {
  934. return;
  935. }
  936. dmin = -BOUND_HUGE;
  937. dmax = BOUND_HUGE;
  938. }
  939. if (rayinfo->nonzero[Y])
  940. {
  941. if (rayinfo->positive[Y])
  942. {
  943. tmin = (BBox->Lower_Left[Y] - rayinfo->slab_num[Y]) * rayinfo->slab_den[Y];
  944. tmax = tmin + (BBox->Lengths[Y] * rayinfo->slab_den[Y]);
  945. }
  946. else
  947. {
  948. tmax = (BBox->Lower_Left[Y] - rayinfo->slab_num[Y]) * rayinfo->slab_den[Y];
  949. tmin = tmax + (BBox->Lengths[Y] * rayinfo->slab_den[Y]);
  950. }
  951. /*
  952. * Unwrap the logic - do the dmin and dmax checks only when tmin and
  953. * tmax actually affect anything, also try to escape ASAP. Better
  954. * yet, fold the logic below into the two branches above so as to
  955. * compute only what is needed.
  956. */
  957. /*
  958. * You might even try tmax < EPSILON first (instead of second) for an
  959. * early quick out.
  960. */
  961. if (tmax < dmax)
  962. {
  963. if (tmax < EPSILON) return;
  964. /* check bbox only if tmax changes dmax */
  965. if (tmin > dmin)
  966. {
  967. if (tmin > tmax) return;
  968. /* do this last in case it's not needed! */
  969. dmin = tmin;
  970. }
  971. else
  972. {
  973. if (dmin > tmax) return;
  974. }
  975. /* do this last in case it's not needed! */
  976. dmax = tmax;
  977. }
  978. else
  979. {
  980. if (tmin > dmin)
  981. {
  982. if (tmin > dmax) return;
  983. /* do this last in case it's not needed! */
  984. dmin = tmin;
  985. }
  986. /* else nothing needs to happen, since dmin and dmax did not change! */
  987. }
  988. }
  989. else
  990. {
  991. if ((rayinfo->slab_num[Y] < BBox->Lower_Left[Y]) ||
  992. (rayinfo->slab_num[Y] > BBox->Lengths[Y] + BBox->Lower_Left[Y]))
  993. {
  994. return;
  995. }
  996. }
  997. if (rayinfo->nonzero[Z])
  998. {
  999. if (rayinfo->positive[Z])
  1000. {
  1001. tmin = (BBox->Lower_Left[Z] - rayinfo->slab_num[Z]) * rayinfo->slab_den[Z];
  1002. tmax = tmin + (BBox->Lengths[Z] * rayinfo->slab_den[Z]);
  1003. }
  1004. else
  1005. {
  1006. tmax = (BBox->Lower_Left[Z] - rayinfo->slab_num[Z]) * rayinfo->slab_den[Z];
  1007. tmin = tmax + (BBox->Lengths[Z] * rayinfo->slab_den[Z]);
  1008. }
  1009. if (tmax < dmax)
  1010. {
  1011. if (tmax < EPSILON) return;
  1012. /* check bbox only if tmax changes dmax */
  1013. if (tmin > dmin)
  1014. {
  1015. if (tmin > tmax) return;
  1016. /* do this last in case it's not needed! */
  1017. dmin = tmin;
  1018. }
  1019. else
  1020. {
  1021. if (dmin > tmax) return;
  1022. }
  1023. }
  1024. else
  1025. {
  1026. if (tmin > dmin)
  1027. {
  1028. if (tmin > dmax) return;
  1029. /* do this last in case it's not needed! */
  1030. dmin = tmin;
  1031. }
  1032. /* else nothing needs to happen, since dmin and dmax did not change! */
  1033. }
  1034. }
  1035. else
  1036. {
  1037. if ((rayinfo->slab_num[Z] < BBox->Lower_Left[Z]) ||
  1038. (rayinfo->slab_num[Z] > BBox->Lengths[Z] + BBox->Lower_Left[Z]))
  1039. {
  1040. return;
  1041. }
  1042. }
  1043. Increase_Counter(stats[nEnqueued]);
  1044. }
  1045. priority_queue_insert(Queue, dmin, Node);
  1046. }
  1047. /*****************************************************************************
  1048. *
  1049. * FUNCTION
  1050. *
  1051. * Create_Rayinfo
  1052. *
  1053. * INPUT
  1054. *
  1055. * Ray - Current ray
  1056. * rayinfo - Rayinfo structure
  1057. *
  1058. * OUTPUT
  1059. *
  1060. * rayinfo
  1061. *
  1062. * RETURNS
  1063. *
  1064. * AUTHOR
  1065. *
  1066. * Dieter Bayer
  1067. *
  1068. * DESCRIPTION
  1069. *
  1070. * Calculate the rayinfo structure for a given ray. It's need for
  1071. * intersection the ray with bounding boxes.
  1072. *
  1073. * CHANGES
  1074. *
  1075. * May 1994 : Creation. (Extracted from Intersect_BBox_Tree)
  1076. *
  1077. ******************************************************************************/
  1078. void Create_Rayinfo(RAY *Ray, RAYINFO *rayinfo)
  1079. {
  1080. DBL t;
  1081. /* Create the direction vectors for this ray */
  1082. Assign_Vector(rayinfo->slab_num, Ray->Initial);
  1083. if ((rayinfo->nonzero[X] = ((t = Ray->Direction[X]) != 0.0)) != 0)
  1084. {
  1085. rayinfo->slab_den[X] = 1.0 / t;
  1086. rayinfo->positive[X] = (Ray->Direction[X] > 0.0);
  1087. }
  1088. if ((rayinfo->nonzero[Y] = ((t = Ray->Direction[Y]) != 0.0)) != 0)
  1089. {
  1090. rayinfo->slab_den[Y] = 1.0 / t;
  1091. rayinfo->positive[Y] = (Ray->Direction[Y] > 0.0);
  1092. }
  1093. if ((rayinfo->nonzero[Z] = ((t = Ray->Direction[Z]) != 0.0)) != 0)
  1094. {
  1095. rayinfo->slab_den[Z] = 1.0 / t;
  1096. rayinfo->positive[Z] = (Ray->Direction[Z] > 0.0);
  1097. }
  1098. }
  1099. /*****************************************************************************
  1100. *
  1101. * FUNCTION
  1102. *
  1103. * create_bbox_node
  1104. *
  1105. * INPUT
  1106. *
  1107. * size - Number of subnodes
  1108. *
  1109. * OUTPUT
  1110. *
  1111. * RETURNS
  1112. *
  1113. * BBOX_TREE * - New node
  1114. *
  1115. * AUTHOR
  1116. *
  1117. * Alexander Enzmann
  1118. *
  1119. * DESCRIPTION
  1120. *
  1121. * -
  1122. *
  1123. * CHANGES
  1124. *
  1125. * -
  1126. *
  1127. ******************************************************************************/
  1128. static BBOX_TREE *create_bbox_node(int size)
  1129. {
  1130. BBOX_TREE *New;
  1131. New = (BBOX_TREE *)POV_MALLOC(sizeof(BBOX_TREE), "bounding box node");
  1132. New->Infinite = FALSE;
  1133. New->Entries = size;
  1134. Make_BBox(New->BBox, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  1135. if (size)
  1136. {
  1137. New->Node = (BBOX_TREE **)POV_MALLOC(size*sizeof(BBOX_TREE *), "bounding box node");
  1138. }
  1139. else
  1140. {
  1141. New->Node = NULL;
  1142. }
  1143. return (New);
  1144. }
  1145. /*****************************************************************************
  1146. *
  1147. * FUNCTION
  1148. *
  1149. * compboxes
  1150. *
  1151. * INPUT
  1152. *
  1153. * in_a, in_b - Elements to compare
  1154. *
  1155. * OUTPUT
  1156. *
  1157. * RETURNS
  1158. *
  1159. * int - result of comparison
  1160. *
  1161. * AUTHOR
  1162. *
  1163. * Alexander Enzmann
  1164. *
  1165. * DESCRIPTION
  1166. *
  1167. * -
  1168. *
  1169. * CHANGES
  1170. *
  1171. * Sep 1994 : Removed test for infinite objects because it's obsolete. [DB]
  1172. *
  1173. ******************************************************************************/
  1174. static int CDECL compboxes(CONST void *in_a, CONST void *in_b)
  1175. {
  1176. BBOX *a, *b;
  1177. BBOX_VAL am, bm;
  1178. a = &((*(BBOX_TREE **)in_a)->BBox);
  1179. b = &((*(BBOX_TREE **)in_b)->BBox);
  1180. am = 2.0 * a->Lower_Left[Axis] + a->Lengths[Axis];
  1181. bm = 2.0 * b->Lower_Left[Axis] + b->Lengths[Axis];
  1182. if (am < bm)
  1183. {
  1184. return (-1);
  1185. }
  1186. else
  1187. {
  1188. if (am == bm)
  1189. {
  1190. return (0);
  1191. }
  1192. else
  1193. {
  1194. return (1);
  1195. }
  1196. }
  1197. }
  1198. /*****************************************************************************
  1199. *
  1200. * FUNCTION
  1201. *
  1202. * find_axis
  1203. *
  1204. * INPUT
  1205. *
  1206. * Finite - Array of finite elements
  1207. * first, last - Position of elements
  1208. *
  1209. * OUTPUT
  1210. *
  1211. * RETURNS
  1212. *
  1213. * int - Axis to sort along
  1214. *
  1215. * AUTHOR
  1216. *
  1217. * Alexander Enzmann
  1218. *
  1219. * DESCRIPTION
  1220. *
  1221. * Find the axis along which the elements will be sorted.
  1222. *
  1223. * CHANGES
  1224. *
  1225. * Sep 1994 : Initialize local variable which. [DB]
  1226. *
  1227. ******************************************************************************/
  1228. static int find_axis(BBOX_TREE **Finite, long first, long last)
  1229. {
  1230. int which = X;
  1231. long i;
  1232. DBL e, d = -BOUND_HUGE;
  1233. VECTOR mins, maxs;
  1234. BBOX *bbox;
  1235. Make_Vector(mins, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  1236. Make_Vector(maxs, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  1237. for (i = first; i < last; i++)
  1238. {
  1239. bbox = &(Finite[i]->BBox);
  1240. if (bbox->Lower_Left[X] < mins[X])
  1241. {
  1242. mins[X] = bbox->Lower_Left[X];
  1243. }
  1244. if (bbox->Lower_Left[X] + bbox->Lengths[X] > maxs[X])
  1245. {
  1246. maxs[X] = bbox->Lower_Left[X];
  1247. }
  1248. if (bbox->Lower_Left[Y] < mins[Y])
  1249. {
  1250. mins[Y] = bbox->Lower_Left[Y];
  1251. }
  1252. if (bbox->Lower_Left[Y] + bbox->Lengths[Y] > maxs[Y])
  1253. {
  1254. maxs[Y] = bbox->Lower_Left[Y];
  1255. }
  1256. if (bbox->Lower_Left[Z] < mins[Z])
  1257. {
  1258. mins[Z] = bbox->Lower_Left[Z];
  1259. }
  1260. if (bbox->Lower_Left[Z] + bbox->Lengths[Z] > maxs[Z])
  1261. {
  1262. maxs[Z] = bbox->Lower_Left[Z];
  1263. }
  1264. }
  1265. e = maxs[X] - mins[X];
  1266. if (e > d)
  1267. {
  1268. d = e; which = X;
  1269. }
  1270. e = maxs[Y] - mins[Y];
  1271. if (e > d)
  1272. {
  1273. d = e; which = Y;
  1274. }
  1275. e = maxs[Z] - mins[Z];
  1276. if (e > d)
  1277. {
  1278. which = Z;
  1279. }
  1280. return (which);
  1281. }
  1282. /*****************************************************************************
  1283. *
  1284. * FUNCTION
  1285. *
  1286. * calc_bbox
  1287. *
  1288. * INPUT
  1289. *
  1290. * OUTPUT
  1291. *
  1292. * RETURNS
  1293. *
  1294. * AUTHOR
  1295. *
  1296. * Alexander Enzmann
  1297. *
  1298. * DESCRIPTION
  1299. *
  1300. * Calculate the bounding box containing Finite[first] through Finite[last-1].
  1301. *
  1302. * CHANGES
  1303. *
  1304. * -
  1305. *
  1306. ******************************************************************************/
  1307. static void calc_bbox(BBOX *BBox, BBOX_TREE **Finite, long first, long last)
  1308. {
  1309. long i;
  1310. DBL tmin, tmax;
  1311. VECTOR bmin, bmax;
  1312. BBOX *bbox;
  1313. COOPERATE_1
  1314. Make_Vector(bmin, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  1315. Make_Vector(bmax, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  1316. for (i = first; i < last; i++)
  1317. {
  1318. bbox = &(Finite[i]->BBox);
  1319. tmin = bbox->Lower_Left[X];
  1320. tmax = tmin + bbox->Lengths[X];
  1321. if (tmin < bmin[X]) { bmin[X] = tmin; }
  1322. if (tmax > bmax[X]) { bmax[X] = tmax; }
  1323. tmin = bbox->Lower_Left[Y];
  1324. tmax = tmin + bbox->Lengths[Y];
  1325. if (tmin < bmin[Y]) { bmin[Y] = tmin; }
  1326. if (tmax > bmax[Y]) { bmax[Y] = tmax; }
  1327. tmin = bbox->Lower_Left[Z];
  1328. tmax = tmin + bbox->Lengths[Z];
  1329. if (tmin < bmin[Z]) { bmin[Z] = tmin; }
  1330. if (tmax > bmax[Z]) { bmax[Z] = tmax; }
  1331. }
  1332. Make_BBox_from_min_max(*BBox, bmin, bmax);
  1333. }
  1334. /*****************************************************************************
  1335. *
  1336. * FUNCTION
  1337. *
  1338. * build_area_table
  1339. *
  1340. * INPUT
  1341. *
  1342. * OUTPUT
  1343. *
  1344. * RETURNS
  1345. *
  1346. * AUTHOR
  1347. *
  1348. * Alexander Enzmann
  1349. *
  1350. * DESCRIPTION
  1351. *
  1352. * Generates a table of bound box surface areas.
  1353. *
  1354. * CHANGES
  1355. *
  1356. * -
  1357. *
  1358. ******************************************************************************/
  1359. static void build_area_table(BBOX_TREE **Finite, long a, long b, DBL *areas)
  1360. {
  1361. long i, imin, dir;
  1362. DBL tmin, tmax;
  1363. VECTOR bmin, bmax, len;
  1364. BBOX *bbox;
  1365. if (a < b)
  1366. {
  1367. imin = a; dir = 1;
  1368. }
  1369. else
  1370. {
  1371. imin = b; dir = -1;
  1372. }
  1373. Make_Vector(bmin, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  1374. Make_Vector(bmax, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  1375. for (i = a; i != (b + dir); i += dir)
  1376. {
  1377. bbox = &(Finite[i]->BBox);
  1378. tmin = bbox->Lower_Left[X];
  1379. tmax = tmin + bbox->Lengths[X];
  1380. if (tmin < bmin[X]) { bmin[X] = tmin; }
  1381. if (tmax > bmax[X]) { bmax[X] = tmax; }
  1382. tmin = bbox->Lower_Left[Y];
  1383. tmax = tmin + bbox->Lengths[Y];
  1384. if (tmin < bmin[Y]) { bmin[Y] = tmin; }
  1385. if (tmax > bmax[Y]) { bmax[Y] = tmax; }
  1386. tmin = bbox->Lower_Left[Z];
  1387. tmax = tmin + bbox->Lengths[Z];
  1388. if (tmin < bmin[Z]) { bmin[Z] = tmin; }
  1389. if (tmax > bmax[Z]) { bmax[Z] = tmax; }
  1390. VSub(len, bmax, bmin);
  1391. areas[i - imin] = len[X] * (len[Y] + len[Z]) + len[Y] * len[Z];
  1392. }
  1393. }
  1394. /*****************************************************************************
  1395. *
  1396. * FUNCTION
  1397. *
  1398. * sort_and_split
  1399. *
  1400. * INPUT
  1401. *
  1402. * OUTPUT
  1403. *
  1404. * RETURNS
  1405. *
  1406. * AUTHOR
  1407. *
  1408. * Alexander Enzmann
  1409. *
  1410. * DESCRIPTION
  1411. *
  1412. * -
  1413. *
  1414. * CHANGES
  1415. *
  1416. * -
  1417. *
  1418. ******************************************************************************/
  1419. static int sort_and_split(BBOX_TREE **Root, BBOX_TREE **Finite, long *nFinite, long first, long last)
  1420. {
  1421. BBOX_TREE *cd;
  1422. long size, i, best_loc;
  1423. DBL *area_left, *area_right;
  1424. DBL best_index, new_index;
  1425. Axis = find_axis(Finite, first, last);
  1426. size = last - first;
  1427. if (size <= 0)
  1428. {
  1429. return (1);
  1430. }
  1431. /*
  1432. * Actually, we could do this faster in several ways. We could use a
  1433. * logn algorithm to find the median along the given axis, and then a
  1434. * linear algorithm to partition along the axis. Oh well.
  1435. */
  1436. QSORT((void *)(&Finite[first]), (unsigned long)size, sizeof(BBOX_TREE *), compboxes);
  1437. /*
  1438. * area_left[] and area_right[] hold the surface areas of the bounding
  1439. * boxes to the left and right of any given point. E.g. area_left[i] holds
  1440. * the surface area of the bounding box containing Finite 0 through i and
  1441. * area_right[i] holds the surface area of the box containing Finite
  1442. * i through size-1.
  1443. */
  1444. area_left = (DBL *)POV_MALLOC(size * sizeof(DBL), "bounding boxes");
  1445. area_right = (DBL *)POV_MALLOC(size * sizeof(DBL), "bounding boxes");
  1446. /* Precalculate the areas for speed. */
  1447. build_area_table(Finite, first, last - 1, area_left);
  1448. build_area_table(Finite, last - 1, first, area_right);
  1449. best_index = area_right[0] * (size - 3.0);
  1450. best_loc = -1;
  1451. /*
  1452. * Find the most effective point to split. The best location will be
  1453. * the one that minimizes the function N1*A1 + N2*A2 where N1 and N2
  1454. * are the number of objects in the two groups and A1 and A2 are the
  1455. * surface areas of the bounding boxes of the two groups.
  1456. */
  1457. for (i = 0; i < size - 1; i++)
  1458. {
  1459. new_index = (i + 1) * area_left[i] + (size - 1 - i) * area_right[i + 1];
  1460. if (new_index < best_index)
  1461. {
  1462. best_index = new_index;
  1463. best_loc = i + first;
  1464. }
  1465. }
  1466. POV_FREE(area_left);
  1467. POV_FREE(area_right);
  1468. /*
  1469. * Stop splitting if the BUNCHING_FACTOR is reached or
  1470. * if splitting stops being effective.
  1471. */
  1472. if ((size <= BUNCHING_FACTOR) || (best_loc < 0))
  1473. {
  1474. cd = create_bbox_node(size);
  1475. for (i = 0; i < size; i++)
  1476. {
  1477. cd->Node[i] = Finite[first+i];
  1478. }
  1479. calc_bbox(&(cd->BBox), Finite, first, last);
  1480. *Root = (BBOX_TREE *)cd;
  1481. if (*nFinite > maxfinitecount)
  1482. {
  1483. /* Prim array overrun, increase array by 50%. */
  1484. maxfinitecount = 1.5 * maxfinitecount;
  1485. /* For debugging only. */
  1486. Debug_Info("Reallocing Finite to %d\n", maxfinitecount);
  1487. Finite = (BBOX_TREE **)POV_REALLOC(Finite, maxfinitecount * sizeof(BBOX_TREE *), "bounding boxes");
  1488. }
  1489. Finite[*nFinite] = cd;
  1490. (*nFinite)++;
  1491. return (1);
  1492. }
  1493. else
  1494. {
  1495. sort_and_split(Root, Finite, nFinite, first, best_loc + 1);
  1496. sort_and_split(Root, Finite, nFinite, best_loc + 1, last);
  1497. return (0);
  1498. }
  1499. }