PLANES.C 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. /****************************************************************************
  2. * planes.c
  3. *
  4. * This module implements functions that manipulate planes.
  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 "matrices.h"
  28. #include "objects.h"
  29. #include "planes.h"
  30. /*****************************************************************************
  31. * Local preprocessor defines
  32. ******************************************************************************/
  33. #define DEPTH_TOLERANCE 1.0e-6
  34. /*****************************************************************************
  35. * Static functions
  36. ******************************************************************************/
  37. static int Intersect_Plane (RAY *Ray, PLANE *Plane, DBL *Depth);
  38. static int All_Plane_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  39. static int Inside_Plane (VECTOR point, OBJECT *Object);
  40. static void Plane_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  41. static PLANE *Copy_Plane (OBJECT *Object);
  42. static void Translate_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  43. static void Rotate_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  44. static void Scale_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  45. static void Transform_Plane (OBJECT *Object, TRANSFORM *Trans);
  46. static void Invert_Plane (OBJECT *Object);
  47. static void Destroy_Plane (OBJECT *Object);
  48. /*****************************************************************************
  49. * Local variables
  50. ******************************************************************************/
  51. METHODS Plane_Methods =
  52. {
  53. All_Plane_Intersections,
  54. Inside_Plane, Plane_Normal,
  55. (COPY_METHOD)Copy_Plane,
  56. Translate_Plane, Rotate_Plane,
  57. Scale_Plane, Transform_Plane, Invert_Plane, Destroy_Plane
  58. };
  59. /*****************************************************************************
  60. *
  61. * FUNCTION
  62. *
  63. * All_Plane_Intersections
  64. *
  65. * INPUT
  66. *
  67. * OUTPUT
  68. *
  69. * RETURNS
  70. *
  71. * AUTHOR
  72. *
  73. * POV-Ray Team
  74. *
  75. * DESCRIPTION
  76. *
  77. * -
  78. *
  79. * CHANGES
  80. *
  81. * -
  82. *
  83. ******************************************************************************/
  84. static int All_Plane_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  85. {
  86. DBL Depth;
  87. VECTOR IPoint;
  88. if (Intersect_Plane(Ray, (PLANE *)Object, &Depth))
  89. {
  90. VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
  91. if (Point_In_Clip(IPoint, Object->Clip))
  92. {
  93. push_entry(Depth,IPoint,Object,Depth_Stack);
  94. return(TRUE);
  95. }
  96. }
  97. return(FALSE);
  98. }
  99. /*****************************************************************************
  100. *
  101. * FUNCTION
  102. *
  103. * Intersect_Plane
  104. *
  105. * INPUT
  106. *
  107. * OUTPUT
  108. *
  109. * RETURNS
  110. *
  111. * AUTHOR
  112. *
  113. * POV-Ray Team
  114. *
  115. * DESCRIPTION
  116. *
  117. * -
  118. *
  119. * CHANGES
  120. *
  121. * -
  122. *
  123. ******************************************************************************/
  124. static int Intersect_Plane (RAY *Ray, PLANE *Plane, DBL *Depth)
  125. {
  126. DBL NormalDotOrigin, NormalDotDirection;
  127. VECTOR P, D;
  128. Increase_Counter(stats[Ray_Plane_Tests]);
  129. if (Plane->Trans == NULL)
  130. {
  131. VDot(NormalDotDirection, Plane->Normal_Vector, Ray->Direction);
  132. if (fabs(NormalDotDirection) < EPSILON)
  133. {
  134. return(FALSE);
  135. }
  136. VDot(NormalDotOrigin, Plane->Normal_Vector, Ray->Initial);
  137. }
  138. else
  139. {
  140. MInvTransPoint(P, Ray->Initial, Plane->Trans);
  141. MInvTransDirection(D, Ray->Direction, Plane->Trans);
  142. VDot(NormalDotDirection, Plane->Normal_Vector, D);
  143. if (fabs(NormalDotDirection) < EPSILON)
  144. {
  145. return(FALSE);
  146. }
  147. VDot(NormalDotOrigin, Plane->Normal_Vector, P);
  148. }
  149. *Depth = -(NormalDotOrigin + Plane->Distance) / NormalDotDirection;
  150. if ((*Depth >= DEPTH_TOLERANCE) && (*Depth <= Max_Distance))
  151. {
  152. Increase_Counter(stats[Ray_Plane_Tests_Succeeded]);
  153. return (TRUE);
  154. }
  155. else
  156. {
  157. return (FALSE);
  158. }
  159. }
  160. /*****************************************************************************
  161. *
  162. * FUNCTION
  163. *
  164. * Inside_Plane
  165. *
  166. * INPUT
  167. *
  168. * OUTPUT
  169. *
  170. * RETURNS
  171. *
  172. * AUTHOR
  173. *
  174. * POV-Ray Team
  175. *
  176. * DESCRIPTION
  177. *
  178. * -
  179. *
  180. * CHANGES
  181. *
  182. * -
  183. *
  184. ******************************************************************************/
  185. static int Inside_Plane (VECTOR IPoint, OBJECT *Object)
  186. {
  187. DBL Temp;
  188. VECTOR P;
  189. if (((PLANE *)Object)->Trans == NULL)
  190. {
  191. VDot (Temp, IPoint, ((PLANE *)Object)->Normal_Vector);
  192. }
  193. else
  194. {
  195. MInvTransPoint(P, IPoint, ((PLANE *)Object)->Trans);
  196. VDot (Temp, P, ((PLANE *)Object)->Normal_Vector);
  197. }
  198. return((Temp + ((PLANE *)Object)->Distance) < EPSILON);
  199. }
  200. /*****************************************************************************
  201. *
  202. * FUNCTION
  203. *
  204. * Plane_Normal
  205. *
  206. * INPUT
  207. *
  208. * OUTPUT
  209. *
  210. * RETURNS
  211. *
  212. * AUTHOR
  213. *
  214. * POV-Ray Team
  215. *
  216. * DESCRIPTION
  217. *
  218. * -
  219. *
  220. * CHANGES
  221. *
  222. * -
  223. *
  224. ******************************************************************************/
  225. static void Plane_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  226. {
  227. Assign_Vector(Result,((PLANE *)Object)->Normal_Vector);
  228. if (((PLANE *)Object)->Trans != NULL)
  229. {
  230. MTransNormal(Result, Result, ((PLANE *)Object)->Trans);
  231. VNormalize(Result, Result);
  232. }
  233. }
  234. /*****************************************************************************
  235. *
  236. * FUNCTION
  237. *
  238. * Translate_Plane
  239. *
  240. * INPUT
  241. *
  242. * OUTPUT
  243. *
  244. * RETURNS
  245. *
  246. * AUTHOR
  247. *
  248. * POV-Ray Team
  249. *
  250. * DESCRIPTION
  251. *
  252. * -
  253. *
  254. * CHANGES
  255. *
  256. * -
  257. *
  258. ******************************************************************************/
  259. static void Translate_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  260. {
  261. VECTOR Translation;
  262. PLANE *Plane = (PLANE *)Object;
  263. if (Plane->Trans == NULL)
  264. {
  265. VEvaluate (Translation, ((PLANE *)Object)->Normal_Vector, Vector);
  266. ((PLANE *)Object)->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  267. Compute_Plane_BBox((PLANE *)Object);
  268. }
  269. else
  270. {
  271. Transform_Plane(Object, Trans);
  272. }
  273. }
  274. /*****************************************************************************
  275. *
  276. * FUNCTION
  277. *
  278. * Rotate_Plane
  279. *
  280. * INPUT
  281. *
  282. * OUTPUT
  283. *
  284. * RETURNS
  285. *
  286. * AUTHOR
  287. *
  288. * POV-Ray Team
  289. *
  290. * DESCRIPTION
  291. *
  292. * -
  293. *
  294. * CHANGES
  295. *
  296. * -
  297. *
  298. ******************************************************************************/
  299. static void Rotate_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  300. {
  301. if (((PLANE *)Object)->Trans == NULL)
  302. {
  303. MTransDirection(((PLANE *)Object)->Normal_Vector, ((PLANE *)Object)->Normal_Vector, Trans);
  304. Compute_Plane_BBox(((PLANE *)Object));
  305. }
  306. else
  307. {
  308. Transform_Plane (Object, Trans);
  309. }
  310. }
  311. /*****************************************************************************
  312. *
  313. * FUNCTION
  314. *
  315. * Scale_Plane
  316. *
  317. * INPUT
  318. *
  319. * OUTPUT
  320. *
  321. * RETURNS
  322. *
  323. * AUTHOR
  324. *
  325. * POV-Ray Team
  326. *
  327. * DESCRIPTION
  328. *
  329. * -
  330. *
  331. * CHANGES
  332. *
  333. * -
  334. *
  335. ******************************************************************************/
  336. static void Scale_Plane (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  337. {
  338. DBL Length;
  339. PLANE *Plane = (PLANE *) Object;
  340. if (Plane->Trans == NULL)
  341. {
  342. VDivEq(Plane->Normal_Vector, Vector);
  343. VLength(Length, ((PLANE *)Object)->Normal_Vector);
  344. VInverseScaleEq (((PLANE *)Object)->Normal_Vector, Length);
  345. ((PLANE *)Object)->Distance /= Length;
  346. Compute_Plane_BBox(Plane);
  347. }
  348. else
  349. {
  350. Transform_Plane (Object, Trans);
  351. }
  352. }
  353. /*****************************************************************************
  354. *
  355. * FUNCTION
  356. *
  357. * Invert_Plane
  358. *
  359. * INPUT
  360. *
  361. * OUTPUT
  362. *
  363. * RETURNS
  364. *
  365. * AUTHOR
  366. *
  367. * POV-Ray Team
  368. *
  369. * DESCRIPTION
  370. *
  371. * -
  372. *
  373. * CHANGES
  374. *
  375. * -
  376. *
  377. ******************************************************************************/
  378. static void Invert_Plane (OBJECT *Object)
  379. {
  380. VScaleEq(((PLANE *)Object)->Normal_Vector, -1.0);
  381. ((PLANE *)Object)->Distance *= -1.0;
  382. }
  383. /*****************************************************************************
  384. *
  385. * FUNCTION
  386. *
  387. * Transform_Plane
  388. *
  389. * INPUT
  390. *
  391. * OUTPUT
  392. *
  393. * RETURNS
  394. *
  395. * AUTHOR
  396. *
  397. * POV-Ray Team
  398. *
  399. * DESCRIPTION
  400. *
  401. * -
  402. *
  403. * CHANGES
  404. *
  405. * -
  406. *
  407. ******************************************************************************/
  408. static void Transform_Plane(OBJECT *Object, TRANSFORM *Trans)
  409. {
  410. PLANE *Plane = (PLANE *) Object;
  411. if (Plane->Trans == NULL)
  412. {
  413. Plane->Trans = Create_Transform();
  414. }
  415. Compose_Transforms(Plane->Trans, Trans);
  416. Compute_Plane_BBox(Plane);
  417. }
  418. /*****************************************************************************
  419. *
  420. * FUNCTION
  421. *
  422. * Create_Plane
  423. *
  424. * INPUT
  425. *
  426. * OUTPUT
  427. *
  428. * RETURNS
  429. *
  430. * AUTHOR
  431. *
  432. * POV-Ray Team
  433. *
  434. * DESCRIPTION
  435. *
  436. * -
  437. *
  438. * CHANGES
  439. *
  440. * -
  441. *
  442. ******************************************************************************/
  443. PLANE *Create_Plane()
  444. {
  445. PLANE *New;
  446. New = (PLANE *)POV_MALLOC(sizeof (PLANE), "plane");
  447. INIT_OBJECT_FIELDS(New,PLANE_OBJECT,&Plane_Methods)
  448. Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  449. New ->Distance = 0.0;
  450. New->Trans = NULL;
  451. return(New);
  452. }
  453. /*****************************************************************************
  454. *
  455. * FUNCTION
  456. *
  457. * Copy_Plane
  458. *
  459. * INPUT
  460. *
  461. * OUTPUT
  462. *
  463. * RETURNS
  464. *
  465. * AUTHOR
  466. *
  467. * POV-Ray Team
  468. *
  469. * DESCRIPTION
  470. *
  471. * -
  472. *
  473. * CHANGES
  474. *
  475. * -
  476. *
  477. ******************************************************************************/
  478. static PLANE *Copy_Plane (OBJECT *Object)
  479. {
  480. PLANE *New;
  481. New = Create_Plane();
  482. Destroy_Transform(New->Trans);
  483. *New = *((PLANE *)Object);
  484. New->Trans = Copy_Transform(((PLANE *)Object)->Trans);
  485. return(New);
  486. }
  487. /*****************************************************************************
  488. *
  489. * FUNCTION
  490. *
  491. * Destroy_Plane
  492. *
  493. * INPUT
  494. *
  495. * OUTPUT
  496. *
  497. * RETURNS
  498. *
  499. * AUTHOR
  500. *
  501. * POV-Ray Team
  502. *
  503. * DESCRIPTION
  504. *
  505. * -
  506. *
  507. * CHANGES
  508. *
  509. * -
  510. *
  511. ******************************************************************************/
  512. static void Destroy_Plane(OBJECT *Object)
  513. {
  514. Destroy_Transform(((PLANE *)Object)->Trans);
  515. POV_FREE(Object);
  516. }
  517. /*****************************************************************************
  518. *
  519. * FUNCTION
  520. *
  521. * Compute_Plane_BBox
  522. *
  523. * INPUT
  524. *
  525. * Plane - Plane
  526. *
  527. * OUTPUT
  528. *
  529. * Plane
  530. *
  531. * RETURNS
  532. *
  533. * AUTHOR
  534. *
  535. * Dieter Bayer
  536. *
  537. * DESCRIPTION
  538. *
  539. * Calculate the bounding box of a plane (it's always infinite).
  540. *
  541. * CHANGES
  542. *
  543. * Aug 1994 : Creation.
  544. *
  545. ******************************************************************************/
  546. void Compute_Plane_BBox(PLANE *Plane)
  547. {
  548. Make_BBox(Plane->BBox, -BOUND_HUGE/2, -BOUND_HUGE/2, -BOUND_HUGE/2,
  549. BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  550. if (Plane->Clip != NULL)
  551. {
  552. Plane->BBox = Plane->Clip->BBox;
  553. }
  554. }