home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / povsrc31.zip / point.c < prev    next >
C/C++ Source or Header  |  2001-01-14  |  18KB  |  900 lines

  1. /****************************************************************************
  2. *                point.c
  3. *
  4. *  This module implements the point & spot light source primitive.
  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 "vector.h"
  26. #include "povproto.h"
  27. #include "point.h"
  28. #include "matrices.h"
  29. #include "objects.h"
  30. #include "povray.h"
  31. /* NK phmap - for Copy_Blend_Map*/
  32. #include "colour.h"
  33. /* NK ---- */
  34.  
  35.  
  36. /*****************************************************************************
  37. * Local preprocessor defines
  38. ******************************************************************************/
  39.  
  40.  
  41. /*****************************************************************************
  42. * Local typedefs
  43. ******************************************************************************/
  44.  
  45.  
  46.  
  47. /*****************************************************************************
  48. * Static functions
  49. ******************************************************************************/
  50.  
  51. static DBL cubic_spline ( DBL low,DBL high,DBL pos);
  52. static int  All_Light_Source_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack);
  53. static int  Inside_Light_Source (VECTOR point, OBJECT *Object);
  54. static void Light_Source_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter);
  55. static void Light_Source_UVCoord (UV_VECT Result, OBJECT *Object, INTERSECTION *Inter);
  56. static void Translate_Light_Source (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  57. static void Rotate_Light_Source (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  58. static void Scale_Light_Source (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans);
  59. static void Transform_Light_Source (OBJECT *Object, TRANSFORM *Trans);
  60. static void Invert_Light_Source (OBJECT *Object);
  61. static LIGHT_SOURCE *Copy_Light_Source (OBJECT *Object);
  62. static void Destroy_Light_Source (OBJECT *Object);
  63.  
  64. /*****************************************************************************
  65. * Local variables
  66. ******************************************************************************/
  67.  
  68. static METHODS Light_Source_Methods =
  69. {
  70.   All_Light_Source_Intersections,
  71.   Inside_Light_Source, Light_Source_Normal, Light_Source_UVCoord,
  72.   (COPY_METHOD)Copy_Light_Source,
  73.   Translate_Light_Source, Rotate_Light_Source,
  74.   Scale_Light_Source, Transform_Light_Source, Invert_Light_Source,
  75.   Destroy_Light_Source
  76. };
  77.  
  78.  
  79.  
  80.  
  81.  
  82. /*****************************************************************************
  83. *
  84. * FUNCTION
  85. *
  86. *   All_Light_Source_Intersections
  87. *
  88. * INPUT
  89. *   
  90. * OUTPUT
  91. *   
  92. * RETURNS
  93. *   
  94. * AUTHOR
  95. *
  96. *   POV-Ray Team
  97. *   
  98. * DESCRIPTION
  99. *
  100. *   -
  101. *
  102. * CHANGES
  103. *
  104. *   -
  105. *
  106. ******************************************************************************/
  107.  
  108. static int All_Light_Source_Intersections (OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack)
  109. {
  110.   if (((LIGHT_SOURCE *)Object)->Children != NULL)
  111.   {
  112.     if (Ray_In_Bound (Ray, ((LIGHT_SOURCE *)Object)->Children->Bound))
  113.     {
  114.       if (All_Intersections (((LIGHT_SOURCE *)Object)->Children, Ray, Depth_Stack))
  115.       {
  116.         return(TRUE);
  117.       }
  118.     }
  119.   }
  120.  
  121.   return(FALSE);
  122. }
  123.  
  124.  
  125.  
  126. /*****************************************************************************
  127. *
  128. * FUNCTION
  129. *
  130. *   Inside_Light_Source
  131. *
  132. * INPUT
  133. *   
  134. * OUTPUT
  135. *   
  136. * RETURNS
  137. *   
  138. * AUTHOR
  139. *
  140. *   POV-Ray Team
  141. *   
  142. * DESCRIPTION
  143. *
  144. *   -
  145. *
  146. * CHANGES
  147. *
  148. *   -
  149. *
  150. ******************************************************************************/
  151.  
  152. static int Inside_Light_Source (VECTOR IPoint, OBJECT *Object)
  153. {
  154.   if (((LIGHT_SOURCE *)Object)->Children != NULL)
  155.   {
  156.     if (Inside_Object (IPoint, ((LIGHT_SOURCE *)Object)->Children))
  157.     {
  158.       return (TRUE);
  159.     }
  160.   }
  161.  
  162.   return (FALSE);
  163. }
  164.  
  165.  
  166.  
  167. /*****************************************************************************
  168. *
  169. * FUNCTION
  170. *
  171. *   Light_Source_Normal
  172. *
  173. * INPUT
  174. *   
  175. * OUTPUT
  176. *   
  177. * RETURNS
  178. *   
  179. * AUTHOR
  180. *
  181. *   POV-Ray Team
  182. *   
  183. * DESCRIPTION
  184. *
  185. *   -
  186. *
  187. * CHANGES
  188. *
  189. *   -
  190. *
  191. ******************************************************************************/
  192.  
  193. static void Light_Source_Normal (VECTOR Result, OBJECT *Object, INTERSECTION *Inter)
  194. {
  195.   if (((LIGHT_SOURCE *)Object)->Children != NULL)
  196.   {
  197.     Normal (Result, ((LIGHT_SOURCE *)Object)->Children,Inter);
  198.   }
  199. }
  200.  
  201.  
  202.  
  203. /*****************************************************************************
  204. *
  205. * FUNCTION
  206. *
  207. *   Translate_Light_Source
  208. *
  209. * INPUT
  210. *   
  211. * OUTPUT
  212. *   
  213. * RETURNS
  214. *   
  215. * AUTHOR
  216. *
  217. *   POV-Ray Team
  218. *   
  219. * DESCRIPTION
  220. *
  221. *   -
  222. *
  223. * CHANGES
  224. *
  225. *   -
  226. *
  227. ******************************************************************************/
  228.  
  229. static void Translate_Light_Source (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  230. {
  231.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  232.  
  233.   VAddEq (Light->Center, Vector);
  234.   VAddEq (Light->Points_At, Vector);
  235.  
  236.   if (Light->Children != NULL)
  237.   {
  238.     Translate_Object (Light->Children, Vector, Trans);
  239.   }
  240. }
  241.  
  242.  
  243.  
  244. /*****************************************************************************
  245. *
  246. * FUNCTION
  247. *
  248. *   Rotate_Light_Source
  249. *
  250. * INPUT
  251. *   
  252. * OUTPUT
  253. *   
  254. * RETURNS
  255. *   
  256. * AUTHOR
  257. *
  258. *   POV-Ray Team
  259. *   
  260. * DESCRIPTION
  261. *
  262. *   -
  263. *
  264. * CHANGES
  265. *
  266. *   -
  267. *
  268. ******************************************************************************/
  269.  
  270. static void Rotate_Light_Source (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  271. {
  272.   Transform_Light_Source(Object, Trans);
  273. }
  274.  
  275.  
  276.  
  277. /*****************************************************************************
  278. *
  279. * FUNCTION
  280. *
  281. *   Scale_Light_Source
  282. *
  283. * INPUT
  284. *   
  285. * OUTPUT
  286. *   
  287. * RETURNS
  288. *   
  289. * AUTHOR
  290. *
  291. *   POV-Ray Team
  292. *   
  293. * DESCRIPTION
  294. *
  295. *   -
  296. *
  297. * CHANGES
  298. *
  299. *   -
  300. *
  301. ******************************************************************************/
  302.  
  303. static void Scale_Light_Source (OBJECT *Object, VECTOR Vector, TRANSFORM *Trans)
  304. {
  305.   Transform_Light_Source(Object, Trans);
  306. }
  307.  
  308.  
  309.  
  310. /*****************************************************************************
  311. *
  312. * FUNCTION
  313. *
  314. *   Transform_Light_Source
  315. *
  316. * INPUT
  317. *   
  318. * OUTPUT
  319. *   
  320. * RETURNS
  321. *   
  322. * AUTHOR
  323. *
  324. *   POV-Ray Team
  325. *   
  326. * DESCRIPTION
  327. *
  328. *   -
  329. *
  330. * CHANGES
  331. *
  332. *   -
  333. *
  334. ******************************************************************************/
  335.  
  336. static void Transform_Light_Source (OBJECT *Object, TRANSFORM *Trans)
  337. {
  338.   DBL len;
  339.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  340.  
  341.   MTransPoint (Light->Center,    Light->Center,    Trans);
  342.   MTransPoint (Light->Points_At, Light->Points_At, Trans);
  343.   MTransPoint (Light->Axis1,     Light->Axis1,     Trans);
  344.   MTransPoint (Light->Axis2,     Light->Axis2,     Trans);
  345.  
  346.   MTransDirection (Light->Direction, Light->Direction, Trans);
  347.  
  348.   /* Make sure direction has unit length. */
  349.  
  350.   VLength(len, Light->Direction);
  351.  
  352.   if (len > EPSILON)
  353.   {
  354.     VInverseScaleEq(Light->Direction, len);
  355.   }
  356.  
  357.   if (Light->Children != NULL)
  358.   {
  359.     Transform_Object (Light->Children, Trans);
  360.   }
  361.  
  362.   if (Light->Projected_Through_Object != NULL)
  363.   {
  364.     Transform_Object (Light->Projected_Through_Object, Trans);
  365.   }
  366. }
  367.  
  368.  
  369.  
  370. /*****************************************************************************
  371. *
  372. * FUNCTION
  373. *
  374. *   Invert_Light_Source
  375. *
  376. * INPUT
  377. *   
  378. * OUTPUT
  379. *   
  380. * RETURNS
  381. *   
  382. * AUTHOR
  383. *
  384. *   POV-Ray Team
  385. *   
  386. * DESCRIPTION
  387. *
  388. *   -
  389. *
  390. * CHANGES
  391. *
  392. *   -
  393. *
  394. ******************************************************************************/
  395.  
  396. static void Invert_Light_Source (OBJECT *Object)
  397. {
  398.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  399.  
  400.   if (Light->Children != NULL)
  401.   {
  402.     Invert_Object (Light->Children);
  403.   }
  404. }
  405.  
  406.  
  407.  
  408. /*****************************************************************************
  409. *
  410. * FUNCTION
  411. *
  412. *   Create_Light_Source
  413. *
  414. * INPUT
  415. *   
  416. * OUTPUT
  417. *   
  418. * RETURNS
  419. *   
  420. * AUTHOR
  421. *
  422. *   POV-Ray Team
  423. *   
  424. * DESCRIPTION
  425. *
  426. *   -
  427. *
  428. * CHANGES
  429. *
  430. *   -
  431. *
  432. ******************************************************************************/
  433.  
  434. LIGHT_SOURCE *Create_Light_Source ()
  435. {
  436.   int i;
  437.   LIGHT_SOURCE *New;
  438.  
  439.   New = (LIGHT_SOURCE *)POV_MALLOC(sizeof (LIGHT_SOURCE), "light_source");
  440.  
  441.   INIT_OBJECT_FIELDS(New, LIGHT_OBJECT, &Light_Source_Methods)
  442.  
  443.   New->Children = NULL;
  444.  
  445.   Set_Flag(New, NO_SHADOW_FLAG);
  446.   New->No_Shadow_Group=ALL_GROUP;
  447.  
  448.   Make_Colour(New->Colour,    1.0, 1.0, 1.0);
  449.   Make_Vector(New->Direction, 0.0, 0.0, 0.0);
  450.   Make_Vector(New->Center,    0.0, 0.0, 0.0);
  451.   Make_Vector(New->Points_At, 0.0, 0.0, 1.0);
  452.   Make_Vector(New->Axis1,     0.0, 0.0, 1.0);
  453.   Make_Vector(New->Axis2,     0.0, 1.0, 0.0);
  454.  
  455.   New->Coeff   = 10.0;
  456.   New->Radius  = 0.35;
  457.   New->Falloff = 0.35;
  458.  
  459.   New->Fade_Distance = 0.0;
  460.   New->Fade_Power    = 0.0;
  461.  
  462.   New->Next_Light_Source    = NULL;
  463.   New->Light_Grid           = NULL;
  464.   New->Shadow_Cached_Object = NULL;
  465.   New->Projected_Through_Object= NULL;
  466.  
  467.   New->Light_Type = POINT_SOURCE;
  468.  
  469.   New->Area_Light = FALSE;
  470.   New->Jitter     = FALSE;
  471.   New->Track      = FALSE;
  472.   /* NK phmap */
  473.   New->Photon_Area_Light = FALSE;
  474.   New->blend_map = NULL;
  475.   /* NK ---- */
  476.   New->Parallel   = FALSE;
  477.  
  478.   New->Area_Size1 = 0;
  479.   New->Area_Size2 = 0;
  480.  
  481.   New->Adaptive_Level = 100;
  482.  
  483.   New->Media_Attenuation = FALSE;
  484.   New->Media_Interaction = TRUE;
  485.  
  486.   for (i = 0; i < 6; i++)
  487.   {
  488.     New->Light_Buffer[i] = NULL;
  489.   }
  490.  
  491.   for (i = 0; i < MAXLIGHTGROUPS; i++)
  492.   {
  493.     New->In_Group[i] = FALSE;
  494.   }
  495.     
  496.   New->In_Group[ALL_GROUP] = TRUE;
  497. #ifdef CircularOrientAreaLightPatch
  498.  New->Orient=FALSE;
  499.   New->Circular=FALSE;
  500.   New->CircularOrient=FALSE;
  501. #endif
  502.  #ifdef GlowPatch
  503.     New->Glow_Amt = 0;
  504.     New->Glow_Type = 0;
  505. #endif   
  506.  
  507.  
  508.   return (New);
  509. }
  510.  
  511.  
  512.  
  513. /*****************************************************************************
  514. *
  515. * FUNCTION
  516. *
  517. *   Copy_Light_Source
  518. *
  519. * INPUT
  520. *   
  521. * OUTPUT
  522. *   
  523. * RETURNS
  524. *   
  525. * AUTHOR
  526. *
  527. *   POV-Ray Team
  528. *   
  529. * DESCRIPTION
  530. *
  531. *   -
  532. *
  533. * CHANGES
  534. *
  535. *   -
  536. *
  537. ******************************************************************************/
  538.  
  539. static LIGHT_SOURCE *Copy_Light_Source (OBJECT *Old)
  540. {
  541.   int i, j;
  542.   LIGHT_SOURCE *New;
  543.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Old;
  544.  
  545.   New = Create_Light_Source();
  546.  
  547.   /* Copy light source. */
  548.  
  549.   *New = *(LIGHT_SOURCE *)Old;
  550.   /*YS*/
  551.     New->UV_Trans = Copy_Transform(Old->UV_Trans);
  552. /*YS*/
  553.   New->Next_Light_Source = NULL;
  554.  
  555.   New->Children = Copy_Object (((LIGHT_SOURCE *)Old)->Children);
  556.   New->Projected_Through_Object = Copy_Object (((LIGHT_SOURCE *)Old)->Projected_Through_Object);
  557.  
  558.   if (Light->Light_Grid != NULL)
  559.   {
  560.     New->Light_Grid = Create_Light_Grid(Light->Area_Size1, Light->Area_Size2);
  561.  
  562.     for (i = 0; i < Light->Area_Size1; i++)
  563.     {
  564.       for (j = 0; j < Light->Area_Size2; j++)
  565.       {
  566.         Assign_Colour(New->Light_Grid[i][j], Light->Light_Grid[i][j]);
  567.       }
  568.     }
  569.   }
  570.  
  571.   /* NK phmap */
  572.   New->blend_map = Copy_Blend_Map(Light->blend_map);
  573.   /* ---- */
  574.  
  575.   return (New);
  576. }
  577.  
  578.  
  579.  
  580. /*****************************************************************************
  581. *
  582. * FUNCTION
  583. *
  584. *   Destroy_Light_Source
  585. *
  586. * INPUT
  587. *   
  588. * OUTPUT
  589. *   
  590. * RETURNS
  591. *   
  592. * AUTHOR
  593. *
  594. *   POV-Ray Team
  595. *   
  596. * DESCRIPTION
  597. *
  598. *   -
  599. *
  600. * CHANGES
  601. *
  602. *   -
  603. *
  604. ******************************************************************************/
  605.  
  606. static void Destroy_Light_Source (OBJECT *Object)
  607. {
  608.   int i;
  609.   LIGHT_SOURCE *Light = (LIGHT_SOURCE *)Object;
  610.  
  611.   if (Light->Light_Grid != NULL)
  612.   {
  613.     for (i = 0; i < Light->Area_Size1; i++)
  614.     {
  615.       POV_FREE(Light->Light_Grid[i]);
  616.     }
  617.  
  618.     POV_FREE(Light->Light_Grid);
  619.   }
  620.  
  621.   Destroy_Object(Light->Children);
  622.   Destroy_Object(Light->Projected_Through_Object);
  623.   /*YS sept 17 memory leaks */
  624.   /* This blend map is used both by Nathan Kopp's photon mapping and Mark Wagner's
  625.    * wavelength-dependant Rayleigh scattering */
  626.   if ( Light->blend_map)
  627.   {
  628.       Destroy_Blend_Map(Light->blend_map);
  629.       Light->blend_map=NULL;
  630.    }
  631.     /*YS*/
  632.   POV_FREE(Object);
  633. }
  634.  
  635.  
  636.  
  637. /*****************************************************************************
  638. *
  639. * FUNCTION
  640. *
  641. *   Create_Light_Grid
  642. *
  643. * INPUT
  644. *   
  645. * OUTPUT
  646. *   
  647. * RETURNS
  648. *   
  649. * AUTHOR
  650. *
  651. *   POV-Ray Team
  652. *   
  653. * DESCRIPTION
  654. *
  655. *   -
  656. *
  657. * CHANGES
  658. *
  659. *   -
  660. *
  661. ******************************************************************************/
  662.  
  663. COLOUR **Create_Light_Grid (int Size1, int  Size2)
  664. {
  665.   int i;
  666.   COLOUR **New;
  667.  
  668.   New = (COLOUR **)POV_MALLOC(Size1 * sizeof (COLOUR *), "area light");
  669.  
  670.   for (i = 0; i < Size1; i++)
  671.   {
  672.     New[i] = (COLOUR *)POV_MALLOC(Size2 * sizeof (COLOUR), "area light");
  673.   }
  674.  
  675.   return (New);
  676. }
  677.  
  678.  
  679.  
  680. /*****************************************************************************
  681. *
  682. * FUNCTION
  683. *
  684. *   cubic_spline
  685. *
  686. * INPUT
  687. *   
  688. * OUTPUT
  689. *   
  690. * RETURNS
  691. *   
  692. * AUTHOR
  693. *
  694. *   POV-Ray Team
  695. *   
  696. * DESCRIPTION
  697. *
  698. *   Cubic spline that has tangents of slope 0 at x == low and at x == high.
  699. *   For a given value "pos" between low and high the spline value is returned.
  700. *
  701. * CHANGES
  702. *
  703. *   -
  704. *
  705. ******************************************************************************/
  706.  
  707. static DBL cubic_spline(DBL low, DBL  high, DBL  pos)
  708. {
  709.   /* Check to see if the position is within the proper boundaries. */
  710.  
  711.   if (pos < low)
  712.   {
  713.     return(0.0);
  714.   }
  715.   else
  716.   {
  717.     if (pos >= high)
  718.     {
  719.       return(1.0);
  720.     }
  721.   }
  722.  
  723.   /* This never happens. [DB] */
  724.  
  725. /*
  726.   if (high == low)
  727.   {
  728.     return(0.0);
  729.   }
  730. */
  731.  
  732.   /* Normalize to the interval [0...1]. */
  733.  
  734.   pos = (pos - low) / (high - low);
  735.  
  736.   /* See where it is on the cubic curve. */
  737.  
  738.   return(3 - 2 * pos) * pos * pos;
  739. }
  740.  
  741.  
  742.  
  743. /*****************************************************************************
  744. *
  745. * FUNCTION
  746. *
  747. *   Attenuate_Light
  748. *
  749. * INPUT
  750. *   
  751. * OUTPUT
  752. *   
  753. * RETURNS
  754. *   
  755. * AUTHOR
  756. *
  757. *   POV-Ray Team
  758. *   
  759. * DESCRIPTION
  760. *
  761. *   -
  762. *
  763. * CHANGES
  764. *
  765. *   Jan 1995 : Added attenuation due to atmospheric scattering and light
  766. *              source distance. Added cylindrical light source. [DB]
  767. *
  768. ******************************************************************************/
  769.  
  770. DBL Attenuate_Light (LIGHT_SOURCE *Light, RAY *Ray, DBL Distance)
  771. {
  772.   DBL len, k, costheta;
  773.   DBL Attenuation = 1.0;
  774.   VECTOR P, V1;
  775.  
  776.   /* If this is a spotlight then attenuate based on the incidence angle. */
  777.  
  778.   switch (Light->Light_Type)
  779.   {
  780.     case SPOT_SOURCE:
  781.  
  782.       VDot(costheta, Ray->Direction, Light->Direction);
  783.  
  784.       costheta *= -1.0;
  785.  
  786.       if (costheta > 0.0)
  787.       {
  788.         Attenuation = pow(costheta, Light->Coeff);
  789.  
  790.         /*
  791.          * If there is a soft falloff region associated with the light then
  792.          * do an interpolation of values between the hot center and the
  793.          * direction at which light falls to nothing.
  794.          */
  795.  
  796.         if (Light->Radius > 0.0)
  797.         {
  798.           Attenuation *= cubic_spline(Light->Falloff, Light->Radius, costheta);
  799.         }
  800. /*
  801.         Debug_Info("Atten: %lg\n", Attenuation);
  802. */
  803.       }
  804.       else
  805.       {
  806.         Attenuation = 0.0;
  807.       }
  808.       break;
  809.  
  810.     case CYLINDER_SOURCE:
  811.  
  812.       VSub(V1, Ray->Initial, Light->Center);
  813.  
  814.       VDot(k, V1, Light->Direction);
  815.  
  816.       if (k > 0.0)
  817.       {
  818.         VLinComb2(P, 1.0, V1, -k, Light->Direction);
  819.  
  820.         VLength(len, P);
  821.  
  822.         if (len < Light->Falloff)
  823.         {
  824.           len = 1.0 - len / Light->Falloff;
  825.  
  826.           /* NK cylinder light */
  827.           /* currently, tightness has no effect on cylinder lights */
  828.           Attenuation = pow(len*2.0, Light->Coeff);
  829.           /* NK ---- */
  830.   
  831.           /* NK cylinder light - commented out the if statement */
  832.           if (Light->Radius > 0.0)
  833.           {
  834.             Attenuation *= cubic_spline(1.0 - Light->Radius / Light->Falloff, 1.0, len);
  835.             /* NK cylinder light - old version is here, new version follows
  836.             Attenuation *= cubic_spline(0.0, 1.0-Light->Radius/Light->Falloff, len);
  837.             */
  838.           }
  839.           /* NK ---- */
  840.         }
  841.         else
  842.         {
  843.           Attenuation = 0.0;
  844.         }
  845.       }
  846.       else
  847.       {
  848.         Attenuation = 0.0;
  849.       }
  850.  
  851.       break;
  852.   }
  853.  
  854.   if (Attenuation > 0.0)
  855.   {
  856.     /* Attenuate light due to light source distance. */
  857.  
  858.     if ((Light->Fade_Power > 0.0) && (fabs(Light->Fade_Distance) > EPSILON))
  859.     {
  860.       Attenuation *= 2.0 / (1.0 + pow(Distance / Light->Fade_Distance, Light->Fade_Power));
  861.     }
  862.   }
  863.  
  864.   return(Attenuation);
  865. }
  866.  
  867. /*****************************************************************************
  868. *
  869. * FUNCTION
  870. *
  871. *   Light_Source_UVCoord
  872. *
  873. * INPUT
  874. *   
  875. * OUTPUT
  876. *   
  877. * RETURNS
  878. *   
  879. * AUTHOR
  880. *
  881. *   Nathan Kopp -- adapted from Light_Source_Normal by the POV-Ray Team
  882. *
  883. * DESCRIPTION
  884. *
  885. *   -
  886. *
  887. * CHANGES
  888. *
  889. *   -
  890. *
  891. ******************************************************************************/
  892.  
  893. static void Light_Source_UVCoord (UV_VECT Result, OBJECT *Object, INTERSECTION *Inter)
  894. {
  895.   if (((LIGHT_SOURCE *)Object)->Children != NULL)
  896.   {
  897.     UVCoord (Result, ((LIGHT_SOURCE *)Object)->Children,Inter);
  898.   }
  899. }
  900.