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

  1. /****************************************************************************
  2. *                   colour.c
  3. *
  4. *  This module implements routines to manipulate colours.
  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 "colour.h"
  28. #include "pigment.h"
  29. #include "normal.h"
  30. #include "texture.h"
  31.  
  32.  
  33. /*****************************************************************************
  34. * Local preprocessor defines
  35. ******************************************************************************/
  36.  
  37.  
  38.  
  39. /*****************************************************************************
  40. * Local typedefs
  41. ******************************************************************************/
  42.  
  43.  
  44.  
  45. /*****************************************************************************
  46. * Local variables
  47. ******************************************************************************/
  48.  
  49.  
  50. /*****************************************************************************
  51. * Static functions
  52. ******************************************************************************/
  53.  
  54.  
  55.  
  56. /*****************************************************************************
  57. *
  58. * FUNCTION
  59. *
  60. * INPUT
  61. *   
  62. * OUTPUT
  63. *   
  64. * RETURNS
  65. *   
  66. * AUTHOR
  67. *
  68. *   POV-Ray Team
  69. *   
  70. * DESCRIPTION
  71. *
  72. *   -
  73. *
  74. * CHANGES
  75. *
  76. *   -
  77. *
  78. ******************************************************************************/
  79.  
  80. COLOUR *Create_Colour ()
  81. {
  82.   COLOUR *New;
  83.  
  84.   New = (COLOUR *)POV_MALLOC(sizeof (COLOUR), "color");
  85.  
  86.   Make_ColourA (*New, 0.0, 0.0, 0.0, 0.0, 0.0);
  87.  
  88.   return (New);
  89. }
  90.  
  91.  
  92.  
  93. /*****************************************************************************
  94. *
  95. * FUNCTION
  96. *
  97. * INPUT
  98. *   
  99. * OUTPUT
  100. *   
  101. * RETURNS
  102. *   
  103. * AUTHOR
  104. *
  105. *   POV-Ray Team
  106. *   
  107. * DESCRIPTION
  108. *
  109. *   -
  110. *
  111. * CHANGES
  112. *
  113. *   -
  114. *
  115. ******************************************************************************/
  116.  
  117. COLOUR *Copy_Colour (COLOUR Old)
  118. {
  119.   COLOUR *New;
  120.  
  121.   if (Old != NULL)
  122.   {
  123.     New = Create_Colour ();
  124.  
  125.     Assign_Colour(*New,Old);
  126.   }
  127.   else
  128.   {
  129.     New = NULL;
  130.   }
  131.  
  132.   return (New);
  133. }
  134.  
  135.  
  136.  
  137. /*****************************************************************************
  138. *
  139. * FUNCTION
  140. *
  141. * INPUT
  142. *   
  143. * OUTPUT
  144. *   
  145. * RETURNS
  146. *   
  147. * AUTHOR
  148. *
  149. *   POV-Ray Team
  150. *   
  151. * DESCRIPTION
  152. *
  153. *   -
  154. *
  155. * CHANGES
  156. *
  157. *   Aug 1995 : Use POV_CALLOC to initialize entries. [DB]
  158. *
  159. ******************************************************************************/
  160.  
  161. BLEND_MAP_ENTRY *Create_BMap_Entries (int Map_Size)
  162. {
  163.   BLEND_MAP_ENTRY *New;
  164.  
  165.   New = (BLEND_MAP_ENTRY *)POV_CALLOC((size_t)Map_Size, sizeof (BLEND_MAP_ENTRY), "blend map entry");
  166.  
  167.   return (New);
  168. }
  169.  
  170.  
  171.  
  172. /*****************************************************************************
  173. *
  174. * FUNCTION
  175. *
  176. * INPUT
  177. *   
  178. * OUTPUT
  179. *   
  180. * RETURNS
  181. *   
  182. * AUTHOR
  183. *
  184. *   POV-Ray Team
  185. *   
  186. * DESCRIPTION
  187. *
  188. *
  189. * CHANGES
  190. *
  191. ******************************************************************************/
  192.  
  193. BLEND_MAP_ENTRY *Copy_BMap_Entries (BLEND_MAP_ENTRY *Old, int Map_Size, int  Type)
  194. {
  195.   int i;
  196.   BLEND_MAP_ENTRY *New;
  197.  
  198.   if (Old != NULL)
  199.   {
  200.     New = Create_BMap_Entries (Map_Size);
  201.  
  202.     for (i = 0; i < Map_Size; i++)
  203.     {
  204.       switch (Type)
  205.       {
  206.         case PIGMENT_TYPE:
  207.  
  208.           New[i].Vals.Pigment = Copy_Pigment(Old[i].Vals.Pigment);
  209.  
  210.           break;
  211.  
  212.         case NORMAL_TYPE:
  213.  
  214.           New[i].Vals.Tnormal = Copy_Tnormal(Old[i].Vals.Tnormal);
  215.  
  216.           break;
  217.  
  218.         case TEXTURE_TYPE:
  219.  
  220.           New[i].Vals.Texture = Copy_Textures(Old[i].Vals.Texture);
  221.  
  222.           break;
  223.  
  224.         case COLOUR_TYPE:
  225.         case SLOPE_TYPE:
  226.  
  227.           New[i] = Old[i];
  228.  
  229.           break;
  230.       }
  231.     }
  232.   }
  233.   else
  234.   {
  235.     New = NULL;
  236.   }
  237.  
  238.   return (New);
  239. }
  240.  
  241.  
  242.  
  243. /*****************************************************************************
  244. *
  245. * FUNCTION
  246. *
  247. *   Create_Blend_Map
  248. *
  249. * INPUT
  250. *   
  251. * OUTPUT
  252. *   
  253. * RETURNS
  254. *   
  255. * AUTHOR
  256. *
  257. *   POV-Ray Team
  258. *   
  259. * DESCRIPTION
  260. *
  261. *   -
  262. *
  263. * CHANGES
  264. *
  265. *   -
  266. *
  267. ******************************************************************************/
  268.  
  269. BLEND_MAP *Create_Blend_Map ()
  270. {
  271.   BLEND_MAP *New;
  272.  
  273.   New = (BLEND_MAP *)POV_MALLOC(sizeof (BLEND_MAP), "blend map");
  274.  
  275.   New->Users = 1;
  276.  
  277.   New->Number_Of_Entries = 0;
  278.  
  279.   New->Type = COLOUR_TYPE;
  280.  
  281.   New->Blend_Map_Entries = NULL;
  282.  
  283.   New->Transparency_Flag = FALSE;
  284.  
  285.   return (New);
  286. }
  287.  
  288.  
  289.  
  290. /*****************************************************************************
  291. *
  292. * FUNCTION
  293. *
  294. *   Copy_Blend_Map
  295. *
  296. * INPUT
  297. *   
  298. * OUTPUT
  299. *
  300. * RETURNS
  301. *   
  302. * AUTHOR
  303. *
  304. *   POV-Ray Team
  305. *   
  306. * DESCRIPTION
  307. *
  308. *   -
  309. *
  310. * CHANGES
  311. *
  312. *   -
  313. *
  314. ******************************************************************************/
  315.  
  316. BLEND_MAP *Copy_Blend_Map (BLEND_MAP *Old)
  317. {
  318.   BLEND_MAP *New;
  319.  
  320.   New = Old;
  321.  
  322.   /* 
  323.    * Do not increase the users field if it is negative.
  324.    *
  325.    * A negative users field incicates a reference to a static
  326.    * or global memory area in the data segment, not on the heap!
  327.    * Thus it must not be deleted later.
  328.    */
  329.  
  330.   if ((New != NULL) && (New->Users >= 0))
  331.   {
  332.     New->Users++;
  333.   }
  334.  
  335.   return (New);
  336. }
  337.  
  338.  
  339.  
  340. /*****************************************************************************
  341. *
  342. * FUNCTION
  343. *
  344. *   Colour_Distance
  345. *
  346. * INPUT
  347. *
  348. * OUTPUT
  349. *
  350. * RETURNS
  351. *
  352. * AUTHOR
  353. *
  354. *   POV-Ray Team
  355. *
  356. * DESCRIPTION
  357. *
  358. *   -
  359. *
  360. * CHANGES
  361. *
  362. *   -
  363. *
  364. ******************************************************************************/
  365.  
  366. DBL Colour_Distance (COLOUR colour1, COLOUR  colour2)
  367. {
  368.   return (fabs(colour1[RED]   - colour2[RED]) +
  369.           fabs(colour1[GREEN] - colour2[GREEN]) +
  370.           fabs(colour1[BLUE]  - colour2[BLUE]));
  371. }
  372.  
  373.  
  374.  
  375. /*****************************************************************************
  376. *
  377. * FUNCTION
  378. *
  379. *   Add_Colour
  380. *
  381. * INPUT
  382. *   
  383. * OUTPUT
  384. *   
  385. * RETURNS
  386. *   
  387. * AUTHOR
  388. *
  389. *   POV-Ray Team
  390. *   
  391. * DESCRIPTION
  392. *
  393. *   -
  394. *
  395. * CHANGES
  396. *
  397. *   -
  398. *
  399. ******************************************************************************/
  400.  
  401. void Add_Colour (COLOUR result, COLOUR  colour1, COLOUR  colour2)
  402. {
  403.   result[RED]    = colour1[RED]    + colour2[RED];
  404.   result[GREEN]  = colour1[GREEN]  + colour2[GREEN];
  405.   result[BLUE]   = colour1[BLUE]   + colour2[BLUE];
  406.   result[FILTER] = colour1[FILTER] + colour2[FILTER];
  407.   result[TRANSM] = colour1[TRANSM] + colour2[TRANSM];
  408. }
  409.  
  410.  
  411.  
  412. /*****************************************************************************
  413. *
  414. * FUNCTION
  415. *
  416. *   Scale_Colour
  417. *
  418. * INPUT
  419. *   
  420. * OUTPUT
  421. *   
  422. * RETURNS
  423. *   
  424. * AUTHOR
  425. *
  426. *   POV-Ray Team
  427. *   
  428. * DESCRIPTION
  429. *
  430. *   -
  431. *
  432. * CHANGES
  433. *
  434. *   -
  435. *
  436. ******************************************************************************/
  437.  
  438. void Scale_Colour (COLOUR result, COLOUR  colour, DBL factor)
  439. {
  440.   result[RED]    = colour[RED]    * factor;
  441.   result[GREEN]  = colour[GREEN]  * factor;
  442.   result[BLUE]   = colour[BLUE]   * factor;
  443.   result[FILTER] = colour[FILTER] * factor;
  444.   result[TRANSM] = colour[TRANSM] * factor;
  445. }
  446.  
  447.  
  448.  
  449. /*****************************************************************************
  450. *
  451. * FUNCTION
  452. *
  453. *   Clip_Colour
  454. *
  455. * INPUT
  456. *   
  457. * OUTPUT
  458. *   
  459. * RETURNS
  460. *   
  461. * AUTHOR
  462. *
  463. *   POV-Ray Team
  464. *   
  465. * DESCRIPTION
  466. *
  467. *   -
  468. *
  469. * CHANGES
  470. *
  471. *   -
  472. *
  473. ******************************************************************************/
  474.  
  475. void Clip_Colour (COLOUR result, COLOUR  colour)
  476. {
  477.   if (colour[RED] > 1.0)
  478.   {
  479.     result[RED] = 1.0;
  480.   }
  481.   else
  482.   {
  483.     if (colour[RED] < 0.0)
  484.     {
  485.       result[RED] = 0.0;
  486.     }
  487.     else
  488.     {
  489.       result[RED] = colour[RED];
  490.     }
  491.   }
  492.  
  493.   if (colour[GREEN] > 1.0)
  494.   {
  495.     result[GREEN] = 1.0;
  496.   }
  497.   else
  498.   {
  499.     if (colour[GREEN] < 0.0)
  500.     {
  501.       result[GREEN] = 0.0;
  502.     }
  503.     else
  504.     {
  505.       result[GREEN] = colour[GREEN];
  506.     }
  507.   }
  508.  
  509.   if (colour[BLUE] > 1.0)
  510.   {
  511.     result[BLUE] = 1.0;
  512.   }
  513.   else
  514.   {
  515.     if (colour[BLUE] < 0.0)
  516.     {
  517.       result[BLUE] = 0.0;
  518.     }
  519.     else
  520.     {
  521.       result[BLUE] = colour[BLUE];
  522.     }
  523.   }
  524.  
  525.   if (colour[FILTER] > 1.0)
  526.   {
  527.     result[FILTER] = 1.0;
  528.   }
  529.   else
  530.   {
  531.     if (colour[FILTER] < 0.0)
  532.     {
  533.       result[FILTER] = 0.0;
  534.     }
  535.     else
  536.     {
  537.       result[FILTER] = colour[FILTER];
  538.     }
  539.   }
  540.  
  541.   if (colour[TRANSM] > 1.0)
  542.   {
  543.     result[TRANSM] = 1.0;
  544.   }
  545.   else
  546.   {
  547.     if (colour[TRANSM] < 0.0)
  548.     {
  549.       result[TRANSM] = 0.0;
  550.     }
  551.     else
  552.     {
  553.       result[TRANSM] = colour[TRANSM];
  554.     }
  555.   }
  556. }
  557.  
  558.  
  559.  
  560. /*****************************************************************************
  561. *
  562. * FUNCTION
  563. *
  564. *   Destroy_Blend_Map
  565. *
  566. * INPUT
  567. *   
  568. * OUTPUT
  569. *   
  570. * RETURNS
  571. *   
  572. * AUTHOR
  573. *
  574. *   POV-Ray Team
  575. *   
  576. * DESCRIPTION
  577. *
  578. *   -
  579. *
  580. * CHANGES
  581. *
  582. *   -
  583. *
  584. ******************************************************************************/
  585.  
  586. void Destroy_Blend_Map (BLEND_MAP *BMap)
  587. {
  588.   int i;
  589.   
  590.   if (BMap != NULL)
  591.   {
  592.     if (--(BMap->Users) == 0)
  593.     {
  594.       for (i = 0; i < BMap->Number_Of_Entries; i++)
  595.       {
  596.         switch (BMap->Type)
  597.         {
  598.            case PIGMENT_TYPE:
  599.            case DENSITY_TYPE:
  600.              Destroy_Pigment(BMap->Blend_Map_Entries[i].Vals.Pigment);
  601.              break;
  602.  
  603.            case NORMAL_TYPE:
  604.              Destroy_Tnormal(BMap->Blend_Map_Entries[i].Vals.Tnormal);
  605.              break;
  606.  
  607.            case TEXTURE_TYPE:
  608.              Destroy_Textures(BMap->Blend_Map_Entries[i].Vals.Texture);
  609.         }
  610.       }
  611.  
  612.       POV_FREE (BMap->Blend_Map_Entries);
  613.  
  614.       POV_FREE (BMap);
  615.     }
  616.   }
  617. }
  618.  
  619.  
  620. /* NK phmap & post process */
  621. /* this code from Mike's MSGTracer */
  622. DBL RGBtoHue( COLOUR c )
  623.  {
  624.   DBL r, g, b;
  625.   DBL mx, mn, delta;
  626.   DBL h, s, v;
  627.   DBL w;
  628.  
  629.   r = c[0];
  630.   g = c[1];
  631.   b = c[2];
  632.  
  633.   /* ----------- Convert to HSV -------------- */
  634.  
  635.   mx = max3(r,g,b);
  636.   mn = min3(r,g,b);
  637.  
  638.   v = mx;
  639.   h = 3.0;
  640.  
  641.   delta = mx-mn;
  642.   if( delta > 0.0 && mx > 0.0 )
  643.    {
  644.     s = delta/mx;
  645.  
  646.     if( r == mx )
  647.       h = (g-b)/delta;
  648.     else if( g == mx )
  649.       h = 2.0 + (b-r)/delta;
  650.     else if( b == mx )
  651.       h = 4.0 + (r-g)/delta;
  652.    }
  653.  
  654.   h *= 60.0;
  655.   if( h < 0.0 ) h += 360.0;
  656.  
  657.  
  658.   /* ------- Convert H to wavelength --------- */
  659.  
  660.   w = h + 60.0;                         /* Split ultraviolet/red at -30 */
  661.   if( w > 360.0 ) w -= 360.0;           
  662.  
  663.   /* should we invert??????? */
  664.   /*w = 360.0 - w;*/                        /* Invert H, 0 = blue, 360 = red    */
  665.   /*w = 380.0 + (780.0-380.0)*(w/360.0);*/  /* Convert to wavelength, 380-780nm */
  666.   w = 0.0 + (1.0-0.0)*(w/360.0);  /* Convert to range, 0-1 */
  667.  
  668.   return w;
  669.  }
  670. /* NK ---- */