TRIANGLE.C 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376
  1. /****************************************************************************
  2. * triangle.c
  3. *
  4. * This module implements primitives for triangles and smooth triangles.
  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 "triangle.h"
  30. /*****************************************************************************
  31. * Local preprocessor defines
  32. ******************************************************************************/
  33. #define DEPTH_TOLERANCE 1e-6
  34. #define max3_coordinate(x,y,z) \
  35. ((x > y) ? ((x > z) ? X : Z) : ((y > z) ? Y : Z))
  36. /*****************************************************************************
  37. * Static functions
  38. ******************************************************************************/
  39. static void find_triangle_dominant_axis (TRIANGLE *Triangle);
  40. static int compute_smooth_triangle (SMOOTH_TRIANGLE *Triangle);
  41. static int Intersect_Triangle (RAY *Ray, TRIANGLE *Triangle, DBL *Depth);
  42. static int All_Triangle_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  43. static int Inside_Triangle (VECTOR IPoint, OBJECT *Object);
  44. static void Triangle_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  45. static TRIANGLE *Copy_Triangle (OBJECT *Object);
  46. static void Translate_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  47. static void Rotate_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  48. static void Scale_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  49. static void Transform_Triangle (OBJECT *Object, TRANSFORM *Trans);
  50. static void Invert_Triangle (OBJECT *Object);
  51. static void Smooth_Triangle_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  52. static SMOOTH_TRIANGLE *Copy_Smooth_Triangle (OBJECT *Object);
  53. static void Translate_Smooth_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  54. static void Rotate_Smooth_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  55. static void Scale_Smooth_Triangle (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  56. static void Transform_Smooth_Triangle (OBJECT *Object, TRANSFORM *Trans);
  57. static void Invert_Smooth_Triangle (OBJECT *Object);
  58. static void Destroy_Triangle (OBJECT *Object);
  59. /*****************************************************************************
  60. * Local variables
  61. ******************************************************************************/
  62. METHODS Triangle_Methods =
  63. {
  64. All_Triangle_Intersections,
  65. Inside_Triangle, Triangle_Normal,
  66. (COPY_METHOD)Copy_Triangle,
  67. Translate_Triangle, Rotate_Triangle,
  68. Scale_Triangle, Transform_Triangle, Invert_Triangle, Destroy_Triangle
  69. };
  70. METHODS Smooth_Triangle_Methods =
  71. {
  72. All_Triangle_Intersections,
  73. Inside_Triangle, Smooth_Triangle_Normal,
  74. (COPY_METHOD)Copy_Smooth_Triangle,
  75. Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
  76. Scale_Smooth_Triangle, Transform_Smooth_Triangle,
  77. Invert_Smooth_Triangle, Destroy_Triangle
  78. };
  79. /*****************************************************************************
  80. *
  81. * FUNCTION
  82. *
  83. * find_triangle_dominant_axis
  84. *
  85. * INPUT
  86. *
  87. * OUTPUT
  88. *
  89. * RETURNS
  90. *
  91. * AUTHOR
  92. *
  93. * POV-Ray Team
  94. *
  95. * DESCRIPTION
  96. *
  97. * -
  98. *
  99. * CHANGES
  100. *
  101. * -
  102. *
  103. ******************************************************************************/
  104. static void find_triangle_dominant_axis(TRIANGLE *Triangle)
  105. {
  106. DBL x, y, z;
  107. x = fabs(Triangle->Normal_Vector[X]);
  108. y = fabs(Triangle->Normal_Vector[Y]);
  109. z = fabs(Triangle->Normal_Vector[Z]);
  110. Triangle->Dominant_Axis = max3_coordinate(x, y, z);
  111. }
  112. /*****************************************************************************
  113. *
  114. * FUNCTION
  115. *
  116. * compute_smooth_triangle
  117. *
  118. * INPUT
  119. *
  120. * OUTPUT
  121. *
  122. * RETURNS
  123. *
  124. * AUTHOR
  125. *
  126. * POV-Ray Team
  127. *
  128. * DESCRIPTION
  129. *
  130. * -
  131. *
  132. * CHANGES
  133. *
  134. * -
  135. *
  136. ******************************************************************************/
  137. static int compute_smooth_triangle(SMOOTH_TRIANGLE *Triangle)
  138. {
  139. VECTOR P3MinusP2, VTemp1, VTemp2;
  140. DBL x, y, z, uDenominator, Proj;
  141. VSub(P3MinusP2, Triangle->P3, Triangle->P2);
  142. x = fabs(P3MinusP2[X]);
  143. y = fabs(P3MinusP2[Y]);
  144. z = fabs(P3MinusP2[Z]);
  145. Triangle->vAxis = max3_coordinate(x, y, z);
  146. VSub(VTemp1, Triangle->P2, Triangle->P3);
  147. VNormalize(VTemp1, VTemp1);
  148. VSub(VTemp2, Triangle->P1, Triangle->P3);
  149. VDot(Proj, VTemp2, VTemp1);
  150. VScaleEq(VTemp1, Proj);
  151. VSub(Triangle->Perp, VTemp1, VTemp2);
  152. VNormalize(Triangle->Perp, Triangle->Perp);
  153. VDot(uDenominator, VTemp2, Triangle->Perp);
  154. VInverseScaleEq(Triangle->Perp, -uDenominator);
  155. /* Degenerate if smooth normals are more than 90 from actual normal
  156. or its inverse. */
  157. VDot(x,Triangle->Normal_Vector,Triangle->N1);
  158. VDot(y,Triangle->Normal_Vector,Triangle->N2);
  159. VDot(z,Triangle->Normal_Vector,Triangle->N3);
  160. if ( ((x<0.0) && (y<0.0) && (z<0.0)) ||
  161. ((x>0.0) && (y>0.0) && (z>0.0)) )
  162. {
  163. return(TRUE);
  164. }
  165. Set_Flag(Triangle, DEGENERATE_FLAG);
  166. return(FALSE);
  167. }
  168. /*****************************************************************************
  169. *
  170. * FUNCTION
  171. *
  172. * Compute_Triangle
  173. *
  174. * INPUT
  175. *
  176. * OUTPUT
  177. *
  178. * RETURNS
  179. *
  180. * AUTHOR
  181. *
  182. * POV-Ray Team
  183. *
  184. * DESCRIPTION
  185. *
  186. * -
  187. *
  188. * CHANGES
  189. *
  190. * -
  191. *
  192. ******************************************************************************/
  193. int Compute_Triangle(TRIANGLE *Triangle,int Smooth)
  194. {
  195. int swap,degn;
  196. VECTOR V1, V2, Temp;
  197. DBL Length;
  198. VSub(V1, Triangle->P1, Triangle->P2);
  199. VSub(V2, Triangle->P3, Triangle->P2);
  200. VCross(Triangle->Normal_Vector, V1, V2);
  201. VLength(Length, Triangle->Normal_Vector);
  202. /* Set up a flag so we can ignore degenerate triangles */
  203. if (Length == 0.0)
  204. {
  205. Set_Flag(Triangle, DEGENERATE_FLAG);
  206. return(FALSE);
  207. }
  208. /* Normalize the normal vector. */
  209. VInverseScaleEq(Triangle->Normal_Vector, Length);
  210. VDot(Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
  211. Triangle->Distance *= -1.0;
  212. find_triangle_dominant_axis(Triangle);
  213. swap = FALSE;
  214. switch (Triangle->Dominant_Axis)
  215. {
  216. case X:
  217. if ((Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  218. (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[Y] - Triangle->P1[Y]))
  219. {
  220. swap = TRUE;
  221. }
  222. break;
  223. case Y:
  224. if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  225. (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[X] - Triangle->P1[X]))
  226. {
  227. swap = TRUE;
  228. }
  229. break;
  230. case Z:
  231. if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Y] - Triangle->P1[Y]) <
  232. (Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[X] - Triangle->P1[X]))
  233. {
  234. swap = TRUE;
  235. }
  236. break;
  237. }
  238. if (swap)
  239. {
  240. Assign_Vector(Temp, Triangle->P2);
  241. Assign_Vector(Triangle->P2, Triangle->P1);
  242. Assign_Vector(Triangle->P1, Temp);
  243. if (Smooth)
  244. {
  245. Assign_Vector(Temp, ((SMOOTH_TRIANGLE *)Triangle)->N2);
  246. Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N2, ((SMOOTH_TRIANGLE *)Triangle)->N1);
  247. Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N1, Temp);
  248. }
  249. }
  250. degn=TRUE;
  251. if (Smooth)
  252. {
  253. degn=compute_smooth_triangle((SMOOTH_TRIANGLE *)Triangle);
  254. }
  255. /* Build the bounding information from the vertices. */
  256. Compute_Triangle_BBox(Triangle);
  257. return(degn);
  258. }
  259. /*****************************************************************************
  260. *
  261. * FUNCTION
  262. *
  263. * All_Triangle_Intersections
  264. *
  265. * INPUT
  266. *
  267. * OUTPUT
  268. *
  269. * RETURNS
  270. *
  271. * AUTHOR
  272. *
  273. * POV-Ray Team
  274. *
  275. * DESCRIPTION
  276. *
  277. * -
  278. *
  279. * CHANGES
  280. *
  281. * -
  282. *
  283. ******************************************************************************/
  284. static int All_Triangle_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  285. {
  286. DBL Depth;
  287. VECTOR IPoint;
  288. if (Intersect_Triangle(Ray, (TRIANGLE *)Object, &Depth))
  289. {
  290. VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
  291. if (Point_In_Clip(IPoint,Object->Clip))
  292. {
  293. push_entry(Depth,IPoint,Object,Depth_Stack);
  294. return(TRUE);
  295. }
  296. }
  297. return(FALSE);
  298. }
  299. /*****************************************************************************
  300. *
  301. * FUNCTION
  302. *
  303. * Intersect_Triangle
  304. *
  305. * INPUT
  306. *
  307. * OUTPUT
  308. *
  309. * RETURNS
  310. *
  311. * AUTHOR
  312. *
  313. * POV-Ray Team
  314. *
  315. * DESCRIPTION
  316. *
  317. * -
  318. *
  319. * CHANGES
  320. *
  321. * -
  322. *
  323. ******************************************************************************/
  324. static int Intersect_Triangle(RAY *Ray, TRIANGLE *Triangle, DBL *Depth)
  325. {
  326. DBL NormalDotOrigin, NormalDotDirection;
  327. DBL s, t;
  328. Increase_Counter(stats[Ray_Triangle_Tests]);
  329. if (Test_Flag(Triangle, DEGENERATE_FLAG))
  330. {
  331. return(FALSE);
  332. }
  333. VDot(NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
  334. if (fabs(NormalDotDirection) < EPSILON)
  335. {
  336. return(FALSE);
  337. }
  338. VDot(NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
  339. *Depth = -(Triangle->Distance + NormalDotOrigin) / NormalDotDirection;
  340. if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance))
  341. {
  342. return(FALSE);
  343. }
  344. switch (Triangle->Dominant_Axis)
  345. {
  346. case X:
  347. s = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  348. t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  349. if ((Triangle->P2[Y] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  350. (Triangle->P2[Z] - t) * (Triangle->P2[Y] - Triangle->P1[Y]))
  351. {
  352. return(FALSE);
  353. }
  354. if ((Triangle->P3[Y] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  355. (Triangle->P3[Z] - t) * (Triangle->P3[Y] - Triangle->P2[Y]))
  356. {
  357. return(FALSE);
  358. }
  359. if ((Triangle->P1[Y] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  360. (Triangle->P1[Z] - t) * (Triangle->P1[Y] - Triangle->P3[Y]))
  361. {
  362. return(FALSE);
  363. }
  364. Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  365. return(TRUE);
  366. case Y:
  367. s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  368. t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  369. if ((Triangle->P2[X] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  370. (Triangle->P2[Z] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  371. {
  372. return(FALSE);
  373. }
  374. if ((Triangle->P3[X] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  375. (Triangle->P3[Z] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  376. {
  377. return(FALSE);
  378. }
  379. if ((Triangle->P1[X] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  380. (Triangle->P1[Z] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  381. {
  382. return(FALSE);
  383. }
  384. Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  385. return(TRUE);
  386. case Z:
  387. s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  388. t = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  389. if ((Triangle->P2[X] - s) * (Triangle->P2[Y] - Triangle->P1[Y]) <
  390. (Triangle->P2[Y] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  391. {
  392. return(FALSE);
  393. }
  394. if ((Triangle->P3[X] - s) * (Triangle->P3[Y] - Triangle->P2[Y]) <
  395. (Triangle->P3[Y] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  396. {
  397. return(FALSE);
  398. }
  399. if ((Triangle->P1[X] - s) * (Triangle->P1[Y] - Triangle->P3[Y]) <
  400. (Triangle->P1[Y] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  401. {
  402. return(FALSE);
  403. }
  404. Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  405. return(TRUE);
  406. }
  407. return(FALSE);
  408. }
  409. /*****************************************************************************
  410. *
  411. * FUNCTION
  412. *
  413. * Inside_Triangle
  414. *
  415. * INPUT
  416. *
  417. * OUTPUT
  418. *
  419. * RETURNS
  420. *
  421. * AUTHOR
  422. *
  423. * POV-Ray Team
  424. *
  425. * DESCRIPTION
  426. *
  427. * -
  428. *
  429. * CHANGES
  430. *
  431. * -
  432. *
  433. ******************************************************************************/
  434. static int Inside_Triangle(VECTOR IPoint, OBJECT *Object)
  435. {
  436. return(FALSE);
  437. }
  438. /*****************************************************************************
  439. *
  440. * FUNCTION
  441. *
  442. * Triangle_Normal
  443. *
  444. * INPUT
  445. *
  446. * OUTPUT
  447. *
  448. * RETURNS
  449. *
  450. * AUTHOR
  451. *
  452. * POV-Ray Team
  453. *
  454. * DESCRIPTION
  455. *
  456. * -
  457. *
  458. * CHANGES
  459. *
  460. * -
  461. *
  462. ******************************************************************************/
  463. static void Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  464. {
  465. Assign_Vector(Result, ((TRIANGLE *)Object)->Normal_Vector);
  466. }
  467. /*****************************************************************************
  468. *
  469. * FUNCTION
  470. *
  471. * Smooth_Triangle_Normal
  472. *
  473. * INPUT
  474. *
  475. * OUTPUT
  476. *
  477. * RETURNS
  478. *
  479. * AUTHOR
  480. *
  481. * POV-Ray Team
  482. *
  483. * DESCRIPTION
  484. *
  485. * Calculate the Phong-interpolated vector within the triangle
  486. * at the given intersection point. The math for this is a bit
  487. * bizarre:
  488. *
  489. * - P1
  490. * | /|\ \
  491. * | / |Perp\
  492. * | / V \ \
  493. * | / | \ \
  494. * u | /____|_____PI___\
  495. * | / | \ \
  496. * - P2-----|--------|----P3
  497. * Pbase PIntersect
  498. * |-------------------|
  499. * v
  500. *
  501. * Triangle->Perp is a unit vector from P1 to Pbase. We calculate
  502. *
  503. * u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
  504. *
  505. * We then calculate where the line from P1 to PI intersects the line P2 to P3:
  506. * PIntersect = (PI - P1)/u.
  507. *
  508. * We really only need one coordinate of PIntersect. We then calculate v as:
  509. *
  510. * v = PIntersect[X] / (P3[X] - P2[X])
  511. * or v = PIntersect[Y] / (P3[Y] - P2[Y])
  512. * or v = PIntersect[Z] / (P3[Z] - P2[Z])
  513. *
  514. * depending on which calculation will give us the best answers.
  515. *
  516. * Once we have u and v, we can perform the normal interpolation as:
  517. *
  518. * NTemp1 = N1 + u(N2 - N1);
  519. * NTemp2 = N1 + u(N3 - N1);
  520. * Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
  521. *
  522. * As always, any values which are constant for the triangle are cached
  523. * in the triangle.
  524. *
  525. * CHANGES
  526. *
  527. * -
  528. *
  529. ******************************************************************************/
  530. static void Smooth_Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  531. {
  532. int Axis;
  533. DBL u, v;
  534. VECTOR PIMinusP1;
  535. SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  536. VSub(PIMinusP1, Inter->IPoint, Triangle->P1);
  537. VDot(u, PIMinusP1, Triangle->Perp);
  538. if (u < EPSILON)
  539. {
  540. Assign_Vector(Result, Triangle->N1);
  541. return;
  542. }
  543. Axis = Triangle->vAxis;
  544. v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]);
  545. /* This is faster. [DB 8/94] */
  546. Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X]));
  547. Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y]));
  548. Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z]));
  549. VNormalize(Result, Result);
  550. }
  551. /*****************************************************************************
  552. *
  553. * FUNCTION
  554. *
  555. * Translate_Triangle
  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. static void Translate_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  577. {
  578. TRIANGLE *Triangle = (TRIANGLE *)Object;
  579. VECTOR Translation;
  580. if (!Test_Flag(Triangle, DEGENERATE_FLAG))
  581. {
  582. VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  583. Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  584. VAddEq(Triangle->P1, Vector);
  585. VAddEq(Triangle->P2, Vector);
  586. VAddEq(Triangle->P3, Vector);
  587. Compute_Triangle(Triangle, FALSE);
  588. }
  589. }
  590. /*****************************************************************************
  591. *
  592. * FUNCTION
  593. *
  594. * Rotate_Triangle
  595. *
  596. * INPUT
  597. *
  598. * OUTPUT
  599. *
  600. * RETURNS
  601. *
  602. * AUTHOR
  603. *
  604. * POV-Ray Team
  605. *
  606. * DESCRIPTION
  607. *
  608. * -
  609. *
  610. * CHANGES
  611. *
  612. * -
  613. *
  614. ******************************************************************************/
  615. static void Rotate_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  616. {
  617. if (!Test_Flag(Object, DEGENERATE_FLAG))
  618. {
  619. Transform_Triangle(Object, Trans);
  620. }
  621. }
  622. /*****************************************************************************
  623. *
  624. * FUNCTION
  625. *
  626. * Scale_Triangle
  627. *
  628. * INPUT
  629. *
  630. * OUTPUT
  631. *
  632. * RETURNS
  633. *
  634. * AUTHOR
  635. *
  636. * POV-Ray Team
  637. *
  638. * DESCRIPTION
  639. *
  640. * -
  641. *
  642. * CHANGES
  643. *
  644. * -
  645. *
  646. ******************************************************************************/
  647. static void Scale_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  648. {
  649. DBL Length;
  650. TRIANGLE *Triangle = (TRIANGLE *)Object;
  651. if (!Test_Flag(Object, DEGENERATE_FLAG))
  652. {
  653. Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  654. Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  655. Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  656. VLength(Length, Triangle->Normal_Vector);
  657. VInverseScaleEq(Triangle->Normal_Vector, Length);
  658. Triangle->Distance /= Length;
  659. VEvaluateEq(Triangle->P1, Vector);
  660. VEvaluateEq(Triangle->P2, Vector);
  661. VEvaluateEq(Triangle->P3, Vector);
  662. Compute_Triangle(Triangle, FALSE);
  663. }
  664. }
  665. /*****************************************************************************
  666. *
  667. * FUNCTION
  668. *
  669. * Transfrom_Triangle
  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. static void Transform_Triangle(OBJECT *Object, TRANSFORM *Trans)
  691. {
  692. TRIANGLE *Triangle = (TRIANGLE *)Object;
  693. if (!Test_Flag(Object, DEGENERATE_FLAG))
  694. {
  695. MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  696. MTransPoint(Triangle->P1, Triangle->P1, Trans);
  697. MTransPoint(Triangle->P2, Triangle->P2, Trans);
  698. MTransPoint(Triangle->P3, Triangle->P3, Trans);
  699. Compute_Triangle(Triangle, FALSE);
  700. }
  701. }
  702. /*****************************************************************************
  703. *
  704. * FUNCTION
  705. *
  706. * Invert_Triangle
  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. static void Invert_Triangle(OBJECT *Object)
  728. {
  729. }
  730. /*****************************************************************************
  731. *
  732. * FUNCTION
  733. *
  734. * Create_Triangle
  735. *
  736. * INPUT
  737. *
  738. * OUTPUT
  739. *
  740. * RETURNS
  741. *
  742. * AUTHOR
  743. *
  744. * POV-Ray Team
  745. *
  746. * DESCRIPTION
  747. *
  748. * -
  749. *
  750. * CHANGES
  751. *
  752. * -
  753. *
  754. ******************************************************************************/
  755. TRIANGLE *Create_Triangle()
  756. {
  757. TRIANGLE *New;
  758. New = (TRIANGLE *)POV_MALLOC(sizeof(TRIANGLE), "triangle");
  759. INIT_OBJECT_FIELDS(New,TRIANGLE_OBJECT,&Triangle_Methods)
  760. Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  761. New->Distance = 0.0;
  762. Make_Vector(New->P1, 0.0, 0.0, 0.0);
  763. Make_Vector(New->P2, 1.0, 0.0, 0.0);
  764. Make_Vector(New->P3, 0.0, 1.0, 0.0);
  765. /*
  766. * NOTE: Dominant_Axis is computed when Parse_Triangle calls
  767. * Compute_Triangle. vAxis is used only for smooth triangles.
  768. */
  769. return(New);
  770. }
  771. /*****************************************************************************
  772. *
  773. * FUNCTION
  774. *
  775. * Copy_Triangle
  776. *
  777. * INPUT
  778. *
  779. * OUTPUT
  780. *
  781. * RETURNS
  782. *
  783. * AUTHOR
  784. *
  785. * POV-Ray Team
  786. *
  787. * DESCRIPTION
  788. *
  789. * -
  790. *
  791. * CHANGES
  792. *
  793. * -
  794. *
  795. ******************************************************************************/
  796. static TRIANGLE *Copy_Triangle(OBJECT *Object)
  797. {
  798. TRIANGLE *New;
  799. New = Create_Triangle();
  800. *New = *((TRIANGLE *)Object);
  801. return(New);
  802. }
  803. /*****************************************************************************
  804. *
  805. * FUNCTION
  806. *
  807. * Destroy_Triangle
  808. *
  809. * INPUT
  810. *
  811. * OUTPUT
  812. *
  813. * RETURNS
  814. *
  815. * AUTHOR
  816. *
  817. * POV-Ray Team
  818. *
  819. * DESCRIPTION
  820. *
  821. * -
  822. *
  823. * CHANGES
  824. *
  825. * -
  826. *
  827. ******************************************************************************/
  828. static void Destroy_Triangle(OBJECT *Object)
  829. {
  830. POV_FREE (Object);
  831. }
  832. /*****************************************************************************
  833. *
  834. * FUNCTION
  835. *
  836. * Translate_Smooth_Triangle
  837. *
  838. * INPUT
  839. *
  840. * OUTPUT
  841. *
  842. * RETURNS
  843. *
  844. * AUTHOR
  845. *
  846. * POV-Ray Team
  847. *
  848. * DESCRIPTION
  849. *
  850. * -
  851. *
  852. * CHANGES
  853. *
  854. * -
  855. *
  856. ******************************************************************************/
  857. static void Translate_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  858. {
  859. SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  860. VECTOR Translation;
  861. if (!Test_Flag(Object, DEGENERATE_FLAG))
  862. {
  863. VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  864. Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  865. VAddEq(Triangle->P1, Vector);
  866. VAddEq(Triangle->P2, Vector);
  867. VAddEq(Triangle->P3, Vector);
  868. Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  869. }
  870. }
  871. /*****************************************************************************
  872. *
  873. * FUNCTION
  874. *
  875. * Rotate_Smooth_Triangle
  876. *
  877. * INPUT
  878. *
  879. * OUTPUT
  880. *
  881. * RETURNS
  882. *
  883. * AUTHOR
  884. *
  885. * POV-Ray Team
  886. *
  887. * DESCRIPTION
  888. *
  889. * -
  890. *
  891. * CHANGES
  892. *
  893. * -
  894. *
  895. ******************************************************************************/
  896. static void Rotate_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  897. {
  898. if (!Test_Flag(Object, DEGENERATE_FLAG))
  899. {
  900. Transform_Smooth_Triangle(Object, Trans);
  901. }
  902. }
  903. /*****************************************************************************
  904. *
  905. * FUNCTION
  906. *
  907. * Scale_Smooth_Triangle
  908. *
  909. * INPUT
  910. *
  911. * OUTPUT
  912. *
  913. * RETURNS
  914. *
  915. * AUTHOR
  916. *
  917. * POV-Ray Team
  918. *
  919. * DESCRIPTION
  920. *
  921. * -
  922. *
  923. * CHANGES
  924. *
  925. * -
  926. *
  927. ******************************************************************************/
  928. static void Scale_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  929. {
  930. DBL Length;
  931. SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  932. if (!Test_Flag(Object, DEGENERATE_FLAG))
  933. {
  934. Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  935. Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  936. Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  937. VLength(Length, Triangle->Normal_Vector);
  938. VScaleEq(Triangle->Normal_Vector, 1.0 / Length);
  939. Triangle->Distance /= Length;
  940. VEvaluateEq(Triangle->P1, Vector);
  941. VEvaluateEq(Triangle->P2, Vector);
  942. VEvaluateEq(Triangle->P3, Vector);
  943. Compute_Triangle((TRIANGLE *)Triangle,TRUE);
  944. }
  945. }
  946. /*****************************************************************************
  947. *
  948. * FUNCTION
  949. *
  950. * Transform_Smooth_Triangle
  951. *
  952. * INPUT
  953. *
  954. * OUTPUT
  955. *
  956. * RETURNS
  957. *
  958. * AUTHOR
  959. *
  960. * POV-Ray Team
  961. *
  962. * DESCRIPTION
  963. *
  964. * -
  965. *
  966. * CHANGES
  967. *
  968. * -
  969. *
  970. ******************************************************************************/
  971. static void Transform_Smooth_Triangle(OBJECT *Object, TRANSFORM *Trans)
  972. {
  973. SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  974. if (!Test_Flag(Object, DEGENERATE_FLAG))
  975. {
  976. MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  977. MTransPoint(Triangle->P1, Triangle->P1, Trans);
  978. MTransPoint(Triangle->P2, Triangle->P2, Trans);
  979. MTransPoint(Triangle->P3, Triangle->P3, Trans);
  980. MTransPoint(Triangle->N1, Triangle->N1, Trans);
  981. MTransPoint(Triangle->N2, Triangle->N2, Trans);
  982. MTransPoint(Triangle->N3, Triangle->N3, Trans);
  983. Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  984. }
  985. }
  986. /*****************************************************************************
  987. *
  988. * FUNCTION
  989. *
  990. * Invert_Smooth_Triangle
  991. *
  992. * INPUT
  993. *
  994. * OUTPUT
  995. *
  996. * RETURNS
  997. *
  998. * AUTHOR
  999. *
  1000. * POV-Ray Team
  1001. *
  1002. * DESCRIPTION
  1003. *
  1004. * -
  1005. *
  1006. * CHANGES
  1007. *
  1008. * -
  1009. *
  1010. ******************************************************************************/
  1011. static void Invert_Smooth_Triangle(OBJECT *Object)
  1012. {
  1013. }
  1014. /*****************************************************************************
  1015. *
  1016. * FUNCTION
  1017. *
  1018. * Create_Smooth_Triangle
  1019. *
  1020. * INPUT
  1021. *
  1022. * OUTPUT
  1023. *
  1024. * RETURNS
  1025. *
  1026. * AUTHOR
  1027. *
  1028. * POV-Ray Team
  1029. *
  1030. * DESCRIPTION
  1031. *
  1032. * -
  1033. *
  1034. * CHANGES
  1035. *
  1036. * -
  1037. *
  1038. ******************************************************************************/
  1039. SMOOTH_TRIANGLE *Create_Smooth_Triangle()
  1040. {
  1041. SMOOTH_TRIANGLE *New;
  1042. New = (SMOOTH_TRIANGLE *)POV_MALLOC(sizeof(SMOOTH_TRIANGLE), "smooth triangle");
  1043. INIT_OBJECT_FIELDS(New,SMOOTH_TRIANGLE_OBJECT,&Smooth_Triangle_Methods)
  1044. Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  1045. New->Distance = 0.0;
  1046. Make_Vector(New->P1, 0.0, 0.0, 0.0);
  1047. Make_Vector(New->P2, 1.0, 0.0, 0.0);
  1048. Make_Vector(New->P3, 0.0, 1.0, 0.0);
  1049. Make_Vector(New->N1, 0.0, 1.0, 0.0);
  1050. Make_Vector(New->N2, 0.0, 1.0, 0.0);
  1051. Make_Vector(New->N3, 0.0, 1.0, 0.0);
  1052. /*
  1053. * NOTE: Dominant_Axis and vAxis are computed when
  1054. * Parse_Triangle calls Compute_Triangle.
  1055. */
  1056. return(New);
  1057. }
  1058. /*****************************************************************************
  1059. *
  1060. * FUNCTION
  1061. *
  1062. * Copy_Smooth_Triangle
  1063. *
  1064. * INPUT
  1065. *
  1066. * OUTPUT
  1067. *
  1068. * RETURNS
  1069. *
  1070. * AUTHOR
  1071. *
  1072. * POV-Ray Team
  1073. *
  1074. * DESCRIPTION
  1075. *
  1076. * -
  1077. *
  1078. * CHANGES
  1079. *
  1080. * -
  1081. *
  1082. ******************************************************************************/
  1083. static SMOOTH_TRIANGLE *Copy_Smooth_Triangle(OBJECT *Object)
  1084. {
  1085. SMOOTH_TRIANGLE *New;
  1086. New = Create_Smooth_Triangle();
  1087. *New = *((SMOOTH_TRIANGLE *)Object);
  1088. return(New);
  1089. }
  1090. /*****************************************************************************
  1091. *
  1092. * FUNCTION
  1093. *
  1094. * Compute_Triangle_BBox
  1095. *
  1096. * INPUT
  1097. *
  1098. * Triangle - Triangle
  1099. *
  1100. * OUTPUT
  1101. *
  1102. * Triangle
  1103. *
  1104. * RETURNS
  1105. *
  1106. * AUTHOR
  1107. *
  1108. * Dieter Bayer
  1109. *
  1110. * DESCRIPTION
  1111. *
  1112. * Calculate the bounding box of a triangle.
  1113. *
  1114. * CHANGES
  1115. *
  1116. * Aug 1994 : Creation.
  1117. *
  1118. ******************************************************************************/
  1119. void Compute_Triangle_BBox(TRIANGLE *Triangle)
  1120. {
  1121. VECTOR Min, Max, Epsilon;
  1122. Make_Vector(Epsilon, EPSILON, EPSILON, EPSILON);
  1123. Min[X] = min3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1124. Min[Y] = min3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1125. Min[Z] = min3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1126. Max[X] = max3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1127. Max[Y] = max3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1128. Max[Z] = max3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1129. VSubEq(Min, Epsilon);
  1130. VAddEq(Max, Epsilon);
  1131. Make_BBox_from_min_max(Triangle->BBox, Min, Max);
  1132. }