VLBUFFER.C 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /****************************************************************************
  2. * vlbuffer.c
  3. *
  4. * This module implements functions that are used by the vista/light buffer.
  5. *
  6. * This module was written by Dieter Bayer [DB].
  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. /****************************************************************************
  26. *
  27. * Explanation:
  28. *
  29. * -
  30. *
  31. * ---
  32. *
  33. * Mar 1994 : Creation.
  34. *
  35. *****************************************************************************/
  36. #include "frame.h"
  37. #include "vector.h"
  38. #include "povproto.h"
  39. #include "bbox.h"
  40. #include "vlbuffer.h"
  41. /*****************************************************************************
  42. * Local preprocessor defines
  43. ******************************************************************************/
  44. #define INITIAL_NUMBER_OF_ENTRIES 256
  45. /*****************************************************************************
  46. * Local typedefs
  47. ******************************************************************************/
  48. /*****************************************************************************
  49. * Local variables
  50. ******************************************************************************/
  51. /* Tree node queue. */
  52. PROJECT_QUEUE *Node_Queue;
  53. /* Priority queue. */
  54. PRIORITY_QUEUE *VLBuffer_Queue;
  55. /*****************************************************************************
  56. * Static functions
  57. ******************************************************************************/
  58. /*****************************************************************************
  59. *
  60. * FUNCTION
  61. *
  62. * Initialize_VLBuffer_Code
  63. *
  64. * INPUT
  65. *
  66. * OUTPUT
  67. *
  68. * RETURNS
  69. *
  70. * AUTHOR
  71. *
  72. * Dieter Bayer
  73. *
  74. * DESCRIPTION
  75. *
  76. * Init queues used by the light and vista buffer.
  77. *
  78. * CHANGES
  79. *
  80. * May 1994 : Creation.
  81. *
  82. ******************************************************************************/
  83. void Initialize_VLBuffer_Code()
  84. {
  85. Node_Queue = (PROJECT_QUEUE *)POV_MALLOC(sizeof(PROJECT_QUEUE),
  86. "vista/light buffer node queue");
  87. Node_Queue->QSize = 0;
  88. Node_Queue->Max_QSize = INITIAL_NUMBER_OF_ENTRIES;
  89. Node_Queue->Queue = (PROJECT_TREE_NODE **)POV_MALLOC(Node_Queue->Max_QSize*sizeof(PROJECT_TREE_NODE *),
  90. "vista/light buffer node queue");
  91. VLBuffer_Queue = Create_Priority_Queue(INITIAL_NUMBER_OF_ENTRIES);
  92. }
  93. /*****************************************************************************
  94. *
  95. * FUNCTION
  96. *
  97. * Reinitialize_VLBuffer_Code
  98. *
  99. * INPUT
  100. *
  101. * OUTPUT
  102. *
  103. * RETURNS
  104. *
  105. * AUTHOR
  106. *
  107. * Dieter Bayer
  108. *
  109. * DESCRIPTION
  110. *
  111. * Reinit queues used by the light and vista buffer.
  112. *
  113. * Note that only the node queue needs to be reinitialized.
  114. *
  115. * CHANGES
  116. *
  117. * Feb 1995 : Creation.
  118. *
  119. ******************************************************************************/
  120. void Reinitialize_VLBuffer_Code()
  121. {
  122. if (Node_Queue->QSize >= Node_Queue->Max_QSize)
  123. {
  124. if (Node_Queue->QSize >= INT_MAX/2)
  125. {
  126. Error("Node queue overflow.\n");
  127. }
  128. Node_Queue->Max_QSize *= 2;
  129. Node_Queue->Queue = (PROJECT_TREE_NODE **)POV_REALLOC(Node_Queue->Queue,
  130. Node_Queue->Max_QSize*sizeof(PROJECT_TREE_NODE *),
  131. "vista/light buffer node queue");
  132. }
  133. }
  134. /*****************************************************************************
  135. *
  136. * FUNCTION
  137. *
  138. * Deinitialize_VLBuffer_Code
  139. *
  140. * INPUT
  141. *
  142. * OUTPUT
  143. *
  144. * RETURNS
  145. *
  146. * AUTHOR
  147. *
  148. * Dieter Bayer
  149. *
  150. * DESCRIPTION
  151. *
  152. * Deinit queues used by the light and vista buffer.
  153. *
  154. * CHANGES
  155. *
  156. * May 1994 : Creation.
  157. *
  158. ******************************************************************************/
  159. void Deinitialize_VLBuffer_Code()
  160. {
  161. if (Node_Queue != NULL)
  162. {
  163. POV_FREE(Node_Queue->Queue);
  164. POV_FREE(Node_Queue);
  165. }
  166. if (VLBuffer_Queue != NULL)
  167. {
  168. Destroy_Priority_Queue(VLBuffer_Queue);
  169. }
  170. Node_Queue = NULL;
  171. VLBuffer_Queue = NULL;
  172. }
  173. /*****************************************************************************
  174. *
  175. * FUNCTION
  176. *
  177. * Clip_Polygon
  178. *
  179. * INPUT
  180. *
  181. * Points - polygon's points
  182. * PointCnt - Number of points in polygon
  183. * VX1, VY1, VX2, VY1 - Normal vectors of the clipping planes
  184. * DX1, DY1, DX2, DY2 - Distances of the clipping planes from
  185. * the origin
  186. *
  187. * OUTPUT
  188. *
  189. * Points, PointCnt
  190. *
  191. * RETURNS
  192. *
  193. * AUTHOR
  194. *
  195. * Dieter Bayer
  196. *
  197. * DESCRIPTION
  198. *
  199. * Clip polygon at the viewing pyramid define by the normal vectors
  200. * VX1, VX2, VY1, VY2 and the distances DX1, DX2, DY1, DY2.
  201. *
  202. * CHANGES
  203. *
  204. * May 1994 : Creation.
  205. *
  206. ******************************************************************************/
  207. void Clip_Polygon(VECTOR *Points, int *PointCnt, VECTOR VX1, VECTOR VX2, VECTOR VY1, VECTOR VY2, DBL DX1, DBL DX2, DBL DY1, DBL DY2)
  208. {
  209. DBL aktd, pred, fird, k;
  210. VECTOR aktP, intP, preP, firP, d;
  211. int i, pc;
  212. VECTOR ClipPoints[MAX_CLIP_POINTS];
  213. /********** clip polygon at "left" plane **********/
  214. pc = 0;
  215. Assign_Vector(firP, Points[0]);
  216. fird = VX1[X] * firP[X] + VX1[Y] * firP[Y] + VX1[Z] * firP[Z] - DX1;
  217. if (fird <= 0.0)
  218. {
  219. Assign_Vector(ClipPoints[pc++], firP);
  220. }
  221. Assign_Vector(aktP, firP);
  222. Assign_Vector(preP, firP);
  223. aktd = pred = fird;
  224. for (i = 1; i < *PointCnt; i++)
  225. {
  226. Assign_Vector(aktP, Points[i]);
  227. aktd = VX1[X] * aktP[X] + VX1[Y] * aktP[Y] + VX1[Z] * aktP[Z] - DX1;
  228. if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  229. {
  230. d[X] = preP[X] - aktP[X];
  231. d[Y] = preP[Y] - aktP[Y];
  232. d[Z] = preP[Z] - aktP[Z];
  233. k = -aktd / (VX1[X] * d[X] + VX1[Y] * d[Y] + VX1[Z] * d[Z]);
  234. intP[X] = aktP[X] + k * d[X];
  235. intP[Y] = aktP[Y] + k * d[Y];
  236. intP[Z] = aktP[Z] + k * d[Z];
  237. Assign_Vector(ClipPoints[pc++], intP);
  238. }
  239. if (aktd <= 0.0)
  240. {
  241. Assign_Vector(ClipPoints[pc++], aktP);
  242. }
  243. Assign_Vector(preP, aktP);
  244. pred = aktd;
  245. }
  246. if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  247. {
  248. d[X] = firP[X] - aktP[X];
  249. d[Y] = firP[Y] - aktP[Y];
  250. d[Z] = firP[Z] - aktP[Z];
  251. k = -aktd / (VX1[X] * d[X] + VX1[Y] * d[Y] + VX1[Z] * d[Z]);
  252. intP[X] = aktP[X] + k * d[X];
  253. intP[Y] = aktP[Y] + k * d[Y];
  254. intP[Z] = aktP[Z] + k * d[Z];
  255. Assign_Vector(ClipPoints[pc++], intP);
  256. }
  257. for (i = 0; i < pc; i++)
  258. {
  259. Assign_Vector(Points[i], ClipPoints[i]);
  260. }
  261. if ((*PointCnt = pc) == 0)
  262. return;
  263. /********** clip polygon at "right" plane **********/
  264. pc = 0;
  265. Assign_Vector(firP, Points[0]);
  266. fird = VX2[X] * firP[X] + VX2[Y] * firP[Y] + VX2[Z] * firP[Z] - DX2;
  267. if (fird <= 0.0)
  268. {
  269. Assign_Vector(ClipPoints[pc++], firP);
  270. }
  271. Assign_Vector(aktP, firP);
  272. Assign_Vector(preP, firP);
  273. aktd = pred = fird;
  274. for (i = 1; i < *PointCnt; i++)
  275. {
  276. Assign_Vector(aktP, Points[i]);
  277. aktd = VX2[X] * aktP[X] + VX2[Y] * aktP[Y] + VX2[Z] * aktP[Z] - DX2;
  278. if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  279. {
  280. d[X] = preP[X] - aktP[X];
  281. d[Y] = preP[Y] - aktP[Y];
  282. d[Z] = preP[Z] - aktP[Z];
  283. k = -aktd / (VX2[X] * d[X] + VX2[Y] * d[Y] + VX2[Z] * d[Z]);
  284. intP[X] = aktP[X] + k * d[X];
  285. intP[Y] = aktP[Y] + k * d[Y];
  286. intP[Z] = aktP[Z] + k * d[Z];
  287. Assign_Vector(ClipPoints[pc++], intP);
  288. }
  289. if (aktd <= 0.0)
  290. {
  291. Assign_Vector(ClipPoints[pc++], aktP);
  292. }
  293. Assign_Vector(preP, aktP);
  294. pred = aktd;
  295. }
  296. if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  297. {
  298. d[X] = firP[X] - aktP[X];
  299. d[Y] = firP[Y] - aktP[Y];
  300. d[Z] = firP[Z] - aktP[Z];
  301. k = -aktd / (VX2[X] * d[X] + VX2[Y] * d[Y] + VX2[Z] * d[Z]);
  302. intP[X] = aktP[X] + k * d[X];
  303. intP[Y] = aktP[Y] + k * d[Y];
  304. intP[Z] = aktP[Z] + k * d[Z];
  305. Assign_Vector(ClipPoints[pc++], intP);
  306. }
  307. for (i = 0; i < pc; i++)
  308. {
  309. Assign_Vector(Points[i], ClipPoints[i]);
  310. }
  311. if ((*PointCnt = pc) == 0)
  312. return;
  313. /********** clip polygon at "bottom" plane **********/
  314. pc = 0;
  315. Assign_Vector(firP, Points[0]);
  316. fird = VY1[X] * firP[X] + VY1[Y] * firP[Y] + VY1[Z] * firP[Z] - DY1;
  317. if (fird <= 0.0)
  318. {
  319. Assign_Vector(ClipPoints[pc++], firP);
  320. }
  321. Assign_Vector(aktP, firP);
  322. Assign_Vector(preP, firP);
  323. aktd = pred = fird;
  324. for (i = 1; i < *PointCnt; i++)
  325. {
  326. Assign_Vector(aktP, Points[i]);
  327. aktd = VY1[X] * aktP[X] + VY1[Y] * aktP[Y] + VY1[Z] * aktP[Z] - DY1;
  328. if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  329. {
  330. d[X] = preP[X] - aktP[X];
  331. d[Y] = preP[Y] - aktP[Y];
  332. d[Z] = preP[Z] - aktP[Z];
  333. k = -aktd / (VY1[X] * d[X] + VY1[Y] * d[Y] + VY1[Z] * d[Z]);
  334. intP[X] = aktP[X] + k * d[X];
  335. intP[Y] = aktP[Y] + k * d[Y];
  336. intP[Z] = aktP[Z] + k * d[Z];
  337. Assign_Vector(ClipPoints[pc++], intP);
  338. }
  339. if (aktd <= 0.0)
  340. {
  341. Assign_Vector(ClipPoints[pc++], aktP);
  342. }
  343. Assign_Vector(preP, aktP);
  344. pred = aktd;
  345. }
  346. if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  347. {
  348. d[X] = firP[X] - aktP[X];
  349. d[Y] = firP[Y] - aktP[Y];
  350. d[Z] = firP[Z] - aktP[Z];
  351. k = -aktd / (VY1[X] * d[X] + VY1[Y] * d[Y] + VY1[Z] * d[Z]);
  352. intP[X] = aktP[X] + k * d[X];
  353. intP[Y] = aktP[Y] + k * d[Y];
  354. intP[Z] = aktP[Z] + k * d[Z];
  355. Assign_Vector(ClipPoints[pc++], intP);
  356. }
  357. for (i = 0; i < pc; i++)
  358. {
  359. Assign_Vector(Points[i], ClipPoints[i]);
  360. }
  361. if ((*PointCnt = pc) == 0)
  362. return;
  363. /********** clip polygon at "top" plane **********/
  364. pc = 0;
  365. Assign_Vector(firP, Points[0]);
  366. fird = VY2[X] * firP[X] + VY2[Y] * firP[Y] + VY2[Z] * firP[Z] - DY2;
  367. if (fird <= 0.0)
  368. {
  369. Assign_Vector(ClipPoints[pc++], firP);
  370. }
  371. Assign_Vector(aktP, firP);
  372. Assign_Vector(preP, firP);
  373. aktd = pred = fird;
  374. for (i = pc = 0; i < *PointCnt; i++)
  375. {
  376. Assign_Vector(aktP, Points[i]);
  377. aktd = VY2[X] * aktP[X] + VY2[Y] * aktP[Y] + VY2[Z] * aktP[Z] - DY2;
  378. if (((aktd < 0.0) && (pred > 0.0)) || ((aktd > 0.0) && (pred < 0.0)))
  379. {
  380. d[X] = preP[X] - aktP[X];
  381. d[Y] = preP[Y] - aktP[Y];
  382. d[Z] = preP[Z] - aktP[Z];
  383. k = -aktd / (VY2[X] * d[X] + VY2[Y] * d[Y] + VY2[Z] * d[Z]);
  384. intP[X] = aktP[X] + k * d[X];
  385. intP[Y] = aktP[Y] + k * d[Y];
  386. intP[Z] = aktP[Z] + k * d[Z];
  387. Assign_Vector(ClipPoints[pc++], intP);
  388. }
  389. if (aktd <= 0.0)
  390. {
  391. Assign_Vector(ClipPoints[pc++], aktP);
  392. }
  393. Assign_Vector(preP, aktP);
  394. pred = aktd;
  395. }
  396. if (((fird < 0.0) && (aktd > 0.0)) || ((fird > 0.0) && (aktd < 0.0)))
  397. {
  398. d[X] = firP[X] - aktP[X];
  399. d[Y] = firP[Y] - aktP[Y];
  400. d[Z] = firP[Z] - aktP[Z];
  401. k = -aktd / (VY2[X] * d[X] + VY2[Y] * d[Y] + VY2[Z] * d[Z]);
  402. intP[X] = aktP[X] + k * d[X];
  403. intP[Y] = aktP[Y] + k * d[Y];
  404. intP[Z] = aktP[Z] + k * d[Z];
  405. Assign_Vector(ClipPoints[pc++], intP);
  406. }
  407. for (i = 0; i < pc; i++)
  408. {
  409. Assign_Vector(Points[i], ClipPoints[i]);
  410. }
  411. *PointCnt = pc;
  412. }
  413. /*****************************************************************************
  414. *
  415. * FUNCTION
  416. *
  417. * Destroy_Project_Tree
  418. *
  419. * INPUT
  420. *
  421. * OUTPUT
  422. *
  423. * RETURNS
  424. *
  425. * AUTHOR
  426. *
  427. * Dieter Bayer
  428. *
  429. * DESCRIPTION
  430. *
  431. * Recursively destroy a node in a projection (i.e. vista/light) tree.
  432. *
  433. * CHANGES
  434. *
  435. * Sep 1994 : Creation.
  436. *
  437. * Dec 1994 : Fixed memory leakage due to pruned branches. [DB]
  438. * Mar 1996 : Added COOPERATE for GUIs. [esp]
  439. *
  440. ******************************************************************************/
  441. void Destroy_Project_Tree(PROJECT_TREE_NODE *Node)
  442. {
  443. unsigned short i;
  444. if (Node->is_leaf & TRUE)
  445. {
  446. COOPERATE_1
  447. POV_FREE(Node);
  448. }
  449. else
  450. {
  451. for (i = 0; i < Node->Entries; i++)
  452. {
  453. Destroy_Project_Tree(Node->Entry[i]);
  454. }
  455. POV_FREE(Node->Entry);
  456. POV_FREE(Node);
  457. }
  458. }