home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / povsrc31.zip / triangle.c < prev    next >
C/C++ Source or Header  |  2000-01-10  |  35KB  |  1,667 lines

  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.  
  24. #include "frame.h"
  25. #include "povray.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "matrices.h"
  29. #include "objects.h"
  30. #include "triangle.h"
  31.  
  32.  
  33.  
  34. /*****************************************************************************
  35. * Local preprocessor defines
  36. ******************************************************************************/
  37.  
  38. #define DEPTH_TOLERANCE 1e-6
  39.  
  40. #define max3_coordinate(x,y,z) \
  41.   ((x > y) ? ((x > z) ? X : Z) : ((y > z) ? Y : Z))
  42.  
  43.  
  44.  
  45. /*****************************************************************************
  46. * Static functions
  47. ******************************************************************************/
  48.  
  49. static void find_triangle_dominant_axis (TRIANGLE *Triangle);
  50. static int compute_smooth_triangle  (SMOOTH_TRIANGLE *Triangle);
  51. static int Intersect_Triangle  (RAY *Ray, TRIANGLE *Triangle, DBL *Depth);
  52. static int All_Triangle_Intersections  (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  53. static int Inside_Triangle  (VECTOR IPoint, OBJECT *Object);
  54. static void Triangle_Normal  (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  55. static TRIANGLE *Copy_Triangle  (OBJECT *Object);
  56. static void Translate_Triangle  (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  57. static void Rotate_Triangle  (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  58. static void Scale_Triangle  (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  59. static void Transform_Triangle  (OBJECT *Object, TRANSFORM *Trans);
  60. static void Invert_Triangle  (OBJECT *Object);
  61. static void Smooth_Triangle_Normal  (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  62. static SMOOTH_TRIANGLE *Copy_Smooth_Triangle (OBJECT *Object);
  63. static void Translate_Smooth_Triangle  (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  64. static void Rotate_Smooth_Triangle  (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  65. static void Scale_Smooth_Triangle  (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  66. static void Transform_Smooth_Triangle  (OBJECT *Object, TRANSFORM *Trans);
  67. static void Invert_Smooth_Triangle  (OBJECT *Object);
  68. static void Destroy_Triangle  (OBJECT *Object);
  69.  
  70.  
  71.  
  72. /*****************************************************************************
  73. * Local variables
  74. ******************************************************************************/
  75.  
  76. METHODS Triangle_Methods =
  77. {
  78.   All_Triangle_Intersections,
  79.   Inside_Triangle, Triangle_Normal, Default_UVCoord,
  80.   (COPY_METHOD)Copy_Triangle,
  81.   Translate_Triangle, Rotate_Triangle,
  82.   Scale_Triangle, Transform_Triangle, Invert_Triangle, Destroy_Triangle
  83. };
  84.  
  85. METHODS Smooth_Triangle_Methods =
  86. {
  87.   All_Triangle_Intersections,
  88.   Inside_Triangle, Smooth_Triangle_Normal, Default_UVCoord,
  89.   (COPY_METHOD)Copy_Smooth_Triangle,
  90.   Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
  91.   Scale_Smooth_Triangle, Transform_Smooth_Triangle,
  92.   Invert_Smooth_Triangle, Destroy_Triangle
  93. };
  94.  
  95. #ifdef ColorTrianglePatch2
  96. METHODS Smooth_Color_Triangle_Methods = /* AP */
  97. {
  98.   All_Triangle_Intersections,
  99.   Inside_Triangle, Smooth_Triangle_Normal,
  100.     Default_UVCoord,
  101.  
  102.   (COPY_METHOD)Copy_Smooth_Triangle,
  103.   Translate_Smooth_Triangle, Rotate_Smooth_Triangle,
  104.   Scale_Smooth_Triangle, Transform_Smooth_Triangle,
  105.   Invert_Smooth_Triangle, Destroy_Triangle
  106. };
  107. #endif
  108.  
  109. /*****************************************************************************
  110. *
  111. * FUNCTION
  112. *
  113. *   find_triangle_dominant_axis
  114. *
  115. * INPUT
  116. *   
  117. * OUTPUT
  118. *   
  119. * RETURNS
  120. *   
  121. * AUTHOR
  122. *
  123. *   POV-Ray Team
  124. *   
  125. * DESCRIPTION
  126. *
  127. *   -
  128. *
  129. * CHANGES
  130. *
  131. *   -
  132. *
  133. ******************************************************************************/
  134.  
  135. static void find_triangle_dominant_axis(TRIANGLE *Triangle)
  136. {
  137.   DBL x, y, z;
  138.  
  139.   x = fabs(Triangle->Normal_Vector[X]);
  140.   y = fabs(Triangle->Normal_Vector[Y]);
  141.   z = fabs(Triangle->Normal_Vector[Z]);
  142.  
  143.   Triangle->Dominant_Axis = max3_coordinate(x, y, z);
  144. }
  145.  
  146.  
  147.  
  148. /*****************************************************************************
  149. *
  150. * FUNCTION
  151. *
  152. *   compute_smooth_triangle
  153. *
  154. * INPUT
  155. *   
  156. * OUTPUT
  157. *   
  158. * RETURNS
  159. *   
  160. * AUTHOR
  161. *
  162. *   POV-Ray Team
  163. *   
  164. * DESCRIPTION
  165. *
  166. *   -
  167. *
  168. * CHANGES
  169. *
  170. *   -
  171. *
  172. ******************************************************************************/
  173.  
  174. static int compute_smooth_triangle(SMOOTH_TRIANGLE *Triangle)
  175. {
  176.   VECTOR P3MinusP2, VTemp1, VTemp2;
  177.   DBL x, y, z, uDenominator, Proj;
  178.  
  179.   VSub(P3MinusP2, Triangle->P3, Triangle->P2);
  180.  
  181.   x = fabs(P3MinusP2[X]);
  182.   y = fabs(P3MinusP2[Y]);
  183.   z = fabs(P3MinusP2[Z]);
  184.  
  185.   Triangle->vAxis = max3_coordinate(x, y, z);
  186.  
  187.   VSub(VTemp1, Triangle->P2, Triangle->P3);
  188.  
  189.   VNormalize(VTemp1, VTemp1);
  190.  
  191.   VSub(VTemp2, Triangle->P1, Triangle->P3);
  192.  
  193.   VDot(Proj, VTemp2, VTemp1);
  194.  
  195.   VScaleEq(VTemp1, Proj);
  196.  
  197.   VSub(Triangle->Perp, VTemp1, VTemp2);
  198.  
  199.   VNormalize(Triangle->Perp, Triangle->Perp);
  200.  
  201.   VDot(uDenominator, VTemp2, Triangle->Perp);
  202.  
  203.   VInverseScaleEq(Triangle->Perp, -uDenominator);
  204.  
  205.   /* Degenerate if smooth normals are more than 90 from actual normal
  206.      or its inverse. */
  207.   VDot(x,Triangle->Normal_Vector,Triangle->N1);
  208.   VDot(y,Triangle->Normal_Vector,Triangle->N2);
  209.   VDot(z,Triangle->Normal_Vector,Triangle->N3);
  210.   if ( ((x<0.0) && (y<0.0) && (z<0.0)) ||
  211.        ((x>0.0) && (y>0.0) && (z>0.0)) )
  212.   {
  213.     return(TRUE);
  214.   }
  215.   Set_Flag(Triangle, DEGENERATE_FLAG);
  216.   return(FALSE);
  217. }
  218.  
  219.  
  220.  
  221. /*****************************************************************************
  222. *
  223. * FUNCTION
  224. *
  225. *   Compute_Triangle
  226. *
  227. * INPUT
  228. *   
  229. * OUTPUT
  230. *   
  231. * RETURNS
  232. *   
  233. * AUTHOR
  234. *
  235. *   POV-Ray Team
  236. *   
  237. * DESCRIPTION
  238. *
  239. *   -
  240. *
  241. * CHANGES
  242. *
  243. *   -
  244. *
  245. ******************************************************************************/
  246.  
  247. int Compute_Triangle(TRIANGLE *Triangle,int Smooth)
  248. {
  249.   int swap,degn;
  250.   VECTOR V1, V2, Temp;
  251.   DBL Length;
  252. #ifdef ColorTrianglePatch2
  253.   COLOUR CTemp; /* AP */
  254. #endif
  255.  
  256.   VSub(V1, Triangle->P1, Triangle->P2);
  257.   VSub(V2, Triangle->P3, Triangle->P2);
  258.  
  259.   VCross(Triangle->Normal_Vector, V1, V2);
  260.  
  261.   VLength(Length, Triangle->Normal_Vector);
  262.  
  263.   /* Set up a flag so we can ignore degenerate triangles */
  264.  
  265.   if (Length == 0.0)
  266.   {
  267.     Set_Flag(Triangle, DEGENERATE_FLAG);
  268.  
  269.     return(FALSE);
  270.   }
  271.  
  272.   /* Normalize the normal vector. */
  273.  
  274.   VInverseScaleEq(Triangle->Normal_Vector, Length);
  275.  
  276.   VDot(Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
  277.  
  278.   Triangle->Distance *= -1.0;
  279.  
  280.   find_triangle_dominant_axis(Triangle);
  281.  
  282.   swap = FALSE;
  283.  
  284.   switch (Triangle->Dominant_Axis)
  285.   {
  286.     case X:
  287.  
  288.       if ((Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  289.           (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[Y] - Triangle->P1[Y]))
  290.       {
  291.         swap = TRUE;
  292.       }
  293.  
  294.       break;
  295.  
  296.     case Y:
  297.  
  298.       if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Z] - Triangle->P1[Z]) <
  299.           (Triangle->P2[Z] - Triangle->P3[Z])*(Triangle->P2[X] - Triangle->P1[X]))
  300.       {
  301.         swap = TRUE;
  302.       }
  303.  
  304.       break;
  305.  
  306.     case Z:
  307.  
  308.       if ((Triangle->P2[X] - Triangle->P3[X])*(Triangle->P2[Y] - Triangle->P1[Y]) <
  309.           (Triangle->P2[Y] - Triangle->P3[Y])*(Triangle->P2[X] - Triangle->P1[X]))
  310.       {
  311.         swap = TRUE;
  312.       }
  313.  
  314.       break;
  315.   }
  316.  
  317.   if (swap)
  318.   {
  319.     Assign_Vector(Temp, Triangle->P2);
  320.     Assign_Vector(Triangle->P2, Triangle->P1);
  321.     Assign_Vector(Triangle->P1, Temp);
  322.  
  323.     if (Smooth)
  324.     {
  325.       Assign_Vector(Temp, ((SMOOTH_TRIANGLE *)Triangle)->N2);
  326.       Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N2, ((SMOOTH_TRIANGLE *)Triangle)->N1);
  327.       Assign_Vector(((SMOOTH_TRIANGLE *)Triangle)->N1, Temp);
  328. #ifdef ColorTrianglePatch2
  329.  
  330.       /* AP */
  331.       if(Triangle->Type & COLOR_SMOOTH_OBJECT) {
  332.       Assign_Colour(CTemp, ((SMOOTH_COLOR_TRIANGLE *)Triangle)->C2);
  333.       Assign_Colour(((SMOOTH_COLOR_TRIANGLE *)Triangle)->C2, ((SMOOTH_COLOR_TRIANGLE *)Triangle)->C1);
  334.       Assign_Colour(((SMOOTH_COLOR_TRIANGLE *)Triangle)->C1, CTemp);
  335.  
  336.  
  337.       }
  338.  
  339. #endif
  340.     }
  341.   }
  342.  
  343.   degn=TRUE;
  344.  
  345.   if (Smooth)
  346.   {
  347.     degn=compute_smooth_triangle((SMOOTH_TRIANGLE *)Triangle);
  348.   }
  349.  
  350.   /* Build the bounding information from the vertices. */
  351.  
  352.   Compute_Triangle_BBox(Triangle);
  353.  
  354.   return(degn);
  355. }
  356.  
  357.  
  358.  
  359. /*****************************************************************************
  360. *
  361. * FUNCTION
  362. *
  363. *   All_Triangle_Intersections
  364. *
  365. * INPUT
  366. *   
  367. * OUTPUT
  368. *   
  369. * RETURNS
  370. *   
  371. * AUTHOR
  372. *
  373. *   POV-Ray Team
  374. *   
  375. * DESCRIPTION
  376. *
  377. *   -
  378. *
  379. * CHANGES
  380. *
  381. *   -
  382. *
  383. ******************************************************************************/
  384.  
  385. static int All_Triangle_Intersections(OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  386. {
  387.   DBL Depth;
  388.   VECTOR IPoint;
  389.  
  390.   if (Intersect_Triangle(Ray, (TRIANGLE *)Object, &Depth))
  391.   {
  392.     VEvaluateRay(IPoint, Ray->Initial, Depth, Ray->Direction);
  393.  
  394.     if (Point_In_Clip(IPoint,Object->Clip))
  395.     {
  396.       push_entry(Depth,IPoint,Object,Depth_Stack);
  397.  
  398.       return(TRUE);
  399.     }
  400.   }
  401.  
  402.   return(FALSE);
  403. }
  404.  
  405.  
  406.  
  407. /*****************************************************************************
  408. *
  409. * FUNCTION
  410. *
  411. *   Intersect_Triangle
  412. *
  413. * INPUT
  414. *   
  415. * OUTPUT
  416. *   
  417. * RETURNS
  418. *   
  419. * AUTHOR
  420. *
  421. *   POV-Ray Team
  422. *   
  423. * DESCRIPTION
  424. *
  425. *   -
  426. *
  427. * CHANGES
  428. *
  429. *   -
  430. *
  431. ******************************************************************************/
  432.  
  433. static int Intersect_Triangle(RAY *Ray, TRIANGLE *Triangle, DBL *Depth)
  434. {
  435.   DBL NormalDotOrigin, NormalDotDirection;
  436.   DBL s, t;
  437.  
  438.   Increase_Counter(stats[Ray_Triangle_Tests]);
  439.  
  440.   if (Test_Flag(Triangle, DEGENERATE_FLAG))
  441.   {
  442.     return(FALSE);
  443.   }
  444.  
  445.   VDot(NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
  446.  
  447.   if (fabs(NormalDotDirection) < EPSILON)
  448.   {
  449.     return(FALSE);
  450.   }
  451.  
  452.   VDot(NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
  453.  
  454.   *Depth = -(Triangle->Distance + NormalDotOrigin) / NormalDotDirection;
  455.  
  456.   if ((*Depth < DEPTH_TOLERANCE) || (*Depth > Max_Distance))
  457.   {
  458.     return(FALSE);
  459.   }
  460.  
  461.   switch (Triangle->Dominant_Axis)
  462.   {
  463.     case X:
  464.  
  465.       s = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  466.       t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  467.  
  468.       if ((Triangle->P2[Y] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  469.           (Triangle->P2[Z] - t) * (Triangle->P2[Y] - Triangle->P1[Y]))
  470.       {
  471.         return(FALSE);
  472.       }
  473.  
  474.       if ((Triangle->P3[Y] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  475.           (Triangle->P3[Z] - t) * (Triangle->P3[Y] - Triangle->P2[Y]))
  476.       {
  477.         return(FALSE);
  478.       }
  479.  
  480.       if ((Triangle->P1[Y] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  481.           (Triangle->P1[Z] - t) * (Triangle->P1[Y] - Triangle->P3[Y]))
  482.       {
  483.         return(FALSE);
  484.       }
  485.  
  486.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  487.  
  488.       return(TRUE);
  489.  
  490.     case Y:
  491.  
  492.       s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  493.       t = Ray->Initial[Z] + *Depth * Ray->Direction[Z];
  494.  
  495.       if ((Triangle->P2[X] - s) * (Triangle->P2[Z] - Triangle->P1[Z]) <
  496.           (Triangle->P2[Z] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  497.       {
  498.         return(FALSE);
  499.       }
  500.  
  501.       if ((Triangle->P3[X] - s) * (Triangle->P3[Z] - Triangle->P2[Z]) <
  502.           (Triangle->P3[Z] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  503.       {
  504.         return(FALSE);
  505.       }
  506.  
  507.       if ((Triangle->P1[X] - s) * (Triangle->P1[Z] - Triangle->P3[Z]) <
  508.           (Triangle->P1[Z] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  509.       {
  510.         return(FALSE);
  511.       }
  512.  
  513.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  514.  
  515.       return(TRUE);
  516.  
  517.     case Z:
  518.  
  519.       s = Ray->Initial[X] + *Depth * Ray->Direction[X];
  520.       t = Ray->Initial[Y] + *Depth * Ray->Direction[Y];
  521.  
  522.       if ((Triangle->P2[X] - s) * (Triangle->P2[Y] - Triangle->P1[Y]) <
  523.           (Triangle->P2[Y] - t) * (Triangle->P2[X] - Triangle->P1[X]))
  524.       {
  525.         return(FALSE);
  526.       }
  527.  
  528.       if ((Triangle->P3[X] - s) * (Triangle->P3[Y] - Triangle->P2[Y]) <
  529.           (Triangle->P3[Y] - t) * (Triangle->P3[X] - Triangle->P2[X]))
  530.       {
  531.         return(FALSE);
  532.       }
  533.  
  534.       if ((Triangle->P1[X] - s) * (Triangle->P1[Y] - Triangle->P3[Y]) <
  535.           (Triangle->P1[Y] - t) * (Triangle->P1[X] - Triangle->P3[X]))
  536.       {
  537.         return(FALSE);
  538.       }
  539.  
  540.       Increase_Counter(stats[Ray_Triangle_Tests_Succeeded]);
  541.  
  542.       return(TRUE);
  543.   }
  544.  
  545.   return(FALSE);
  546. }
  547.  
  548.  
  549.  
  550. /*****************************************************************************
  551. *
  552. * FUNCTION
  553. *
  554. *   Inside_Triangle
  555. *
  556. * INPUT
  557. *   
  558. * OUTPUT
  559. *   
  560. * RETURNS
  561. *   
  562. * AUTHOR
  563. *
  564. *   POV-Ray Team
  565. *   
  566. * DESCRIPTION
  567. *
  568. *   -
  569. *
  570. * CHANGES
  571. *
  572. *   -
  573. *
  574. ******************************************************************************/
  575.  
  576. static int Inside_Triangle(VECTOR IPoint, OBJECT *Object)
  577. {
  578.   return(FALSE);
  579. }
  580.  
  581.  
  582.  
  583. /*****************************************************************************
  584. *
  585. * FUNCTION
  586. *
  587. *   Triangle_Normal
  588. *
  589. * INPUT
  590. *   
  591. * OUTPUT
  592. *   
  593. * RETURNS
  594. *   
  595. * AUTHOR
  596. *
  597. *   POV-Ray Team
  598. *   
  599. * DESCRIPTION
  600. *
  601. *   -
  602. *
  603. * CHANGES
  604. *
  605. *   -
  606. *
  607. ******************************************************************************/
  608.  
  609. static void Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  610. {
  611.   Assign_Vector(Result, ((TRIANGLE *)Object)->Normal_Vector);
  612. }
  613.  
  614.  
  615.  
  616. /*****************************************************************************
  617. *
  618. * FUNCTION
  619. *
  620. *   Smooth_Triangle_Normal
  621. *
  622. * INPUT
  623. *   
  624. * OUTPUT
  625. *   
  626. * RETURNS
  627. *   
  628. * AUTHOR
  629. *
  630. *   POV-Ray Team
  631. *   
  632. * DESCRIPTION
  633. *
  634. *   Calculate the Phong-interpolated vector within the triangle
  635. *   at the given intersection point. The math for this is a bit
  636. *   bizarre:
  637. *
  638. *      -         P1
  639. *      |        /|\ \
  640. *      |       / |Perp\
  641. *      |      /  V  \   \
  642. *      |     /   |    \   \
  643. *    u |    /____|_____PI___\
  644. *      |   /     |       \    \
  645. *      -  P2-----|--------|----P3
  646. *                Pbase    PIntersect
  647. *          |-------------------|
  648. *                         v
  649. *
  650. *   Triangle->Perp is a unit vector from P1 to Pbase. We calculate
  651. *
  652. *   u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
  653. *
  654. *   We then calculate where the line from P1 to PI intersects the line P2 to P3:
  655. *   PIntersect = (PI - P1)/u.
  656. *
  657. *   We really only need one coordinate of PIntersect.  We then calculate v as:
  658. *
  659. *        v = PIntersect[X] / (P3[X] - P2[X])
  660. *   or   v = PIntersect[Y] / (P3[Y] - P2[Y])
  661. *   or   v = PIntersect[Z] / (P3[Z] - P2[Z])
  662. *
  663. *   depending on which calculation will give us the best answers.
  664. *
  665. *   Once we have u and v, we can perform the normal interpolation as:
  666. *
  667. *     NTemp1 = N1 + u(N2 - N1);
  668. *     NTemp2 = N1 + u(N3 - N1);
  669. *     Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
  670. *
  671. *   As always, any values which are constant for the triangle are cached
  672. *   in the triangle.
  673. *
  674. * CHANGES
  675. *
  676. *   -
  677. *
  678. ******************************************************************************/
  679.  
  680. static void Smooth_Triangle_Normal(VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  681. {
  682.   int Axis;
  683.   DBL u, v;
  684.   VECTOR PIMinusP1;
  685.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  686.  
  687.   VSub(PIMinusP1, Inter->IPoint, Triangle->P1);
  688.  
  689.   VDot(u, PIMinusP1, Triangle->Perp);
  690.  
  691.   if (u < EPSILON)
  692.   {
  693.     Assign_Vector(Result, Triangle->N1);
  694.  
  695.     return;
  696.   }
  697.  
  698.   Axis = Triangle->vAxis;
  699.  
  700.   v = (PIMinusP1[Axis] / u + Triangle->P1[Axis] - Triangle->P2[Axis]) / (Triangle->P3[Axis] - Triangle->P2[Axis]);
  701.  
  702.   /* This is faster. [DB 8/94] */
  703.  
  704.   Result[X] = Triangle->N1[X] + u * (Triangle->N2[X] - Triangle->N1[X] + v * (Triangle->N3[X] - Triangle->N2[X]));
  705.   Result[Y] = Triangle->N1[Y] + u * (Triangle->N2[Y] - Triangle->N1[Y] + v * (Triangle->N3[Y] - Triangle->N2[Y]));
  706.   Result[Z] = Triangle->N1[Z] + u * (Triangle->N2[Z] - Triangle->N1[Z] + v * (Triangle->N3[Z] - Triangle->N2[Z]));
  707.  
  708.   VNormalize(Result, Result);
  709. }
  710.  
  711.  
  712.  
  713. /*****************************************************************************
  714. *
  715. * FUNCTION
  716. *
  717. *   Translate_Triangle
  718. *
  719. * INPUT
  720. *   
  721. * OUTPUT
  722. *   
  723. * RETURNS
  724. *   
  725. * AUTHOR
  726. *
  727. *   POV-Ray Team
  728. *   
  729. * DESCRIPTION
  730. *
  731. *   -
  732. *
  733. * CHANGES
  734. *
  735. *   -
  736. *
  737. ******************************************************************************/
  738.  
  739. static void Translate_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  740. {
  741.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  742.   /*VECTOR Translation;*/
  743.  
  744.   if (!Test_Flag(Triangle, DEGENERATE_FLAG))
  745.   {
  746. /* BEG ROSE
  747.    this is useless, because Compute_Triangle recalculates this anyway:
  748.     VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  749.  
  750.     Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  751.    END ROSE */
  752.  
  753.     VAddEq(Triangle->P1, Vector);
  754.     VAddEq(Triangle->P2, Vector);
  755.     VAddEq(Triangle->P3, Vector);
  756.  
  757.     Compute_Triangle(Triangle, FALSE);
  758.   }
  759. }
  760.  
  761.  
  762.  
  763. /*****************************************************************************
  764. *
  765. * FUNCTION
  766. *
  767. *   Rotate_Triangle
  768. *
  769. * INPUT
  770. *
  771. * OUTPUT
  772. *
  773. * RETURNS
  774. *
  775. * AUTHOR
  776. *
  777. *   POV-Ray Team
  778. *
  779. * DESCRIPTION
  780. *
  781. *   -
  782. *
  783. * CHANGES
  784. *
  785. *   -
  786. *
  787. ******************************************************************************/
  788.  
  789. static void Rotate_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  790. {
  791.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  792.   {
  793.     Transform_Triangle(Object, Trans);
  794.   }
  795. }
  796.  
  797.  
  798.  
  799. /*****************************************************************************
  800. *
  801. * FUNCTION
  802. *
  803. *   Scale_Triangle
  804. *
  805. * INPUT
  806. *
  807. * OUTPUT
  808. *
  809. * RETURNS
  810. *
  811. * AUTHOR
  812. *
  813. *   POV-Ray Team
  814. *
  815. * DESCRIPTION
  816. *
  817. *   -
  818. *
  819. * CHANGES
  820. *
  821. *   -
  822. *
  823. ******************************************************************************/
  824.  
  825. static void Scale_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  826. {
  827.   /*DBL Length;*/
  828.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  829.  
  830.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  831.   {
  832. /*  BEG ROSE
  833.     this is useless, because Compute_Triangle recalculates this anyway:
  834.     Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  835.     Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  836.     Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  837.  
  838.     VLength(Length, Triangle->Normal_Vector);
  839.  
  840.     VInverseScaleEq(Triangle->Normal_Vector, Length);
  841.  
  842.     Triangle->Distance /= Length;
  843.     END ROSE */
  844.  
  845.     VEvaluateEq(Triangle->P1, Vector);
  846.     VEvaluateEq(Triangle->P2, Vector);
  847.     VEvaluateEq(Triangle->P3, Vector);
  848.  
  849.     Compute_Triangle(Triangle, FALSE);
  850.   }
  851. }
  852.  
  853.  
  854.  
  855. /*****************************************************************************
  856. *
  857. * FUNCTION
  858. *
  859. *   Transfrom_Triangle
  860. *
  861. * INPUT
  862. *   
  863. * OUTPUT
  864. *   
  865. * RETURNS
  866. *
  867. * AUTHOR
  868. *
  869. *   POV-Ray Team
  870. *
  871. * DESCRIPTION
  872. *
  873. *   -
  874. *
  875. * CHANGES
  876. *
  877. *   -
  878. *
  879. ******************************************************************************/
  880.  
  881. static void Transform_Triangle(OBJECT *Object, TRANSFORM *Trans)
  882. {
  883.   TRIANGLE *Triangle = (TRIANGLE *)Object;
  884.  
  885.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  886.   {
  887. /*  ROSE BEG
  888.     this is useless, because Compute_Triangle recalculates this anyway:
  889.     MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  890.     END ROSE */
  891.     MTransPoint(Triangle->P1, Triangle->P1, Trans);
  892.     MTransPoint(Triangle->P2, Triangle->P2, Trans);
  893.     MTransPoint(Triangle->P3, Triangle->P3, Trans);
  894.  
  895.     Compute_Triangle(Triangle, FALSE);
  896.   }
  897. }
  898.  
  899.  
  900.  
  901. /*****************************************************************************
  902. *
  903. * FUNCTION
  904. *
  905. *   Invert_Triangle
  906. *
  907. * INPUT
  908. *   
  909. * OUTPUT
  910. *   
  911. * RETURNS
  912. *   
  913. * AUTHOR
  914. *
  915. *   POV-Ray Team
  916. *   
  917. * DESCRIPTION
  918. *
  919. *   -
  920. *
  921. * CHANGES
  922. *
  923. *   -
  924. *
  925. ******************************************************************************/
  926.  
  927. static void Invert_Triangle(OBJECT *Object)
  928. {
  929. }
  930.  
  931.  
  932.  
  933. /*****************************************************************************
  934. *
  935. * FUNCTION
  936. *
  937. *   Create_Triangle
  938. *
  939. * INPUT
  940. *   
  941. * OUTPUT
  942. *   
  943. * RETURNS
  944. *   
  945. * AUTHOR
  946. *
  947. *   POV-Ray Team
  948. *   
  949. * DESCRIPTION
  950. *
  951. *   -
  952. *
  953. * CHANGES
  954. *
  955. *   -
  956. *
  957. ******************************************************************************/
  958.  
  959. TRIANGLE *Create_Triangle()
  960. {
  961.   TRIANGLE *New;
  962.  
  963.   New = (TRIANGLE *)POV_MALLOC(sizeof(TRIANGLE), "triangle");
  964.  
  965.   INIT_OBJECT_FIELDS(New,TRIANGLE_OBJECT,&Triangle_Methods)
  966.  
  967.   Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  968.  
  969.   New->Distance = 0.0;
  970.  
  971. /* BEG ROSE
  972.    this three points doesn't belong to the normal vector, created above:
  973.    END ROSE */
  974.   Make_Vector(New->P1, 0.0, 0.0, 0.0);
  975.   Make_Vector(New->P2, 1.0, 0.0, 0.0);
  976.   Make_Vector(New->P3, 0.0, 1.0, 0.0);
  977.  
  978.   /*
  979.    * NOTE: Dominant_Axis is computed when Parse_Triangle calls
  980.    * Compute_Triangle. vAxis is used only for smooth triangles.
  981.    */
  982.  
  983.   return(New);
  984. }
  985.  
  986.  
  987.  
  988. /*****************************************************************************
  989. *
  990. * FUNCTION
  991. *
  992. *   Copy_Triangle
  993. *
  994. * INPUT
  995. *   
  996. * OUTPUT
  997. *   
  998. * RETURNS
  999. *   
  1000. * AUTHOR
  1001. *
  1002. *   POV-Ray Team
  1003. *   
  1004. * DESCRIPTION
  1005. *
  1006. *   -
  1007. *
  1008. * CHANGES
  1009. *
  1010. *   -
  1011. *
  1012. ******************************************************************************/
  1013.  
  1014. static TRIANGLE *Copy_Triangle(OBJECT *Object)
  1015. {
  1016.   TRIANGLE *New;
  1017.  
  1018.   New = Create_Triangle();
  1019.  
  1020.   *New = *((TRIANGLE *)Object);
  1021.  
  1022.   return(New);
  1023. }
  1024.  
  1025.  
  1026.  
  1027. /*****************************************************************************
  1028. *
  1029. * FUNCTION
  1030. *
  1031. *   Destroy_Triangle
  1032. *
  1033. * INPUT
  1034. *   
  1035. * OUTPUT
  1036. *   
  1037. * RETURNS
  1038. *   
  1039. * AUTHOR
  1040. *
  1041. *   POV-Ray Team
  1042. *   
  1043. * DESCRIPTION
  1044. *
  1045. *   -
  1046. *
  1047. * CHANGES
  1048. *
  1049. *   -
  1050. *
  1051. ******************************************************************************/
  1052.  
  1053. static void Destroy_Triangle(OBJECT *Object)
  1054. {
  1055.   POV_FREE (Object);
  1056. }
  1057.  
  1058.  
  1059.  
  1060. /*****************************************************************************
  1061. *
  1062. * FUNCTION
  1063. *
  1064. *   Translate_Smooth_Triangle
  1065. *
  1066. * INPUT
  1067. *   
  1068. * OUTPUT
  1069. *   
  1070. * RETURNS
  1071. *   
  1072. * AUTHOR
  1073. *
  1074. *   POV-Ray Team
  1075. *   
  1076. * DESCRIPTION
  1077. *
  1078. *   -
  1079. *
  1080. * CHANGES
  1081. *
  1082. *   -
  1083. *
  1084. ******************************************************************************/
  1085.  
  1086. static void Translate_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  1087. {
  1088.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1089.   /*VECTOR Translation;*/
  1090.  
  1091.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1092.   {
  1093.  /*  BEG ROSE
  1094.     this is useless, because Compute_Triange recalculates this anyway:
  1095.    VEvaluate(Translation, Triangle->Normal_Vector, Vector);
  1096.  
  1097.     Triangle->Distance -= Translation[X] + Translation[Y] + Translation[Z];
  1098.     END ROSE */
  1099.  
  1100.     VAddEq(Triangle->P1, Vector);
  1101.     VAddEq(Triangle->P2, Vector);
  1102.     VAddEq(Triangle->P3, Vector);
  1103.  
  1104.     Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  1105.   }
  1106. }
  1107.  
  1108.  
  1109.  
  1110. /*****************************************************************************
  1111. *
  1112. * FUNCTION
  1113. *
  1114. *   Rotate_Smooth_Triangle
  1115. *
  1116. * INPUT
  1117. *   
  1118. * OUTPUT
  1119. *   
  1120. * RETURNS
  1121. *   
  1122. * AUTHOR
  1123. *
  1124. *   POV-Ray Team
  1125. *
  1126. * DESCRIPTION
  1127. *
  1128. *   -
  1129. *
  1130. * CHANGES
  1131. *
  1132. *   -
  1133. *
  1134. ******************************************************************************/
  1135.  
  1136. static void Rotate_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  1137. {
  1138.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1139.   {
  1140.     Transform_Smooth_Triangle(Object, Trans);
  1141.   }
  1142. }
  1143.  
  1144.  
  1145.  
  1146. /*****************************************************************************
  1147. *
  1148. * FUNCTION
  1149. *
  1150. *   Scale_Smooth_Triangle
  1151. *
  1152. * INPUT
  1153. *   
  1154. * OUTPUT
  1155. *   
  1156. * RETURNS
  1157. *   
  1158. * AUTHOR
  1159. *
  1160. *   POV-Ray Team
  1161. *   
  1162. * DESCRIPTION
  1163. *
  1164. *   -
  1165. *
  1166. * CHANGES
  1167. *
  1168. *   -
  1169. *
  1170. ******************************************************************************/
  1171.  
  1172. static void Scale_Smooth_Triangle(OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  1173. {
  1174.   DBL Length;
  1175.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1176.  
  1177.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1178.   {
  1179. /*  BEG ROSE
  1180.     this is useless, because Compute_Triange recalculates this anyway:
  1181.     Triangle->Normal_Vector[X] = Triangle->Normal_Vector[X] / Vector[X];
  1182.     Triangle->Normal_Vector[Y] = Triangle->Normal_Vector[Y] / Vector[Y];
  1183.     Triangle->Normal_Vector[Z] = Triangle->Normal_Vector[Z] / Vector[Z];
  1184.  
  1185.     VLength(Length, Triangle->Normal_Vector);
  1186.     VScaleEq(Triangle->Normal_Vector, 1.0 / Length);
  1187.     Triangle->Distance /= Length;
  1188.     END ROSE */
  1189.  
  1190.     VEvaluateEq(Triangle->P1, Vector);
  1191.     VEvaluateEq(Triangle->P2, Vector);
  1192.     VEvaluateEq(Triangle->P3, Vector);
  1193.  
  1194. /*  BEG ROSE
  1195.     The normal vectors also have to be transformed (BUG fix): */
  1196.     Triangle->N1[X] /= Vector[X];
  1197.     Triangle->N1[Y] /= Vector[Y];
  1198.     Triangle->N1[Z] /= Vector[Z];
  1199.     VLength(Length,Triangle->N1);
  1200.     VScaleEq(Triangle->N1,1.0/Length);
  1201.     Triangle->N2[X] /= Vector[X];
  1202.     Triangle->N2[Y] /= Vector[Y];
  1203.     Triangle->N2[Z] /= Vector[Z];
  1204.     VLength(Length,Triangle->N2);
  1205.     VScaleEq(Triangle->N2,1.0/Length);
  1206.     Triangle->N3[X] /= Vector[X];
  1207.     Triangle->N3[Y] /= Vector[Y];
  1208.     Triangle->N3[Z] /= Vector[Z];
  1209.     VLength(Length,Triangle->N3);
  1210.     VScaleEq(Triangle->N3,1.0/Length);
  1211. /*  END ROSE */
  1212.  
  1213.     Compute_Triangle((TRIANGLE *)Triangle,TRUE);
  1214.   }
  1215. }
  1216.  
  1217.  
  1218.  
  1219. /*****************************************************************************
  1220. *
  1221. * FUNCTION
  1222. *
  1223. *   Transform_Smooth_Triangle
  1224. *
  1225. * INPUT
  1226. *   
  1227. * OUTPUT
  1228. *   
  1229. * RETURNS
  1230. *   
  1231. * AUTHOR
  1232. *
  1233. *   POV-Ray Team
  1234. *   
  1235. * DESCRIPTION
  1236. *
  1237. *   -
  1238. *
  1239. * CHANGES
  1240. *
  1241. *   -
  1242. *
  1243. ******************************************************************************/
  1244.  
  1245. static void Transform_Smooth_Triangle(OBJECT *Object, TRANSFORM *Trans)
  1246. {
  1247.   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *)Object;
  1248.  
  1249.   if (!Test_Flag(Object, DEGENERATE_FLAG))
  1250.   {
  1251. /*  BEG ROSE
  1252.     This is useless, because Compute_Triange recalculates this anyway:
  1253.     MTransPoint(Triangle->Normal_Vector,Triangle->Normal_Vector, Trans);
  1254.     END ROSE */
  1255.     MTransPoint(Triangle->P1, Triangle->P1, Trans);
  1256.     MTransPoint(Triangle->P2, Triangle->P2, Trans);
  1257.     MTransPoint(Triangle->P3, Triangle->P3, Trans);
  1258. /*  BEG ROSE
  1259.     This code is definitely wrong:
  1260.     MTransPoint(Triangle->N1, Triangle->N1, Trans);
  1261.     MTransPoint(Triangle->N2, Triangle->N2, Trans);
  1262.     MTransPoint(Triangle->N3, Triangle->N3, Trans);
  1263.     Bug fix for this: */
  1264.     MTransNormal(Triangle->N1,Triangle->N1,Trans);
  1265.     MTransNormal(Triangle->N2,Triangle->N2,Trans);
  1266.     MTransNormal(Triangle->N3,Triangle->N3,Trans);
  1267. /*  END ROSE */
  1268.  
  1269.     Compute_Triangle((TRIANGLE *)Triangle, TRUE);
  1270.   }
  1271. }
  1272.  
  1273.  
  1274.  
  1275. /*****************************************************************************
  1276. *
  1277. * FUNCTION
  1278. *
  1279. *   Invert_Smooth_Triangle
  1280. *
  1281. * INPUT
  1282. *   
  1283. * OUTPUT
  1284. *   
  1285. * RETURNS
  1286. *   
  1287. * AUTHOR
  1288. *
  1289. *   POV-Ray Team
  1290. *   
  1291. * DESCRIPTION
  1292. *
  1293. *   -
  1294. *
  1295. * CHANGES
  1296. *
  1297. *   -
  1298. *
  1299. ******************************************************************************/
  1300.  
  1301. static void Invert_Smooth_Triangle(OBJECT *Object)
  1302. {
  1303. }
  1304.  
  1305.  
  1306.  
  1307. /*****************************************************************************
  1308. *
  1309. * FUNCTION
  1310. *
  1311. *   Create_Smooth_Triangle
  1312. *
  1313. * INPUT
  1314. *   
  1315. * OUTPUT
  1316. *   
  1317. * RETURNS
  1318. *   
  1319. * AUTHOR
  1320. *
  1321. *   POV-Ray Team
  1322. *   
  1323. * DESCRIPTION
  1324. *
  1325. *   -
  1326. *
  1327. * CHANGES
  1328. *
  1329. *   -
  1330. *
  1331. ******************************************************************************/
  1332.  
  1333. SMOOTH_TRIANGLE *Create_Smooth_Triangle()
  1334. {
  1335.   SMOOTH_TRIANGLE *New;
  1336.  
  1337.   New = (SMOOTH_TRIANGLE *)POV_MALLOC(sizeof(SMOOTH_TRIANGLE), "smooth triangle");
  1338.  
  1339.   INIT_OBJECT_FIELDS(New,SMOOTH_TRIANGLE_OBJECT,&Smooth_Triangle_Methods)
  1340.  
  1341.   Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  1342.  
  1343.   New->Distance = 0.0;
  1344.  
  1345. /* BEG ROSE
  1346.    The normal vectors are not matching the triangle, given by the points:
  1347.    END ROSE */
  1348.   Make_Vector(New->P1, 0.0, 0.0, 0.0);
  1349.   Make_Vector(New->P2, 1.0, 0.0, 0.0);
  1350.   Make_Vector(New->P3, 0.0, 1.0, 0.0);
  1351.   Make_Vector(New->N1, 0.0, 1.0, 0.0);
  1352.   Make_Vector(New->N2, 0.0, 1.0, 0.0);
  1353.   Make_Vector(New->N3, 0.0, 1.0, 0.0);
  1354.  
  1355.   /*
  1356.    * NOTE: Dominant_Axis and vAxis are computed when
  1357.    * Parse_Triangle calls Compute_Triangle.
  1358.    */
  1359.  
  1360.   return(New);
  1361. }
  1362.  
  1363.  
  1364.  
  1365. /*****************************************************************************
  1366. *
  1367. * FUNCTION
  1368. *
  1369. *   Copy_Smooth_Triangle
  1370. *
  1371. * INPUT
  1372. *   
  1373. * OUTPUT
  1374. *   
  1375. * RETURNS
  1376. *   
  1377. * AUTHOR
  1378. *
  1379. *   POV-Ray Team
  1380. *   
  1381. * DESCRIPTION
  1382. *
  1383. *   -
  1384. *
  1385. * CHANGES
  1386. *
  1387. *   -
  1388. *
  1389. ******************************************************************************/
  1390.  
  1391. static SMOOTH_TRIANGLE *Copy_Smooth_Triangle(OBJECT *Object)
  1392. {
  1393.   SMOOTH_TRIANGLE *New;
  1394.  
  1395.   New = Create_Smooth_Triangle();
  1396.  
  1397.   *New = *((SMOOTH_TRIANGLE *)Object);
  1398.  
  1399.   return(New);
  1400. }
  1401.  
  1402.  
  1403.  
  1404. /*****************************************************************************
  1405. *
  1406. * FUNCTION
  1407. *
  1408. *   Compute_Triangle_BBox
  1409. *
  1410. * INPUT
  1411. *
  1412. *   Triangle - Triangle
  1413. *   
  1414. * OUTPUT
  1415. *
  1416. *   Triangle
  1417. *   
  1418. * RETURNS
  1419. *   
  1420. * AUTHOR
  1421. *
  1422. *   Dieter Bayer
  1423. *   
  1424. * DESCRIPTION
  1425. *
  1426. *   Calculate the bounding box of a triangle.
  1427. *
  1428. * CHANGES
  1429. *
  1430. *   Aug 1994 : Creation.
  1431. *
  1432. ******************************************************************************/
  1433.  
  1434. void Compute_Triangle_BBox(TRIANGLE *Triangle)
  1435. {
  1436.   VECTOR Min, Max, Epsilon;
  1437.  
  1438.   Make_Vector(Epsilon, EPSILON, EPSILON, EPSILON);
  1439.  
  1440.   Min[X] = min3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1441.   Min[Y] = min3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1442.   Min[Z] = min3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1443.  
  1444.   Max[X] = max3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  1445.   Max[Y] = max3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  1446.   Max[Z] = max3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);
  1447.  
  1448.   VSubEq(Min, Epsilon);
  1449.   VAddEq(Max, Epsilon);
  1450.  
  1451.   Make_BBox_from_min_max(Triangle->BBox, Min, Max);
  1452. }
  1453.  
  1454.  
  1455. #ifdef ColorTrianglePatch2
  1456. /*****************************************************************************
  1457. *
  1458. * FUNCTION
  1459. *
  1460. *   Create_Smooth_Color_Triangle
  1461. *
  1462. * INPUT
  1463. *   
  1464. * OUTPUT
  1465. *   
  1466. * RETURNS
  1467. *   
  1468. * AUTHOR
  1469. *
  1470. *   AP
  1471. *   
  1472. * DESCRIPTION
  1473. *
  1474. *   -
  1475. *
  1476. * CHANGES
  1477. *
  1478. *   -
  1479. *
  1480. ******************************************************************************/
  1481.  
  1482. SMOOTH_COLOR_TRIANGLE *Create_Smooth_Color_Triangle() /* AP */
  1483. {
  1484.   SMOOTH_COLOR_TRIANGLE *New;
  1485.  
  1486.   New = (SMOOTH_COLOR_TRIANGLE *)POV_MALLOC(sizeof(SMOOTH_COLOR_TRIANGLE), "smooth color triangle");
  1487.  
  1488.   INIT_OBJECT_FIELDS(New,SMOOTH_COLOR_TRIANGLE_OBJECT,&Smooth_Color_Triangle_Methods)
  1489.  
  1490.   Make_Vector(New->Normal_Vector, 0.0, 1.0, 0.0);
  1491.  
  1492.   New->Distance = 0.0;
  1493.  
  1494.   New->magic=31415926;
  1495.  
  1496.   Make_Vector(New->P1, 0.0, 0.0, 0.0);
  1497.   Make_Vector(New->P2, 1.0, 0.0, 0.0);
  1498.   Make_Vector(New->P3, 0.0, 1.0, 0.0);
  1499.   Make_Vector(New->N1, 0.0, 1.0, 0.0);
  1500.   Make_Vector(New->N2, 0.0, 1.0, 0.0);
  1501.   Make_Vector(New->N3, 0.0, 1.0, 0.0);
  1502.   Make_Colour(New->C1, 0.0, 0.0, 0.0);
  1503.   Make_Colour(New->C2, 0.0, 0.0, 0.0);
  1504.   Make_Colour(New->C3, 0.0, 0.0, 0.0);
  1505.  
  1506.   return(New);
  1507. }
  1508.  
  1509. /* AP */
  1510.  
  1511. /*
  1512.   
  1513.   corners A B C
  1514.   point inside triangle M
  1515.   Q is intersection of line AM with line BC
  1516.  
  1517.   1 <= r  Q = A + r(M-A)
  1518.   
  1519.  
  1520.   0 <= s <= 1  Q = B + s(C-B)
  1521.  
  1522.   0 <= t <=1   M = A + t(Q-A)
  1523.  
  1524.   ra+sb=c
  1525.   rd+se=f
  1526.   rg+sh=i
  1527.  
  1528.  */
  1529.  
  1530. int Calculate_Smooth_Color(COLOUR Col, VECTOR IPoint, INTERSECTION *Intersection)
  1531. {
  1532.   SMOOTH_COLOR_TRIANGLE *tri=(SMOOTH_COLOR_TRIANGLE *)Intersection->Object;
  1533.   /*
  1534.   fprintf(stderr,"%d\n",tri->magic);
  1535.   */
  1536.   return Interpolate_Smooth_Color(Col, IPoint,
  1537.                   tri->P1, tri->P2, tri->P3,
  1538.                   tri->C1, tri->C2, tri->C3);
  1539.  
  1540. }
  1541.  
  1542. int Interpolate_Smooth_Color(COLOUR Col, VECTOR IPoint, VECTOR P1, VECTOR P2, VECTOR P3, COLOUR C1, COLOUR C2, COLOUR C3)
  1543. {
  1544.   int i;
  1545.  
  1546.   DBL t1,t2,t3,tsum;
  1547.  
  1548.   t1=Calculate_Smooth_T(IPoint, P1, P2, P3);
  1549.   t2=Calculate_Smooth_T(IPoint, P2, P3, P1);
  1550.   t3=Calculate_Smooth_T(IPoint, P3, P1, P2);
  1551.  
  1552.   /*
  1553.   fprintf(stderr,"<%.3f %.3f %.3f> <%.3f %.3f %.3f> <%.3f %.3f %.3f>\n",
  1554.       C1[0],C1[1],C1[2],
  1555.       C2[0],C2[1],C2[2],
  1556.       C3[0],C3[1],C3[2]);
  1557.   */
  1558.  
  1559.   /*
  1560.   fprintf(stderr,"%.3f %.3f %.3f\n",t1,t2,t3);
  1561.   Col[0]=Col[1]=Col[2]=Col[3]=Col[4]=0.0;
  1562.   */
  1563.  
  1564.   tsum=(1.0-t1)+(1.0-t2)+(1.0-t3);
  1565.  
  1566.   for(i=0;i<5;i++)
  1567.     Col[i]=((1.0-t1)*C1[i]+(1.0-t2)*C2[i]+(1.0-t3)*C3[i])/tsum;
  1568.   
  1569.  
  1570.   /*
  1571.   CInt[RED]=(1.0-s)*C2[RED]+s*C3[RED];
  1572.   CInt[GREEN]=(1.0-s)*C2[GREEN]+s*C3[GREEN];
  1573.   CInt[BLUE]=(1.0-s)*C2[BLUE]+s*C3[BLUE];
  1574.   CInt[3]=(1.0-s)*C2[3]+s*C3[3];
  1575.   CInt[4]=(1.0-s)*C2[4]+s*C3[4];
  1576.  
  1577.   Col[RED]=(1.0-t)*C1[RED]+t*CInt[RED];
  1578.   Col[GREEN]=(1.0-t)*C1[GREEN]+t*CInt[GREEN];
  1579.   Col[BLUE]=(1.0-t)*C1[BLUE]+t*CInt[BLUE];
  1580.   Col[3]=(1.0-t)*C1[3]+t*CInt[3];
  1581.   Col[4]=(1.0-t)*C1[4]+t*CInt[4];
  1582.   */
  1583.  
  1584.  
  1585.   /*
  1586.   fprintf(stderr,"%.4f %.4f <%.3f %.3f %.3f>\n",s,t,Col[0],Col[1],Col[2]);
  1587.   */
  1588.   
  1589.   return TRUE;
  1590. }
  1591. #endif
  1592.  
  1593. #ifdef ColorTrianglePatch
  1594. DBL Calculate_Smooth_T(VECTOR IPoint, VECTOR P1, VECTOR P2, VECTOR P3)
  1595. {
  1596.   DBL a,b,c,d,e,f,g,h,i;
  1597.   DBL dm1,dm2,dm3,r,s,t;
  1598.   VECTOR Q;
  1599.  
  1600.   a=IPoint[0]-P1[0];
  1601.   b=P2[0]-P3[0];
  1602.   c=P2[0]-P1[0];
  1603.  
  1604.   d=IPoint[1]-P1[1];
  1605.   e=P2[1]-P3[1];
  1606.   f=P2[1]-P1[1];
  1607.  
  1608.   g=IPoint[2]-P1[2];
  1609.   h=P2[2]-P3[2];
  1610.   i=P2[2]-P1[2];
  1611.  
  1612.   dm1=a*e-d*b;
  1613.   dm2=a*h-g*b;
  1614.   dm3=d*h-g*e;
  1615.  
  1616.   if(dm1*dm1<EPSILON) {
  1617.     if(dm2*dm2<EPSILON) {
  1618.       if(dm3*dm3 < EPSILON) {
  1619.     fprintf(stderr,"all determinants too small\n");
  1620.     return FALSE;
  1621.       } else {
  1622.     /* use dm3 */
  1623.     r=(f*h-i*e)/dm3;
  1624.     s=(d*i-g*f)/dm3;
  1625.       }  
  1626.     } else {
  1627.       /* use dm2 */
  1628.       r=(c*h-b*i)/dm2;
  1629.       s=(a*i-g*c)/dm2;
  1630.     }
  1631.   } else {
  1632.     /* use dm1 */
  1633.     r=(c*e-f*b)/dm1;
  1634.     s=(a*f-d*c)/dm1;
  1635.   }
  1636.  
  1637.  
  1638.   Q[0]=P2[0]+s*(P3[0]-P2[0]);
  1639.   Q[1]=P2[1]+s*(P3[1]-P2[1]);
  1640.   Q[2]=P2[2]+s*(P3[2]-P2[2]);
  1641.  
  1642.   /*
  1643.     t=(M-A)/(Q-A)
  1644.    */
  1645.  
  1646.   a=Q[0]-P1[0];
  1647.   b=Q[1]-P1[1];
  1648.   c=Q[2]-P1[2];
  1649.   
  1650.   if(a*a<EPSILON) {
  1651.     if(b*b<EPSILON) {
  1652.       if(c*c<EPSILON) {
  1653.     t=0;
  1654.       } else {
  1655.     t=(IPoint[2]-P1[2])/c;
  1656.       }
  1657.     } else {
  1658.     t=(IPoint[1]-P1[1])/b;
  1659.     }
  1660.   } else {
  1661.     t=(IPoint[0]-P1[0])/a;
  1662.   }
  1663.  
  1664.   return t;
  1665. }
  1666. #endif
  1667.