OBJECTS.C 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. /****************************************************************************
  2. * objects.c
  3. *
  4. * This module implements the methods for objects and composite objects.
  5. *
  6. * from Persistence of Vision(tm) Ray Tracer
  7. * Copyright 1996,1999 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. * NOTICE: This source code file is provided so that users may experiment
  10. * with enhancements to POV-Ray and to port the software to platforms other
  11. * than those supported by the POV-Ray Team. There are strict rules under
  12. * which you are permitted to use this file. The rules are in the file
  13. * named POVLEGAL.DOC which should be distributed with this file.
  14. * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. * Team Coordinator by email to team-coord@povray.org or visit us on the web at
  16. * http://www.povray.org. The latest version of POV-Ray may be found at this site.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23. #include "frame.h"
  24. #include "povray.h"
  25. #include "vector.h"
  26. #include "povproto.h"
  27. #include "interior.h"
  28. #include "objects.h"
  29. #include "texture.h"
  30. /*****************************************************************************
  31. * Local preprocessor defines
  32. ******************************************************************************/
  33. /*****************************************************************************
  34. * Local typedefs
  35. ******************************************************************************/
  36. /*****************************************************************************
  37. * Local variables
  38. ******************************************************************************/
  39. unsigned int Number_of_istacks;
  40. unsigned int Max_Intersections;
  41. ISTACK *free_istack;
  42. /*****************************************************************************
  43. * Static functions
  44. ******************************************************************************/
  45. static OBJECT *Copy_Bound_Clip (OBJECT *Old);
  46. static void create_istack (void);
  47. /*****************************************************************************
  48. *
  49. * FUNCTION
  50. *
  51. * Intersection
  52. *
  53. * INPUT
  54. *
  55. * OUTPUT
  56. *
  57. * RETURNS
  58. *
  59. * AUTHOR
  60. *
  61. * POV-Ray Team
  62. *
  63. * DESCRIPTION
  64. *
  65. * -
  66. *
  67. * CHANGES
  68. *
  69. * -
  70. *
  71. ******************************************************************************/
  72. int Intersection (INTERSECTION *Ray_Intersection, OBJECT *Object, RAY *Ray)
  73. {
  74. ISTACK *Depth_Stack;
  75. INTERSECTION *Local;
  76. DBL Closest = HUGE_VAL;
  77. if (Object == NULL)
  78. {
  79. return (FALSE);
  80. }
  81. if (!Ray_In_Bound (Ray,Object->Bound))
  82. {
  83. return (FALSE);
  84. }
  85. Depth_Stack = open_istack ();
  86. if (All_Intersections (Object, Ray, Depth_Stack))
  87. {
  88. while ((Local = pop_entry(Depth_Stack)) != NULL)
  89. {
  90. if (Local->Depth < Closest)
  91. {
  92. *Ray_Intersection = *Local;
  93. Closest = Local->Depth;
  94. }
  95. }
  96. close_istack (Depth_Stack);
  97. return (TRUE);
  98. }
  99. else
  100. {
  101. close_istack (Depth_Stack);
  102. return (FALSE);
  103. }
  104. }
  105. /*****************************************************************************
  106. *
  107. * FUNCTION
  108. *
  109. * Inside_Object
  110. *
  111. * INPUT
  112. *
  113. * OUTPUT
  114. *
  115. * RETURNS
  116. *
  117. * AUTHOR
  118. *
  119. * POV-Ray Team
  120. *
  121. * DESCRIPTION
  122. *
  123. * -
  124. *
  125. * CHANGES
  126. *
  127. * -
  128. *
  129. ******************************************************************************/
  130. int Inside_Object (VECTOR IPoint, OBJECT *Object)
  131. {
  132. OBJECT *Sib;
  133. for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  134. {
  135. if (!Inside_Object(IPoint, Sib))
  136. {
  137. return(FALSE);
  138. }
  139. }
  140. return (Inside(IPoint,Object));
  141. }
  142. /*****************************************************************************
  143. *
  144. * FUNCTION
  145. *
  146. * Ray_In_Bound
  147. *
  148. * INPUT
  149. *
  150. * OUTPUT
  151. *
  152. * RETURNS
  153. *
  154. * AUTHOR
  155. *
  156. * POV-Ray Team
  157. *
  158. * DESCRIPTION
  159. *
  160. * -
  161. *
  162. * CHANGES
  163. *
  164. * -
  165. *
  166. ******************************************************************************/
  167. int Ray_In_Bound (RAY *Ray, OBJECT *Bounding_Object)
  168. {
  169. OBJECT *Bound;
  170. INTERSECTION Local;
  171. for (Bound = Bounding_Object; Bound != NULL; Bound = Bound->Sibling)
  172. {
  173. Increase_Counter(stats[Bounding_Region_Tests]);
  174. if (!Intersection (&Local, Bound, Ray))
  175. {
  176. if (!Inside_Object(Ray->Initial, Bound))
  177. {
  178. return (FALSE);
  179. }
  180. }
  181. Increase_Counter(stats[Bounding_Region_Tests_Succeeded]);
  182. }
  183. return (TRUE);
  184. }
  185. /*****************************************************************************
  186. *
  187. * FUNCTION
  188. *
  189. * Point_In_Clip
  190. *
  191. * INPUT
  192. *
  193. * OUTPUT
  194. *
  195. * RETURNS
  196. *
  197. * AUTHOR
  198. *
  199. * POV-Ray Team
  200. *
  201. * DESCRIPTION
  202. *
  203. * -
  204. *
  205. * CHANGES
  206. *
  207. * -
  208. *
  209. ******************************************************************************/
  210. int Point_In_Clip (VECTOR IPoint, OBJECT *Clip)
  211. {
  212. OBJECT *Local_Clip;
  213. for (Local_Clip = Clip; Local_Clip != NULL; Local_Clip = Local_Clip->Sibling)
  214. {
  215. Increase_Counter(stats[Clipping_Region_Tests]);
  216. if (!Inside_Object(IPoint, Local_Clip))
  217. {
  218. return (FALSE);
  219. }
  220. Increase_Counter(stats[Clipping_Region_Tests_Succeeded]);
  221. }
  222. return (TRUE);
  223. }
  224. /*****************************************************************************
  225. *
  226. * FUNCTION
  227. *
  228. * Translate_Object
  229. *
  230. * INPUT
  231. *
  232. * OUTPUT
  233. *
  234. * RETURNS
  235. *
  236. * AUTHOR
  237. *
  238. * POV-Ray Team
  239. *
  240. * DESCRIPTION
  241. *
  242. * -
  243. *
  244. * CHANGES
  245. *
  246. * -
  247. *
  248. ******************************************************************************/
  249. void Translate_Object (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  250. {
  251. OBJECT *Sib;
  252. if (Object == NULL)
  253. {
  254. return;
  255. }
  256. for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  257. {
  258. Translate_Object(Sib, Vector, Trans);
  259. }
  260. if (Object->Clip != Object->Bound)
  261. {
  262. for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  263. {
  264. Translate_Object(Sib, Vector, Trans);
  265. }
  266. }
  267. Transform_Textures(Object->Texture, Trans);
  268. Transform_Interior(Object->Interior, Trans);
  269. Translate(Object, Vector, Trans);
  270. }
  271. /*****************************************************************************
  272. *
  273. * FUNCTION
  274. *
  275. * Rotate_Object
  276. *
  277. * INPUT
  278. *
  279. * OUTPUT
  280. *
  281. * RETURNS
  282. *
  283. * AUTHOR
  284. *
  285. * POV-Ray Team
  286. *
  287. * DESCRIPTION
  288. *
  289. * -
  290. *
  291. * CHANGES
  292. *
  293. * -
  294. *
  295. ******************************************************************************/
  296. void Rotate_Object (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  297. {
  298. OBJECT *Sib;
  299. if (Object == NULL)
  300. {
  301. return;
  302. }
  303. for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  304. {
  305. Rotate_Object(Sib, Vector, Trans);
  306. }
  307. if (Object->Clip != Object->Bound)
  308. {
  309. for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  310. {
  311. Rotate_Object(Sib, Vector, Trans);
  312. }
  313. }
  314. Transform_Textures(Object->Texture, Trans);
  315. Transform_Interior(Object->Interior, Trans);
  316. Rotate(Object, Vector, Trans);
  317. }
  318. /*****************************************************************************
  319. *
  320. * FUNCTION
  321. *
  322. * Scale_Object
  323. *
  324. * INPUT
  325. *
  326. * OUTPUT
  327. *
  328. * RETURNS
  329. *
  330. * AUTHOR
  331. *
  332. * POV-Ray Team
  333. *
  334. * DESCRIPTION
  335. *
  336. * -
  337. *
  338. * CHANGES
  339. *
  340. * -
  341. *
  342. ******************************************************************************/
  343. void Scale_Object (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  344. {
  345. OBJECT *Sib;
  346. if (Object == NULL)
  347. {
  348. return;
  349. }
  350. for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  351. {
  352. Scale_Object(Sib, Vector, Trans);
  353. }
  354. if (Object->Clip != Object->Bound)
  355. {
  356. for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  357. {
  358. Scale_Object(Sib, Vector, Trans);
  359. }
  360. }
  361. Transform_Textures(Object->Texture, Trans);
  362. Transform_Interior(Object->Interior, Trans);
  363. Scale(Object, Vector, Trans);
  364. }
  365. /*****************************************************************************
  366. *
  367. * FUNCTION
  368. *
  369. * Transform_Object
  370. *
  371. * INPUT
  372. *
  373. * OUTPUT
  374. *
  375. * RETURNS
  376. *
  377. * AUTHOR
  378. *
  379. * POV-Ray Team
  380. *
  381. * DESCRIPTION
  382. *
  383. * -
  384. *
  385. * CHANGES
  386. *
  387. * -
  388. *
  389. ******************************************************************************/
  390. void Transform_Object (OBJECT *Object, TRANSFORM *Trans)
  391. {
  392. OBJECT *Sib;
  393. if (Object == NULL)
  394. {
  395. return;
  396. }
  397. for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
  398. {
  399. Transform_Object(Sib, Trans);
  400. }
  401. if (Object->Clip != Object->Bound)
  402. {
  403. for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
  404. {
  405. Transform_Object(Sib, Trans);
  406. }
  407. }
  408. Transform_Textures(Object->Texture, Trans);
  409. Transform_Interior(Object->Interior, Trans);
  410. Transform(Object,Trans);
  411. }
  412. /*****************************************************************************
  413. *
  414. * FUNCTION
  415. *
  416. * Invert_Object
  417. *
  418. * INPUT
  419. *
  420. * OUTPUT
  421. *
  422. * RETURNS
  423. *
  424. * AUTHOR
  425. *
  426. * POV-Ray Team
  427. *
  428. * DESCRIPTION
  429. *
  430. * -
  431. *
  432. * CHANGES
  433. *
  434. * -
  435. *
  436. ******************************************************************************/
  437. void Invert_Object (OBJECT *Object)
  438. {
  439. if (Object == NULL)
  440. {
  441. return;
  442. }
  443. Invert (Object);
  444. }
  445. /*****************************************************************************
  446. *
  447. * FUNCTION
  448. *
  449. * Copy_Bound_Clip
  450. *
  451. * INPUT
  452. *
  453. * OUTPUT
  454. *
  455. * RETURNS
  456. *
  457. * AUTHOR
  458. *
  459. * POV-Ray Team
  460. *
  461. * DESCRIPTION
  462. *
  463. * -
  464. *
  465. * CHANGES
  466. *
  467. * -
  468. *
  469. ******************************************************************************/
  470. static OBJECT *Copy_Bound_Clip (OBJECT *Old)
  471. {
  472. OBJECT *Current, *New, *Prev, *First;
  473. First = Prev = NULL;
  474. for (Current = Old; Current != NULL; Current = Current->Sibling)
  475. {
  476. New = Copy_Object (Current);
  477. if (First == NULL)
  478. {
  479. First = New;
  480. }
  481. if (Prev != NULL)
  482. {
  483. Prev->Sibling = New;
  484. }
  485. Prev = New;
  486. }
  487. return (First);
  488. }
  489. /*****************************************************************************
  490. *
  491. * FUNCTION
  492. *
  493. * Copy_Object
  494. *
  495. * INPUT
  496. *
  497. * OUTPUT
  498. *
  499. * RETURNS
  500. *
  501. * AUTHOR
  502. *
  503. * POV-Ray Team
  504. *
  505. * DESCRIPTION
  506. *
  507. * -
  508. *
  509. * CHANGES
  510. *
  511. * -
  512. *
  513. ******************************************************************************/
  514. OBJECT *Copy_Object (OBJECT *Old)
  515. {
  516. OBJECT *New;
  517. if (Old == NULL)
  518. {
  519. return (NULL);
  520. }
  521. New = (OBJECT *)Copy(Old);
  522. COOPERATE_0
  523. /*
  524. * The following copying of OBJECT_FIELDS is redundant if Copy
  525. * did *New = *Old but we cannot assume it did. It is safe for
  526. * Copy to do *New = *Old but it should not otherwise
  527. * touch OBJECT_FIELDS.
  528. */
  529. New->Methods = Old->Methods;
  530. New->Type = Old->Type;
  531. New->Sibling = Old->Sibling;
  532. New->Texture = Old->Texture;
  533. New->Bound = Old->Bound;
  534. New->Clip = Old->Clip;
  535. New->BBox = Old->BBox;
  536. New->Flags = Old->Flags;
  537. New->Sibling = NULL; /* Important */
  538. New->Texture = Copy_Textures (Old->Texture);
  539. New->Bound = Copy_Bound_Clip (Old->Bound);
  540. New->Interior = Copy_Interior(Old->Interior);
  541. if (Old->Bound != Old->Clip)
  542. {
  543. New->Clip = Copy_Bound_Clip (Old->Clip);
  544. }
  545. else
  546. {
  547. New->Clip = New->Bound;
  548. }
  549. return (New);
  550. }
  551. /*****************************************************************************
  552. *
  553. * FUNCTION
  554. *
  555. * Destroy_Object
  556. *
  557. * INPUT
  558. *
  559. * OUTPUT
  560. *
  561. * RETURNS
  562. *
  563. * AUTHOR
  564. *
  565. * POV-Ray Team
  566. *
  567. * DESCRIPTION
  568. *
  569. * -
  570. *
  571. * CHANGES
  572. *
  573. * -
  574. *
  575. ******************************************************************************/
  576. void Destroy_Object (OBJECT *Object)
  577. {
  578. OBJECT *Sib;
  579. while (Object != NULL)
  580. {
  581. Destroy_Textures(Object->Texture);
  582. Destroy_Object(Object->Bound);
  583. Destroy_Interior((INTERIOR *)Object->Interior);
  584. if (Object->Bound != Object->Clip)
  585. {
  586. Destroy_Object(Object->Clip);
  587. }
  588. Sib = Object->Sibling;
  589. Destroy(Object);
  590. Object = Sib;
  591. }
  592. }
  593. /*****************************************************************************
  594. *
  595. * FUNCTION
  596. *
  597. * create_istack
  598. *
  599. * INPUT
  600. *
  601. * OUTPUT
  602. *
  603. * RETURNS
  604. *
  605. * AUTHOR
  606. *
  607. * POV-Ray Team
  608. *
  609. * DESCRIPTION
  610. *
  611. * -
  612. *
  613. * CHANGES
  614. *
  615. * -
  616. *
  617. ******************************************************************************/
  618. static void create_istack()
  619. {
  620. ISTACK *New;
  621. New = (ISTACK *)POV_MALLOC(sizeof (ISTACK), "istack");
  622. New->next = free_istack;
  623. free_istack = New;
  624. New->istack = (INTERSECTION *)POV_MALLOC(Max_Intersections * sizeof (INTERSECTION), "istack entries");
  625. Number_of_istacks++;
  626. }
  627. /*****************************************************************************
  628. *
  629. * FUNCTION
  630. *
  631. * Destroy_IStacks
  632. *
  633. * INPUT
  634. *
  635. * OUTPUT
  636. *
  637. * RETURNS
  638. *
  639. * AUTHOR
  640. *
  641. * POV-Ray Team
  642. *
  643. * DESCRIPTION
  644. *
  645. * -
  646. *
  647. * CHANGES
  648. *
  649. * -
  650. *
  651. ******************************************************************************/
  652. void Destroy_IStacks()
  653. {
  654. ISTACK *istk, *temp;
  655. istk = free_istack;
  656. while (istk != NULL)
  657. {
  658. temp = istk;
  659. istk = istk->next;
  660. POV_FREE (temp->istack);
  661. POV_FREE (temp);
  662. }
  663. free_istack = NULL;
  664. }
  665. /*****************************************************************************
  666. *
  667. * FUNCTION
  668. *
  669. * open_sstack
  670. *
  671. * INPUT
  672. *
  673. * OUTPUT
  674. *
  675. * RETURNS
  676. *
  677. * AUTHOR
  678. *
  679. * POV-Ray Team
  680. *
  681. * DESCRIPTION
  682. *
  683. * -
  684. *
  685. * CHANGES
  686. *
  687. * -
  688. *
  689. ******************************************************************************/
  690. ISTACK *open_istack()
  691. {
  692. ISTACK *istk;
  693. if (free_istack == NULL)
  694. {
  695. create_istack ();
  696. }
  697. istk = free_istack;
  698. free_istack = istk->next;
  699. istk->top_entry = 0;
  700. return (istk);
  701. }
  702. /*****************************************************************************
  703. *
  704. * FUNCTION
  705. *
  706. * close_istack
  707. *
  708. * INPUT
  709. *
  710. * OUTPUT
  711. *
  712. * RETURNS
  713. *
  714. * AUTHOR
  715. *
  716. * POV-Ray Team
  717. *
  718. * DESCRIPTION
  719. *
  720. * -
  721. *
  722. * CHANGES
  723. *
  724. * -
  725. *
  726. ******************************************************************************/
  727. void close_istack (ISTACK *istk)
  728. {
  729. istk->next = free_istack;
  730. free_istack = istk;
  731. }
  732. /*****************************************************************************
  733. *
  734. * FUNCTION
  735. *
  736. * incstack
  737. *
  738. * INPUT
  739. *
  740. * OUTPUT
  741. *
  742. * RETURNS
  743. *
  744. * AUTHOR
  745. *
  746. * POV-Ray Team
  747. *
  748. * DESCRIPTION
  749. *
  750. * -
  751. *
  752. * CHANGES
  753. *
  754. * -
  755. *
  756. ******************************************************************************/
  757. void incstack(ISTACK *istk)
  758. {
  759. if (++istk->top_entry >= Max_Intersections)
  760. {
  761. istk->top_entry--;
  762. Increase_Counter(stats[Istack_overflows]);
  763. }
  764. }