BOXES.C 19 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. /****************************************************************************
  2. * boxes.c
  3. *
  4. * This module implements the box primitive.
  5. * This file was written by Alexander Enzmann. He wrote the code for
  6. * boxes and generously provided us these enhancements.
  7. *
  8. * from Persistence of Vision(tm) Ray Tracer
  9. * Copyright 1996,1999 Persistence of Vision Team
  10. *---------------------------------------------------------------------------
  11. * NOTICE: This source code file is provided so that users may experiment
  12. * with enhancements to POV-Ray and to port the software to platforms other
  13. * than those supported by the POV-Ray Team. There are strict rules under
  14. * which you are permitted to use this file. The rules are in the file
  15. * named POVLEGAL.DOC which should be distributed with this file.
  16. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  17. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  18. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  19. *
  20. * This program is based on the popular DKB raytracer version 2.12.
  21. * DKBTrace was originally written by David K. Buck.
  22. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  23. *
  24. *****************************************************************************/
  25. #include "frame.h"
  26. #include "povray.h"
  27. #include "vector.h"
  28. #include "povproto.h"
  29. #include "bbox.h"
  30. #include "boxes.h"
  31. #include "matrices.h"
  32. #include "objects.h"
  33. /*****************************************************************************
  34. * Local preprocessor defines
  35. ******************************************************************************/
  36. /* Minimal intersection depth. */
  37. #define DEPTH_TOLERANCE 1.0e-6
  38. /* Two values are equal if their difference is small than CLOSE_TOLERANCE. */
  39. #define CLOSE_TOLERANCE 1.0e-6
  40. /* Side hit. */
  41. #define SIDE_X_0 1
  42. #define SIDE_X_1 2
  43. #define SIDE_Y_0 3
  44. #define SIDE_Y_1 4
  45. #define SIDE_Z_0 5
  46. #define SIDE_Z_1 6
  47. /*****************************************************************************
  48. * Static functions
  49. ******************************************************************************/
  50. static int All_Box_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  51. static int Inside_Box (VECTOR point, OBJECT *Object);
  52. static void Box_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  53. static void Translate_Box (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  54. static void Rotate_Box (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  55. static void Scale_Box (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  56. static void Transform_Box (OBJECT *Object, TRANSFORM *Trans);
  57. static void Invert_Box (OBJECT *Object);
  58. /*****************************************************************************
  59. * Local variables
  60. ******************************************************************************/
  61. METHODS Box_Methods =
  62. {
  63. All_Box_Intersections,
  64. Inside_Box, Box_Normal,
  65. (COPY_METHOD)Copy_Box, Translate_Box, Rotate_Box, Scale_Box, Transform_Box,
  66. Invert_Box, Destroy_Box
  67. };
  68. /*****************************************************************************
  69. *
  70. * FUNCTION
  71. *
  72. * All_Box_Intersections
  73. *
  74. * INPUT
  75. *
  76. * OUTPUT
  77. *
  78. * RETURNS
  79. *
  80. * AUTHOR
  81. *
  82. * Alexander Enzmann
  83. *
  84. * DESCRIPTION
  85. *
  86. * -
  87. *
  88. * CHANGES
  89. *
  90. * -
  91. *
  92. ******************************************************************************/
  93. static int All_Box_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  94. {
  95. int Intersection_Found;
  96. int Side1, Side2;
  97. DBL Depth1, Depth2;
  98. VECTOR IPoint;
  99. Increase_Counter(stats[Ray_Box_Tests]);
  100. Intersection_Found = FALSE;
  101. if (Intersect_Box(Ray, (BOX *)Object, &Depth1, &Depth2, &Side1, &Side2))
  102. {
  103. if (Depth1 > DEPTH_TOLERANCE)
  104. {
  105. VEvaluateRay(IPoint, Ray->Initial, Depth1, Ray->Direction);
  106. if (Point_In_Clip(IPoint, Object->Clip))
  107. {
  108. push_entry_i1(Depth1,IPoint,Object,Side1,Depth_Stack);
  109. Intersection_Found = TRUE;
  110. }
  111. }
  112. VEvaluateRay(IPoint, Ray->Initial, Depth2, Ray->Direction);
  113. if (Point_In_Clip(IPoint, Object->Clip))
  114. {
  115. push_entry_i1(Depth2,IPoint,Object,Side2,Depth_Stack);
  116. Intersection_Found = TRUE;
  117. }
  118. }
  119. if (Intersection_Found)
  120. {
  121. Increase_Counter(stats[Ray_Box_Tests_Succeeded]);
  122. }
  123. return (Intersection_Found);
  124. }
  125. /*****************************************************************************
  126. *
  127. * FUNCTION
  128. *
  129. * Intersect_Box
  130. *
  131. * INPUT
  132. *
  133. * OUTPUT
  134. *
  135. * RETURNS
  136. *
  137. * AUTHOR
  138. *
  139. * Alexander Enzmann
  140. *
  141. * DESCRIPTION
  142. *
  143. * -
  144. *
  145. * CHANGES
  146. *
  147. * Sep 1994 : Added code to decide which side was hit in the case
  148. * intersection points are close to each other. This removes
  149. * some ugly artefacts one could observe at the corners of
  150. * boxes due to the usage of the wrong normal vector. [DB]
  151. *
  152. ******************************************************************************/
  153. int Intersect_Box(RAY *Ray, BOX *box, DBL *Depth1, DBL *Depth2, int *Side1, int *Side2)
  154. {
  155. int smin = 0, smax = 0; /* Side hit for min/max intersection. */
  156. DBL t, tmin, tmax;
  157. VECTOR P, D;
  158. /* Transform the point into the boxes space */
  159. if (box->Trans != NULL)
  160. {
  161. MInvTransPoint(P, Ray->Initial, box->Trans);
  162. MInvTransDirection(D, Ray->Direction, box->Trans);
  163. }
  164. else
  165. {
  166. Assign_Vector(P, Ray->Initial);
  167. Assign_Vector(D, Ray->Direction);
  168. }
  169. tmin = 0.0;
  170. tmax = BOUND_HUGE;
  171. /*
  172. * Sides first.
  173. */
  174. if (D[X] < -EPSILON)
  175. {
  176. t = (box->bounds[0][X] - P[X]) / D[X];
  177. if (t < tmin) return(FALSE);
  178. if (t <= tmax)
  179. {
  180. smax = SIDE_X_0;
  181. tmax = t;
  182. }
  183. t = (box->bounds[1][X] - P[X]) / D[X];
  184. if (t >= tmin)
  185. {
  186. if (t > tmax) return(FALSE);
  187. smin = SIDE_X_1;
  188. tmin = t;
  189. }
  190. }
  191. else
  192. {
  193. if (D[X] > EPSILON)
  194. {
  195. t = (box->bounds[1][X] - P[X]) / D[X];
  196. if (t < tmin) return(FALSE);
  197. if (t <= tmax)
  198. {
  199. smax = SIDE_X_1;
  200. tmax = t;
  201. }
  202. t = (box->bounds[0][X] - P[X]) / D[X];
  203. if (t >= tmin)
  204. {
  205. if (t > tmax) return(FALSE);
  206. smin = SIDE_X_0;
  207. tmin = t;
  208. }
  209. }
  210. else
  211. {
  212. if ((P[X] < box->bounds[0][X]) || (P[X] > box->bounds[1][X]))
  213. {
  214. return(FALSE);
  215. }
  216. }
  217. }
  218. /*
  219. * Check Top/Bottom.
  220. */
  221. if (D[Y] < -EPSILON)
  222. {
  223. t = (box->bounds[0][Y] - P[Y]) / D[Y];
  224. if (t < tmin) return(FALSE);
  225. if (t <= tmax - CLOSE_TOLERANCE)
  226. {
  227. smax = SIDE_Y_0;
  228. tmax = t;
  229. }
  230. else
  231. {
  232. /*
  233. * If intersection points are close to each other find out
  234. * which side to use, i.e. is most probably hit. [DB 9/94]
  235. */
  236. if (t <= tmax + CLOSE_TOLERANCE)
  237. {
  238. if (-D[Y] > fabs(D[X])) smax = SIDE_Y_0;
  239. }
  240. }
  241. t = (box->bounds[1][Y] - P[Y]) / D[Y];
  242. if (t >= tmin + CLOSE_TOLERANCE)
  243. {
  244. if (t > tmax) return(FALSE);
  245. smin = SIDE_Y_1;
  246. tmin = t;
  247. }
  248. else
  249. {
  250. /*
  251. * If intersection points are close to each other find out
  252. * which side to use, i.e. is most probably hit. [DB 9/94]
  253. */
  254. if (t >= tmin - CLOSE_TOLERANCE)
  255. {
  256. if (-D[Y] > fabs(D[X])) smin = SIDE_Y_1;
  257. }
  258. }
  259. }
  260. else
  261. {
  262. if (D[Y] > EPSILON)
  263. {
  264. t = (box->bounds[1][Y] - P[Y]) / D[Y];
  265. if (t < tmin) return(FALSE);
  266. if (t <= tmax - CLOSE_TOLERANCE)
  267. {
  268. smax = SIDE_Y_1;
  269. tmax = t;
  270. }
  271. else
  272. {
  273. /*
  274. * If intersection points are close to each other find out
  275. * which side to use, i.e. is most probably hit. [DB 9/94]
  276. */
  277. if (t <= tmax + CLOSE_TOLERANCE)
  278. {
  279. if (D[Y] > fabs(D[X])) smax = SIDE_Y_1;
  280. }
  281. }
  282. t = (box->bounds[0][Y] - P[Y]) / D[Y];
  283. if (t >= tmin + CLOSE_TOLERANCE)
  284. {
  285. if (t > tmax) return(FALSE);
  286. smin = SIDE_Y_0;
  287. tmin = t;
  288. }
  289. else
  290. {
  291. /*
  292. * If intersection points are close to each other find out
  293. * which side to use, i.e. is most probably hit. [DB 9/94]
  294. */
  295. if (t >= tmin - CLOSE_TOLERANCE)
  296. {
  297. if (D[Y] > fabs(D[X])) smin = SIDE_Y_0;
  298. }
  299. }
  300. }
  301. else
  302. {
  303. if ((P[Y] < box->bounds[0][Y]) || (P[Y] > box->bounds[1][Y]))
  304. {
  305. return(FALSE);
  306. }
  307. }
  308. }
  309. /* Now front/back */
  310. if (D[Z] < -EPSILON)
  311. {
  312. t = (box->bounds[0][Z] - P[Z]) / D[Z];
  313. if (t < tmin) return(FALSE);
  314. if (t <= tmax - CLOSE_TOLERANCE)
  315. {
  316. smax = SIDE_Z_0;
  317. tmax = t;
  318. }
  319. else
  320. {
  321. /*
  322. * If intersection points are close to each other find out
  323. * which side to use, i.e. is most probably hit. [DB 9/94]
  324. */
  325. if (t <= tmax + CLOSE_TOLERANCE)
  326. {
  327. switch (smax)
  328. {
  329. case SIDE_X_0 :
  330. case SIDE_X_1 : if (-D[Z] > fabs(D[X])) smax = SIDE_Z_0; break;
  331. case SIDE_Y_0 :
  332. case SIDE_Y_1 : if (-D[Z] > fabs(D[Y])) smax = SIDE_Z_0; break;
  333. }
  334. }
  335. }
  336. t = (box->bounds[1][Z] - P[Z]) / D[Z];
  337. if (t >= tmin + CLOSE_TOLERANCE)
  338. {
  339. if (t > tmax) return(FALSE);
  340. smin = SIDE_Z_1;
  341. tmin = t;
  342. }
  343. else
  344. {
  345. /*
  346. * If intersection points are close to each other find out
  347. * which side to use, i.e. is most probably hit. [DB 9/94]
  348. */
  349. if (t >= tmin - CLOSE_TOLERANCE)
  350. {
  351. switch (smin)
  352. {
  353. case SIDE_X_0 :
  354. case SIDE_X_1 : if (-D[Z] > fabs(D[X])) smin = SIDE_Z_1; break;
  355. case SIDE_Y_0 :
  356. case SIDE_Y_1 : if (-D[Z] > fabs(D[Y])) smin = SIDE_Z_1; break;
  357. }
  358. }
  359. }
  360. }
  361. else
  362. {
  363. if (D[Z] > EPSILON)
  364. {
  365. t = (box->bounds[1][Z] - P[Z]) / D[Z];
  366. if (t < tmin) return(FALSE);
  367. if (t <= tmax - CLOSE_TOLERANCE)
  368. {
  369. smax = SIDE_Z_1;
  370. tmax = t;
  371. }
  372. else
  373. {
  374. /*
  375. * If intersection points are close to each other find out
  376. * which side to use, i.e. is most probably hit. [DB 9/94]
  377. */
  378. if (t <= tmax + CLOSE_TOLERANCE)
  379. {
  380. switch (smax)
  381. {
  382. case SIDE_X_0 :
  383. case SIDE_X_1 : if (D[Z] > fabs(D[X])) smax = SIDE_Z_1; break;
  384. case SIDE_Y_0 :
  385. case SIDE_Y_1 : if (D[Z] > fabs(D[Y])) smax = SIDE_Z_1; break;
  386. }
  387. }
  388. }
  389. t = (box->bounds[0][Z] - P[Z]) / D[Z];
  390. if (t >= tmin + CLOSE_TOLERANCE)
  391. {
  392. if (t > tmax) return(FALSE);
  393. smin = SIDE_Z_0;
  394. tmin = t;
  395. }
  396. else
  397. {
  398. /*
  399. * If intersection points are close to each other find out
  400. * which side to use, i.e. is most probably hit. [DB 9/94]
  401. */
  402. if (t >= tmin - CLOSE_TOLERANCE)
  403. {
  404. switch (smin)
  405. {
  406. case SIDE_X_0 :
  407. case SIDE_X_1 : if (D[Z] > fabs(D[X])) smin = SIDE_Z_0; break;
  408. case SIDE_Y_0 :
  409. case SIDE_Y_1 : if (D[Z] > fabs(D[Y])) smin = SIDE_Z_0; break;
  410. }
  411. }
  412. }
  413. }
  414. else
  415. {
  416. if ((P[Z] < box->bounds[0][Z]) || (P[Z] > box->bounds[1][Z]))
  417. {
  418. return(FALSE);
  419. }
  420. }
  421. }
  422. if (tmax < DEPTH_TOLERANCE)
  423. {
  424. return (FALSE);
  425. }
  426. *Depth1 = tmin;
  427. *Depth2 = tmax;
  428. *Side1 = smin;
  429. *Side2 = smax;
  430. return(TRUE);
  431. }
  432. /*****************************************************************************
  433. *
  434. * FUNCTION
  435. *
  436. * Inside_Box
  437. *
  438. * INPUT
  439. *
  440. * OUTPUT
  441. *
  442. * RETURNS
  443. *
  444. * AUTHOR
  445. *
  446. * Alexander Enzmann
  447. *
  448. * DESCRIPTION
  449. *
  450. * -
  451. *
  452. * CHANGES
  453. *
  454. * -
  455. *
  456. ******************************************************************************/
  457. static int Inside_Box(VECTOR IPoint, OBJECT *Object)
  458. {
  459. VECTOR New_Point;
  460. BOX *box = (BOX *) Object;
  461. /* Transform the point into box space. */
  462. if (box->Trans != NULL)
  463. {
  464. MInvTransPoint(New_Point, IPoint, box->Trans);
  465. }
  466. else
  467. {
  468. Assign_Vector(New_Point,IPoint);
  469. }
  470. /* Test to see if we are outside the box. */
  471. if ((New_Point[X] < box->bounds[0][X]) || (New_Point[X] > box->bounds[1][X]))
  472. {
  473. return (Test_Flag(box, INVERTED_FLAG));
  474. }
  475. if ((New_Point[Y] < box->bounds[0][Y]) || (New_Point[Y] > box->bounds[1][Y]))
  476. {
  477. return (Test_Flag(box, INVERTED_FLAG));
  478. }
  479. if ((New_Point[Z] < box->bounds[0][Z]) || (New_Point[Z] > box->bounds[1][Z]))
  480. {
  481. return (Test_Flag(box, INVERTED_FLAG));
  482. }
  483. /* Inside the box. */
  484. return (!Test_Flag(box, INVERTED_FLAG));
  485. }
  486. /*****************************************************************************
  487. *
  488. * FUNCTION
  489. *
  490. * Box_Normal
  491. *
  492. * INPUT
  493. *
  494. * OUTPUT
  495. *
  496. * RETURNS
  497. *
  498. * AUTHOR
  499. *
  500. * Alexander Enzmann
  501. *
  502. * DESCRIPTION
  503. *
  504. * -
  505. *
  506. * CHANGES
  507. *
  508. * -
  509. *
  510. ******************************************************************************/
  511. static void Box_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  512. {
  513. switch (Inter->i1)
  514. {
  515. case SIDE_X_0: Make_Vector(Result, -1.0, 0.0, 0.0); break;
  516. case SIDE_X_1: Make_Vector(Result, 1.0, 0.0, 0.0); break;
  517. case SIDE_Y_0: Make_Vector(Result, 0.0, -1.0, 0.0); break;
  518. case SIDE_Y_1: Make_Vector(Result, 0.0, 1.0, 0.0); break;
  519. case SIDE_Z_0: Make_Vector(Result, 0.0, 0.0, -1.0); break;
  520. case SIDE_Z_1: Make_Vector(Result, 0.0, 0.0, 1.0); break;
  521. default: Error("Unknown box side in Box_Normal().\n");
  522. }
  523. /* Transform the point into the boxes space. */
  524. if (((BOX *)Object)->Trans != NULL)
  525. {
  526. MTransNormal(Result, Result, ((BOX *)Object)->Trans);
  527. VNormalize(Result, Result);
  528. }
  529. }
  530. /*****************************************************************************
  531. *
  532. * FUNCTION
  533. *
  534. * Translate_Box
  535. *
  536. * INPUT
  537. *
  538. * OUTPUT
  539. *
  540. * RETURNS
  541. *
  542. * AUTHOR
  543. *
  544. * Alexander Enzmann
  545. *
  546. * DESCRIPTION
  547. *
  548. * -
  549. *
  550. * CHANGES
  551. *
  552. * -
  553. *
  554. ******************************************************************************/
  555. static void Translate_Box(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  556. {
  557. if (((BOX *)Object)->Trans == NULL)
  558. {
  559. VAddEq(((BOX *)Object)->bounds[0], Vector);
  560. VAddEq(((BOX *)Object)->bounds[1], Vector);
  561. Compute_Box_BBox((BOX *)Object);
  562. }
  563. else
  564. {
  565. Transform_Box(Object, Trans);
  566. }
  567. }
  568. /*****************************************************************************
  569. *
  570. * FUNCTION
  571. *
  572. * Rotate_Box
  573. *
  574. * INPUT
  575. *
  576. * OUTPUT
  577. *
  578. * RETURNS
  579. *
  580. * AUTHOR
  581. *
  582. * Alexander Enzmann
  583. *
  584. * DESCRIPTION
  585. *
  586. * -
  587. *
  588. * CHANGES
  589. *
  590. * -
  591. *
  592. ******************************************************************************/
  593. static void Rotate_Box(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  594. {
  595. Transform_Box(Object, Trans);
  596. }
  597. /*****************************************************************************
  598. *
  599. * FUNCTION
  600. *
  601. * Scale_Box
  602. *
  603. * INPUT
  604. *
  605. * OUTPUT
  606. *
  607. * RETURNS
  608. *
  609. * AUTHOR
  610. *
  611. * Alexander Enzmann
  612. *
  613. * DESCRIPTION
  614. *
  615. * -
  616. *
  617. * CHANGES
  618. *
  619. * -
  620. *
  621. ******************************************************************************/
  622. static void Scale_Box(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  623. {
  624. DBL temp;
  625. BOX *Box = (BOX *)Object;
  626. if (((BOX *)Object)->Trans == NULL)
  627. {
  628. VEvaluateEq(Box->bounds[0], Vector);
  629. VEvaluateEq(Box->bounds[1], Vector);
  630. if (Box->bounds[0][X] > Box->bounds[1][X])
  631. {
  632. temp = Box->bounds[0][X];
  633. Box->bounds[0][X] = Box->bounds[1][X];
  634. Box->bounds[1][X] = temp;
  635. }
  636. if (Box->bounds[0][Y] > Box->bounds[1][Y])
  637. {
  638. temp = Box->bounds[0][Y];
  639. Box->bounds[0][Y] = Box->bounds[1][Y];
  640. Box->bounds[1][Y] = temp;
  641. }
  642. if (Box->bounds[0][Z] > Box->bounds[1][Z])
  643. {
  644. temp = Box->bounds[0][Z];
  645. Box->bounds[0][Z] = Box->bounds[1][Z];
  646. Box->bounds[1][Z] = temp;
  647. }
  648. Compute_Box_BBox((BOX *)Object);
  649. }
  650. else
  651. {
  652. Transform_Box(Object, Trans);
  653. }
  654. }
  655. /*****************************************************************************
  656. *
  657. * FUNCTION
  658. *
  659. * Invert_Box
  660. *
  661. * INPUT
  662. *
  663. * OUTPUT
  664. *
  665. * RETURNS
  666. *
  667. * AUTHOR
  668. *
  669. * Alexander Enzmann
  670. *
  671. * DESCRIPTION
  672. *
  673. * -
  674. *
  675. * CHANGES
  676. *
  677. * -
  678. *
  679. ******************************************************************************/
  680. static void Invert_Box(OBJECT *Object)
  681. {
  682. Invert_Flag(Object, INVERTED_FLAG);
  683. }
  684. /*****************************************************************************
  685. *
  686. * FUNCTION
  687. *
  688. * Transform_Box
  689. *
  690. * INPUT
  691. *
  692. * OUTPUT
  693. *
  694. * RETURNS
  695. *
  696. * AUTHOR
  697. *
  698. * Alexander Enzmann
  699. *
  700. * DESCRIPTION
  701. *
  702. * -
  703. *
  704. * CHANGES
  705. *
  706. * -
  707. *
  708. ******************************************************************************/
  709. static void Transform_Box(OBJECT *Object, TRANSFORM *Trans)
  710. {
  711. BOX *box = (BOX *)Object;
  712. if (box->Trans == NULL)
  713. {
  714. box->Trans = Create_Transform();
  715. }
  716. Compose_Transforms(box->Trans, Trans);
  717. Compute_Box_BBox(box);
  718. }
  719. /*****************************************************************************
  720. *
  721. * FUNCTION
  722. *
  723. * Create_Box
  724. *
  725. * INPUT
  726. *
  727. * OUTPUT
  728. *
  729. * RETURNS
  730. *
  731. * AUTHOR
  732. *
  733. * Alexander Enzmann
  734. *
  735. * DESCRIPTION
  736. *
  737. * -
  738. *
  739. * CHANGES
  740. *
  741. * -
  742. *
  743. ******************************************************************************/
  744. BOX *Create_Box()
  745. {
  746. BOX *New;
  747. New = (BOX *)POV_MALLOC(sizeof(BOX), "box");
  748. INIT_OBJECT_FIELDS(New, BOX_OBJECT, &Box_Methods)
  749. Make_Vector(New->bounds[0], -1.0, -1.0, -1.0);
  750. Make_Vector(New->bounds[1], 1.0, 1.0, 1.0);
  751. Make_BBox(New->BBox, -1.0, -1.0, -1.0, 2.0, 2.0, 2.0);
  752. New->Trans = NULL;
  753. return (New);
  754. }
  755. /*****************************************************************************
  756. *
  757. * FUNCTION
  758. *
  759. * Copy_Box
  760. *
  761. * INPUT
  762. *
  763. * OUTPUT
  764. *
  765. * RETURNS
  766. *
  767. * AUTHOR
  768. *
  769. * Alexander Enzmann
  770. *
  771. * DESCRIPTION
  772. *
  773. * -
  774. *
  775. * CHANGES
  776. *
  777. * -
  778. *
  779. ******************************************************************************/
  780. BOX *Copy_Box(OBJECT *Object)
  781. {
  782. BOX *New;
  783. New = Create_Box();
  784. /* Copy box. */
  785. *New = *((BOX *)Object);
  786. New->Trans = Copy_Transform(((BOX *)Object)->Trans);
  787. return (New);
  788. }
  789. /*****************************************************************************
  790. *
  791. * FUNCTION
  792. *
  793. * Destroy_Box
  794. *
  795. * INPUT
  796. *
  797. * OUTPUT
  798. *
  799. * RETURNS
  800. *
  801. * AUTHOR
  802. *
  803. * Alexander Enzmann
  804. *
  805. * DESCRIPTION
  806. *
  807. * -
  808. *
  809. * CHANGES
  810. *
  811. * -
  812. *
  813. ******************************************************************************/
  814. void Destroy_Box(OBJECT *Object)
  815. {
  816. Destroy_Transform(((BOX *)Object)->Trans);
  817. POV_FREE (Object);
  818. }
  819. /*****************************************************************************
  820. *
  821. * FUNCTION
  822. *
  823. * Compute_Box_BBox
  824. *
  825. * INPUT
  826. *
  827. * Box - Box
  828. *
  829. * OUTPUT
  830. *
  831. * Box
  832. *
  833. * RETURNS
  834. *
  835. * AUTHOR
  836. *
  837. * Dieter Bayer
  838. *
  839. * DESCRIPTION
  840. *
  841. * Calculate the bounding box of a box.
  842. *
  843. * CHANGES
  844. *
  845. * Aug 1994 : Creation.
  846. *
  847. ******************************************************************************/
  848. void Compute_Box_BBox(BOX *Box)
  849. {
  850. Assign_BBox_Vect(Box->BBox.Lower_Left, Box->bounds[0]);
  851. VSub(Box->BBox.Lengths, Box->bounds[1], Box->bounds[0]);
  852. if (Box->Trans != NULL)
  853. {
  854. Recompute_BBox(&Box->BBox, Box->Trans);
  855. }
  856. }