home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / povsrc31.zip / Warps.c < prev    next >
C/C++ Source or Header  |  2001-01-27  |  30KB  |  1,171 lines

  1. /**************************************************************************
  2. *                warps.c
  3. *
  4. *  This module implements functions that warp or modify the point at which
  5. *  a texture pattern is evaluated.
  6. *
  7. *  from Persistence of Vision(tm) Ray Tracer
  8. *  Copyright 1996,1999 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file.
  15. *  If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by email to team-coord@povray.org or visit us on the web at
  17. *  http://www.povray.org. The latest version of POV-Ray may be found at this site.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. #include "frame.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "matrices.h"
  29. #include "warps.h"
  30. #include "pattern.h"
  31. #include "texture.h"
  32. #include "povray.h"
  33. #ifdef DisplaceWarpPatch
  34. #include "pigment.h"
  35. #include "colour.h"
  36. #endif
  37. /*****************************************************************************
  38. * Local preprocessor defines
  39. ******************************************************************************/
  40.  
  41. #define COORDINATE_LIMIT 1.0e17
  42.  
  43.  
  44. /*****************************************************************************
  45. * Static functions
  46. ******************************************************************************/
  47.  
  48. #ifdef PatternWarpPatch
  49.  
  50. static int warp_cylindrical(VECTOR TPoint, CYLW *Warp);
  51. static int warp_spherical(VECTOR TPoint, SPHEREW *Warp);
  52. static int warp_toroidal(VECTOR TPoint,  TOROIDAL *Warp);
  53. static int warp_planar(VECTOR TPoint,  PLANARW *Warp);
  54. #endif
  55. #ifdef DisplaceWarpPatch/*Chris Huff 6/25/2000 added ability to warp with pigment colors*/
  56. static int displace_point(VECTOR TPoint,  DISP_WARP *Warp);
  57. #endif
  58. /*****************************************************************************
  59. *
  60. * FUNCTION
  61. *
  62. *   Warp_EPoint
  63. *
  64. * INPUT
  65. *
  66. *   EPoint -- The original point in 3d space at which a pattern
  67. *   is evaluated.
  68. *   TPat   -- Texture pattern struct
  69. *   
  70. * OUTPUT
  71. *
  72. *   TPoint -- Point after turbulence and transform
  73. *   have been applied
  74. *   
  75. * RETURNS
  76. *   
  77. * AUTHOR
  78. *
  79. *   POV-Ray Team
  80. *   
  81. * DESCRIPTION
  82. *
  83. * CHANGES
  84. *
  85. ******************************************************************************/
  86.  
  87. void Warp_EPoint (VECTOR TPoint, VECTOR EPoint, TPATTERN *TPat, int warping_children)
  88. {
  89.    VECTOR PTurbulence,RP;
  90.    int Axis,i,temp_rand;
  91.    int blockX = 0, blockY = 0, blockZ = 0 ;
  92.    SNGL BlkNum;
  93.    DBL  Length;
  94.    DBL  Strength;
  95.    WARP *Warp=TPat->Warps;
  96.    TURB *Turb;
  97.    TRANS *Tr;
  98.    REPEAT *Repeat;
  99.    BLACK_HOLE *Black_Hole;
  100.    VECTOR Delta, Center;
  101.  
  102.    Assign_Vector(TPoint, EPoint);
  103.  
  104.    while (Warp != NULL)
  105.    {
  106.         #ifdef TransformableWarpsPatch
  107.               if(Warp->Warp_Transform != NULL)
  108.                   MInvTransPoint(TPoint, TPoint, Warp->Warp_Transform);
  109.         #endif
  110.       switch(Warp->Warp_Type)
  111.       {
  112.         /* NK 1998 reset_children */
  113.         case RESET_CHILDREN_WARP:
  114.           /* if processing child textures, we stop warping at this
  115.              point using code below */
  116.           break;
  117.         /* NK ---- */
  118.  
  119.           case CLASSIC_TURB_WARP:
  120.           if ((TPat->Type == MARBLE_PATTERN) ||
  121.               (TPat->Type == NO_PATTERN)     ||
  122.               (TPat->Type == WOOD_PATTERN))
  123.           {
  124.              break;
  125.           }
  126.         /* If not a special type, fall through to next case */
  127.  
  128.         case EXTRA_TURB_WARP:
  129.           Turb=(TURB *)Warp;
  130.           DTurbulence (PTurbulence, TPoint, Turb);
  131.           TPoint[X] += PTurbulence[X] * Turb->Turbulence[X];
  132.           TPoint[Y] += PTurbulence[Y] * Turb->Turbulence[Y];
  133.           TPoint[Z] += PTurbulence[Z] * Turb->Turbulence[Z];
  134.           break;
  135.  
  136.         case NO_WARP:
  137.           break;
  138.  
  139.         case TRANSFORM_WARP:
  140.           Tr=(TRANS *)Warp;
  141.           MInvTransPoint(TPoint, TPoint, &(Tr->Trans));
  142.           break;
  143.  
  144.         case REPEAT_WARP:
  145.           Repeat=(REPEAT *)Warp;
  146.           Assign_Vector(RP,TPoint);
  147.           Axis=Repeat->Axis;
  148.           BlkNum=(SNGL)floor(TPoint[Axis]/Repeat->Width);
  149.           
  150.           RP[Axis]=TPoint[Axis]-BlkNum*Repeat->Width;
  151.           
  152.           if (((int)BlkNum) & 1)
  153.           {          
  154.              VEvaluateEq(RP,Repeat->Flip);
  155.              if ( Repeat->Flip[Axis] < 0 ) 
  156.              {
  157.                 RP[Axis] = Repeat->Width+RP[Axis];
  158.              }
  159.           }
  160.  
  161.           VAddScaledEq(RP,BlkNum,Repeat->Offset);
  162.           Assign_Vector(TPoint,RP);
  163.           break;
  164.  
  165.         case BLACK_HOLE_WARP:
  166.           Black_Hole = (BLACK_HOLE *) Warp ;
  167.           Assign_Vector (Center, Black_Hole->Center) ;
  168.  
  169.           if (Black_Hole->Repeat)
  170.           {
  171.             /* first, get the block number we're in for each dimension  */
  172.             /* block numbers are (currently) calculated relative to 0   */
  173.             /* we use floor () since it correctly returns -1 for the
  174.                first block below 0 in each axis                         */
  175.             /* one final point - we could run into overflow problems if
  176.                the repeat vector was small and the scene very large.    */
  177.             if (Black_Hole->Repeat_Vector [X] >= Small_Tolerance)
  178.               blockX = (int) floor (TPoint [X] / Black_Hole->Repeat_Vector [X]) ;
  179.  
  180.             if (Black_Hole->Repeat_Vector [Y] >= Small_Tolerance)
  181.               blockY = (int) floor (TPoint [Y] / Black_Hole->Repeat_Vector [Y]) ;
  182.  
  183.             if (Black_Hole->Repeat_Vector [Z] >= Small_Tolerance)
  184.               blockZ = (int) floor (TPoint [Z] / Black_Hole->Repeat_Vector [Z]) ;
  185.  
  186.             if (Black_Hole->Uncertain)
  187.             {
  188.               /* if the position is uncertain calculate the new one first */
  189.               /* this will allow the same numbers to be returned by frand */
  190.               temp_rand = POV_GET_OLD_RAND(); /*protect seed*/
  191.   
  192.               POV_SRAND (Hash3d (blockX, blockY, blockZ)) ;
  193.               Center [X] += FRAND () * Black_Hole->Uncertainty_Vector [X] ;
  194.               Center [Y] += FRAND () * Black_Hole->Uncertainty_Vector [Y] ;
  195.               Center [Z] += FRAND () * Black_Hole->Uncertainty_Vector [Z] ;
  196.               POV_SRAND (temp_rand) ;  /*restore*/
  197.             }
  198.  
  199.             Center [X] += Black_Hole->Repeat_Vector [X] * blockX ;
  200.             Center [Y] += Black_Hole->Repeat_Vector [Y] * blockY ;
  201.             Center [Z] += Black_Hole->Repeat_Vector [Z] * blockZ ;
  202.           }
  203.  
  204.           VSub (Delta, TPoint, Center) ;
  205.           VLength (Length, Delta) ;
  206.  
  207.           /* Length is the distance from the centre of the black hole */
  208.           if (Length >= Black_Hole->Radius) break ;
  209.  
  210.           if (Black_Hole->Type == 0)
  211.           {
  212.             /* now convert the length to a proportion (0 to 1) that the point
  213.                is from the edge of the black hole. a point on the perimeter
  214.                of the black hole will be 0.0 ; a point at the centre will be
  215.                1.0 ; a point exactly halfway will be 0.5, and so forth. */
  216.             Length = (Black_Hole->Radius - Length) / Black_Hole->Radius ;
  217.  
  218.             /* Strength is the magnitude of the transformation effect. firstly,
  219.                apply the Power variable to Length. this is meant to provide a
  220.                means of controlling how fast the power of the Black Hole falls
  221.                off from its centre. if Power is 2.0, then the effect is inverse
  222.                square. increasing power will cause the Black Hole to be a lot
  223.                weaker in its effect towards its perimeter. 
  224.                
  225.                finally we multiply Strength with the Black Hole's Strength
  226.                variable. if the resultant value exceeds 1.0 we clip it to 1.0.
  227.                this means a point will never be transformed by more than its
  228.                original distance from the centre. the result of this clipping
  229.                is that you will have an 'exclusion' area near the centre of
  230.                the black hole where all points whose final value exceeded or
  231.                equalled 1.0 were moved by a fixed amount. this only happens
  232.                if the Strength value of the Black Hole was greater than one. */
  233.  
  234.             Strength = pow (Length, Black_Hole->Power) * Black_Hole->Strength ;
  235.             if (Strength > 1.0) Strength = 1.0 ;
  236.             
  237.             /* if the Black Hole is inverted, it gives the impression of 'push-
  238.                ing' the pattern away from its centre. otherwise it sucks. */
  239.             VScaleEq (Delta, Black_Hole->Inverted ? -Strength : Strength) ;
  240.  
  241.             /* add the scaled Delta to the input point to end up with TPoint. */
  242.             VAddEq (TPoint, Delta) ;
  243.           }
  244.           break;
  245.  
  246. #ifdef DisplaceWarpPatch
  247.         /*Chris Huff 6/25/2000 added ability to warp with pigment colors*/
  248.         case DISPLACE_WARP:
  249.           displace_point(TPoint, (DISP_WARP *)Warp);
  250.           break;
  251. #endif
  252.  
  253. #ifdef PatternWarpPatch
  254.         /* 10/23/1998 Talious added SPherical Cylindrical and toroidal
  255.         warps */
  256.  
  257.         case CYLINDRICAL_WARP:
  258.           warp_cylindrical(TPoint, (CYLW *)Warp);
  259.           break;
  260.  
  261.         case PLANAR_WARP:
  262.           warp_planar(TPoint, (PLANARW *)Warp);
  263.           break;
  264.       
  265.         case SPHERICAL_WARP:
  266.           warp_spherical(TPoint, (SPHEREW *)Warp);
  267.           break;
  268.         case TOROIDAL_WARP:
  269.           warp_toroidal(TPoint, (TOROIDAL *) Warp);
  270.           break;
  271. #endif
  272.           
  273.         default:
  274.           Error("Warp type %d not yet implemented",Warp->Warp_Type);
  275.       }
  276.     #ifdef TransformableWarpsPatch
  277.       if(Warp->Warp_Transform != NULL)
  278.          MTransPoint(TPoint, TPoint, Warp->Warp_Transform);
  279.     #endif
  280.       /* nk 1998 reset_children */
  281.       if ((Warp->Warp_Type==RESET_CHILDREN_WARP) && (warping_children))
  282.         /* if we are warping child textures, we want to stop warping at this
  283.            point... setting Warp to NULL stops the loop */
  284.         Warp = NULL;
  285.       else
  286.       /* NK ---- */
  287.         Warp=Warp->Next_Warp;
  288.    }
  289.  
  290.    for (i=X; i<=Z; i++)
  291.      if (TPoint[i] > COORDINATE_LIMIT)
  292.        TPoint[i]= COORDINATE_LIMIT;
  293.      else
  294.        if (TPoint[i] < -COORDINATE_LIMIT)
  295.          TPoint[i] = -COORDINATE_LIMIT;
  296.  
  297. }
  298.  
  299. #ifdef NormalBugFix
  300. void Warp_Classic_Turb (VECTOR TPoint, VECTOR EPoint, TPATTERN *TPat)
  301. {
  302.    int i;
  303.    VECTOR PTurbulence;
  304.    WARP *Warp=TPat->Warps;
  305.    TURB *Turb;
  306.  
  307.    Assign_Vector(TPoint, EPoint);
  308.  
  309.    if (Warp!=NULL)
  310.    while (Warp->Next_Warp != NULL)
  311.    {
  312.      Warp = Warp->Next_Warp;
  313.    }
  314.  
  315.    if(Warp->Warp_Type == CLASSIC_TURB_WARP)
  316.    {
  317.     if (!(
  318.         (TPat->Type == MARBLE_PATTERN) ||
  319.         (TPat->Type == NO_PATTERN)     ||
  320.         (TPat->Type == WOOD_PATTERN)))
  321.     {
  322.       Turb=(TURB *)Warp;
  323.       DTurbulence (PTurbulence, TPoint, Turb);
  324.       TPoint[X] += PTurbulence[X] * Turb->Turbulence[X];
  325.       TPoint[Y] += PTurbulence[Y] * Turb->Turbulence[Y];
  326.       TPoint[Z] += PTurbulence[Z] * Turb->Turbulence[Z];
  327.     }
  328.    }
  329.  
  330.    for (i=X; i<=Z; i++)
  331.      if (TPoint[i] > COORDINATE_LIMIT)
  332.        TPoint[i]= COORDINATE_LIMIT;
  333.      else
  334.        if (TPoint[i] < -COORDINATE_LIMIT)
  335.          TPoint[i] = -COORDINATE_LIMIT;
  336. }
  337.  
  338.  
  339. void Warp_Normal (VECTOR TNorm, VECTOR ENorm, TPATTERN *TPat, int warping_children, int DontScaleBumps)
  340. {
  341.    WARP *Warp=TPat->Warps;
  342.    TRANS *Tr;
  343.  
  344.   if(!DontScaleBumps)
  345.   {
  346.     VNormalize(TNorm,ENorm)
  347.   }
  348.   else
  349.   {
  350.     Assign_Vector(TNorm,ENorm);
  351.   }
  352.  
  353.    while (Warp != NULL)
  354.    {
  355.       switch(Warp->Warp_Type)
  356.       {
  357.         /* NK 1998 reset_children */
  358.         case RESET_CHILDREN_WARP:
  359.           /* if processing child textures, we stop warping at this
  360.              point using code below */
  361.           break;
  362.         /* NK ---- */
  363.  
  364.         case NO_WARP:
  365.           break;
  366.  
  367.         case TRANSFORM_WARP:
  368.           Tr=(TRANS *)Warp;
  369.           MInvTransNormal(TNorm, TNorm, &(Tr->Trans));
  370.           break;
  371.           
  372.         /*
  373.         default:
  374.           Error("Warp type %d not yet implemented",Warp->Warp_Type);
  375.         */
  376.       }
  377.       /* nk 1998 reset_children */
  378.       if ((Warp->Warp_Type==RESET_CHILDREN_WARP) && (warping_children))
  379.         /* if we are warping child textures, we want to stop warping at this
  380.            point... setting Warp to NULL stops the loop */
  381.         Warp = NULL;
  382.       else
  383.       /* NK ---- */
  384.         Warp=Warp->Next_Warp;
  385.    }
  386.   if(!DontScaleBumps)
  387.   {
  388.    VNormalizeEq(TNorm);
  389.   }
  390. }
  391.  
  392. void UnWarp_Normal (VECTOR TNorm, VECTOR ENorm, TPATTERN *TPat, int warping_children, int DontScaleBumps)
  393. {
  394.    WARP *Warp=TPat->Warps;
  395.    TRANS *Tr;
  396.  
  397.   if(!DontScaleBumps)
  398.   {
  399.    VNormalize(TNorm,ENorm)
  400.   }
  401.   else
  402.   {
  403.     Assign_Vector(TNorm,ENorm);
  404.   }
  405.  
  406.    while (Warp != NULL)
  407.    {
  408.       switch(Warp->Warp_Type)
  409.       {
  410.         /* NK 1998 reset_children */
  411.         case RESET_CHILDREN_WARP:
  412.           /* if processing child textures, we stop warping at this
  413.              point using code below */
  414.           break;
  415.         /* NK ---- */
  416.  
  417.         case NO_WARP:
  418.           break;
  419.  
  420.         case TRANSFORM_WARP:
  421.           Tr=(TRANS *)Warp;
  422.           MTransNormal(TNorm, TNorm, &(Tr->Trans));
  423.           break;
  424.           
  425.         /*
  426.         default:
  427.           Error("Warp type %d not yet implemented",Warp->Warp_Type);
  428.         */
  429.       }
  430.       /* nk 1998 reset_children */
  431.       if ((Warp->Warp_Type==RESET_CHILDREN_WARP) && (warping_children))
  432.         /* if we are warping child textures, we want to stop warping at this
  433.            point... setting Warp to NULL stops the loop */
  434.         Warp = NULL;
  435.       else
  436.       /* NK ---- */
  437.         Warp=Warp->Next_Warp;
  438.    }
  439.   if(!DontScaleBumps)
  440.   {
  441.    VNormalizeEq(TNorm);
  442.   }
  443. }
  444. #endif
  445.  
  446. #ifdef PatternWarpPatch
  447. /*****************************************************************************
  448. *
  449. * FUNCTION
  450. *    warp_planar
  451. *
  452. * INPUT
  453. *    
  454. * OUTPUT
  455. *
  456. * RETURNS
  457. *
  458. * AUTHOR  Matthew Corey Brown (talious)
  459. *
  460. * DESCRIPTION
  461. *    Based on cylindrical_image_map from image.c
  462. *    Its a 3d version of that for warps
  463. *
  464. * CHANGES
  465. *
  466. ******************************************************************************/
  467.  
  468. static int warp_planar(VECTOR EPoint,  PLANARW *Warp)
  469. {
  470.   DBL x = EPoint[X];
  471.   DBL z = Warp->OffSet;
  472.   DBL y = EPoint[Y];
  473.  
  474.  
  475.    if ( Warp->Orientation_Vector[X] == 0.0 &&
  476.         Warp->Orientation_Vector[Y] == 0.0 &&
  477.         Warp->Orientation_Vector[Z] == 1.0 ) {
  478.     
  479.         EPoint[X] = x;
  480.         EPoint[Y] = y;
  481.         EPoint[Z] = z;
  482.   } else {
  483.      EPoint[X] = (Warp->Orientation_Vector[X] * z) + 
  484.                  (Warp->Orientation_Vector[Y] * x) +
  485.                  (Warp->Orientation_Vector[Z] * x);
  486.      EPoint[Y] = (Warp->Orientation_Vector[X] * y) + 
  487.                  (Warp->Orientation_Vector[Y] * -z) +
  488.                  (Warp->Orientation_Vector[Z] * y);
  489.      EPoint[Z] = (Warp->Orientation_Vector[X] * -x) + 
  490.                  (Warp->Orientation_Vector[Y] * y) +
  491.                  (Warp->Orientation_Vector[Z] * z);
  492.   }
  493.   return 1;
  494. }
  495.  
  496.  
  497. /*****************************************************************************
  498. *
  499. * FUNCTION
  500. *    warp_cylindrical
  501. *
  502. * INPUT
  503. *    
  504. * OUTPUT
  505. *
  506. * RETURNS
  507. *
  508. * AUTHOR  Matthew Corey Brown (talious)
  509. *
  510. * DESCRIPTION
  511. *    Based on cylindrical_image_map from image.c
  512. *    Its a 3d version of that for warps
  513. *
  514. * CHANGES
  515. *
  516. ******************************************************************************/
  517.  
  518. static int warp_cylindrical(VECTOR EPoint, CYLW *Warp)
  519. {
  520.   DBL len, theta;
  521.   DBL x = EPoint[X];
  522.   DBL y = EPoint[Y];
  523.   DBL z = EPoint[Z];
  524.  
  525.   /* Determine its angle from the point (1, 0, 0) in the x-z plane. */
  526.   len = sqrt(x * x + z * z);
  527.  
  528.   if (len == 0.0)
  529.   {
  530.     return 0;
  531.   }
  532.   else
  533.   {
  534.     if (z == 0.0)
  535.     {
  536.       if (x > 0)
  537.       {
  538.         theta = 0.0;
  539.       }
  540.       else
  541.       {
  542.         theta = M_PI;
  543.       }
  544.     }
  545.     else
  546.     {
  547.       theta = acos(x / len);
  548.  
  549.       if (z < 0.0)
  550.       {
  551.         theta = TWO_M_PI - theta;
  552.       }
  553.     }
  554.  
  555.     theta /= TWO_M_PI;  /* This will be from 0 to 1 */
  556.   }
  557.  
  558.     if (Warp->DistExp == 1.0){
  559.         theta *= len;
  560.     } else if (Warp->DistExp != 0.0){
  561.         theta *= pow(len,Warp->DistExp);
  562.     }
  563.  
  564.    x = theta;
  565.    z = len;
  566.  
  567.     
  568.    if ( Warp->Orientation_Vector[X] == 0.0 &&
  569.         Warp->Orientation_Vector[Y] == 0.0 &&
  570.         Warp->Orientation_Vector[Z] == 1.0 ) {
  571.     
  572.         EPoint[X] = x;
  573.         EPoint[Y] = y;
  574.         EPoint[Z] = z;
  575.   } else {
  576.      EPoint[X] = (Warp->Orientation_Vector[X] * z) + 
  577.                  (Warp->Orientation_Vector[Y] * x) +
  578.                  (Warp->Orientation_Vector[Z] * x);
  579.      EPoint[Y] = (Warp->Orientation_Vector[X] * y) + 
  580.                  (Warp->Orientation_Vector[Y] * -z) +
  581.                  (Warp->Orientation_Vector[Z] * y);
  582.      EPoint[Z] = (Warp->Orientation_Vector[X] * -x) + 
  583.                  (Warp->Orientation_Vector[Y] * y) +
  584.                  (Warp->Orientation_Vector[Z] * z);
  585.   }
  586.   return 1;
  587. }
  588.  
  589. /*****************************************************************************
  590. *
  591. * FUNCTION
  592. *        warp_toroidal(VECTOR EPoint, TOROIDAL *Warp)
  593. *
  594. * INPUT
  595. *
  596. * OUTPUT
  597. *
  598. * RETURNS
  599. *
  600. * AUTHOR   Matthew Corey Brown (Talious)
  601. *
  602. *
  603. * DESCRIPTION
  604. * Warps a point on a torus centered on orgin to a 2 d plane in space
  605. * based on torus_image_map
  606. *
  607. * CHANGES
  608. *
  609. ******************************************************************************/
  610.  
  611. static int warp_toroidal(VECTOR EPoint, TOROIDAL *Warp)
  612. {
  613.   DBL len, phi, theta;
  614.   DBL r0;
  615.   DBL x = EPoint[X];
  616.   DBL y = EPoint[Y];
  617.   DBL z = EPoint[Z];
  618.  
  619.   r0 = Warp->MajorRadius;
  620.  
  621.   /* Determine its angle from the x-axis. */
  622.  
  623.   len = sqrt(x * x + z * z);
  624.  
  625.   if (len == 0.0) {
  626.     return 0;
  627.   } else {
  628.     if (z == 0.0) {
  629.       if (x > 0) {
  630.         theta = 0.0;
  631.       } else {
  632.         theta = M_PI;
  633.       }
  634.     } else {
  635.       theta = acos(x / len);
  636.       if (z < 0.0) {
  637.         theta = TWO_M_PI - theta;
  638.       }
  639.     }
  640.   }
  641.  
  642.   theta = 0.0 - theta;
  643.  
  644.   /* Now rotate about the y-axis to get the point (x, y, z) into the x-y
  645. plane. 
  646. */
  647.  
  648.   x = len - r0;
  649.   len = sqrt(x * x + y * y);
  650.   phi = acos(-x / len);
  651.   if (y > 0.0)
  652.   {
  653.     phi = TWO_M_PI - phi;
  654.   }
  655.  
  656.   /* Determine the parametric coordinates. */
  657.  
  658.   theta /= (-TWO_M_PI);
  659.  
  660.   phi /= TWO_M_PI;
  661.  
  662.     if (Warp->DistExp == 1.0){
  663.         theta *= len;
  664.         phi *= len;
  665.     } else if (Warp->DistExp != 0.0){
  666.         theta *= pow(len,Warp->DistExp);
  667.         phi *= pow(len,Warp->DistExp);
  668.     }
  669.  
  670.    x = theta;
  671.    z = len;
  672.    y = phi;
  673.  
  674.     
  675.    if ( Warp->Orientation_Vector[X] == 0.0 &&
  676.         Warp->Orientation_Vector[Y] == 0.0 &&
  677.         Warp->Orientation_Vector[Z] == 1.0 ) {
  678.     
  679.         EPoint[X] = x;
  680.         EPoint[Y] = y;
  681.         EPoint[Z] = z;
  682.   } else {
  683.      EPoint[X] = (Warp->Orientation_Vector[X] * z) + 
  684.                  (Warp->Orientation_Vector[Y] * x) +
  685.                  (Warp->Orientation_Vector[Z] * x);
  686.      EPoint[Y] = (Warp->Orientation_Vector[X] * y) + 
  687.                  (Warp->Orientation_Vector[Y] * -z) +
  688.                  (Warp->Orientation_Vector[Z] * y);
  689.      EPoint[Z] = (Warp->Orientation_Vector[X] * -x) + 
  690.                  (Warp->Orientation_Vector[Y] * y) +
  691.                  (Warp->Orientation_Vector[Z] * z);
  692.   }
  693.  
  694.  
  695.  
  696.   return 1;
  697. }
  698.  
  699. /*****************************************************************************
  700. *
  701. * FUNCTION 
  702. *    warp_spherical
  703. *
  704. * INPUT
  705. *
  706. * OUTPUT
  707. *
  708. * RETURNS
  709. *
  710. * AUTHOR   Matthew Corey Brown (Talious)
  711. *
  712. *
  713. * DESCRIPTION
  714. * Warps a point on a sphere centered on orgin to a 2 d plane in space
  715. * based on spherical_image_map
  716. *
  717. * CHANGES
  718. *
  719. ******************************************************************************/
  720. static int warp_spherical(VECTOR EPoint, SPHEREW *Warp)
  721. {
  722.   DBL len, phi, theta,dist;
  723.   DBL x = EPoint[X];
  724.   DBL y = EPoint[Y];
  725.   DBL z = EPoint[Z];
  726.  
  727.   /* Make sure this vector is on the unit sphere. */
  728.  
  729.   dist = sqrt(x * x + y * y + z * z);
  730.  
  731.   if (dist == 0.0)
  732.   {
  733.     return 0;
  734.   }
  735.   else
  736.   {
  737.     x /= dist;
  738.     y /= dist;
  739.     z /= dist;
  740.   }
  741.  
  742.   /* Determine its angle from the x-z plane. */
  743.  
  744.   phi = 0.5 + asin(y) / M_PI; /* This will be from 0 to 1 */
  745.  
  746.  
  747.   /* Determine its angle from the point (1, 0, 0) in the x-z plane. */
  748.  
  749.   len = sqrt(x * x + z * z);
  750.   if (len == 0.0)
  751.   {
  752.     /* This point is at one of the poles. Any value of xcoord will be
  753. ok... */
  754.  
  755.     theta = 0;
  756.   }
  757.   else
  758.   {
  759.     if (z == 0.0)
  760.     {
  761.       if (x > 0)
  762.       {
  763.         theta = 0.0;
  764.       }
  765.       else
  766.       {
  767.         theta = M_PI;
  768.       }
  769.     }
  770.     else
  771.     {
  772.       theta = acos(x / len);
  773.  
  774.       if (z < 0.0)
  775.       {
  776.         theta = TWO_M_PI - theta;
  777.       }
  778.     }
  779.  
  780.     theta /= TWO_M_PI;  /* This will be from 0 to 1 */
  781.   }
  782.  
  783.     if (Warp->DistExp == 1.0){
  784.         theta *= dist;
  785.         phi *= dist;
  786.     } else if (Warp->DistExp != 0.0){
  787.         theta *= pow(dist,Warp->DistExp);
  788.         phi *= pow(dist,Warp->DistExp);
  789.     }
  790.  
  791.    x = theta;
  792.    z = dist;
  793.    y = phi;
  794.  
  795.     
  796.    if ( Warp->Orientation_Vector[X] == 0.0 &&
  797.         Warp->Orientation_Vector[Y] == 0.0 &&
  798.         Warp->Orientation_Vector[Z] == 1.0 ) {
  799.     
  800.         EPoint[X] = x;
  801.         EPoint[Y] = y;
  802.         EPoint[Z] = z;
  803.   } else {
  804.      EPoint[X] = (Warp->Orientation_Vector[X] * z) + 
  805.                  (Warp->Orientation_Vector[Y] * x) +
  806.                  (Warp->Orientation_Vector[Z] * x);
  807.      EPoint[Y] = (Warp->Orientation_Vector[X] * y) + 
  808.                  (Warp->Orientation_Vector[Y] * -z) +
  809.                  (Warp->Orientation_Vector[Z] * y);
  810.      EPoint[Z] = (Warp->Orientation_Vector[X] * -x) + 
  811.                  (Warp->Orientation_Vector[Y] * y) +
  812.                  (Warp->Orientation_Vector[Z] * z);
  813.   }
  814.  
  815.  
  816.   return 1;
  817. }
  818. #endif
  819. /*****************************************************************************
  820. *
  821. * FUNCTION
  822. *
  823. * INPUT
  824. *   
  825. * OUTPUT
  826. *   
  827. * RETURNS
  828. *   
  829. * AUTHOR
  830. *   
  831. * DESCRIPTION
  832. *
  833. * CHANGES
  834. *
  835. ******************************************************************************/
  836.  
  837. WARP *Create_Warp (int Warp_Type)
  838. {
  839.  WARP *New;
  840.  TURB *TNew;
  841.  REPEAT *RNew;
  842.  TRANS *TRNew;
  843.  BLACK_HOLE *BNew;
  844. #ifdef PatternWarpPatch
  845.  TOROIDAL *TorNew;
  846.  SPHEREW *SNew;
  847.  CYLW *CNew;
  848.  PLANARW *PNew;
  849. #endif   
  850. #ifdef DisplaceWarpPatch
  851.  DISP_WARP *DispNew;
  852. #endif  
  853.  New = NULL;
  854.  
  855.  switch (Warp_Type)
  856.  {
  857.    /* NK 1998 reset_children */
  858.    case RESET_CHILDREN_WARP:
  859.      New = (WARP *)POV_MALLOC(sizeof(WARP),"reset-children warp");
  860.      break;
  861.    /* NK ---- */
  862.  
  863.    case CLASSIC_TURB_WARP:
  864.    case EXTRA_TURB_WARP:
  865.      
  866.      TNew = (TURB *)POV_MALLOC(sizeof(TURB),"turbulence struct");
  867.  
  868.      Make_Vector(TNew->Turbulence,0.0,0.0,0.0);
  869.  
  870.      TNew->Octaves = 6;
  871.      TNew->Omega = 0.5;
  872.      TNew->Lambda = 2.0;
  873.  
  874.      New = (WARP *)TNew;
  875.  
  876.      break;
  877.      
  878.    case REPEAT_WARP:
  879.  
  880.      RNew = (REPEAT *)POV_MALLOC(sizeof(REPEAT),"repeat warp");
  881.  
  882.      RNew->Axis = -1;
  883.      RNew->Width = 0.0;
  884.  
  885.      Make_Vector(RNew->Offset,0.0,0.0,0.0);
  886.      Make_Vector(RNew->Flip,1.0,1.0,1.0);
  887.  
  888.      New = (WARP *)RNew;
  889.  
  890.      break;
  891.  
  892.    case BLACK_HOLE_WARP:
  893.      BNew = (BLACK_HOLE *)POV_MALLOC (sizeof (BLACK_HOLE), "black hole warp") ;
  894.      Make_Vector (BNew->Center, 0.0, 0.0, 0.0) ;
  895.      Make_Vector (BNew->Repeat_Vector, 0.0, 0.0, 0.0) ;
  896.      Make_Vector (BNew->Uncertainty_Vector, 0.0, 0.0, 0.0) ;
  897.      BNew->Strength = 1.0 ;
  898.      BNew->Power = 2.0 ;
  899.      BNew->Radius = 1.0 ;
  900.      BNew->Radius_Squared = 1.0 ;
  901.      BNew->Inverse_Radius = 1.0 ;
  902.      BNew->Inverted = FALSE ;
  903.      BNew->Type = 0 ;
  904.      BNew->Repeat = FALSE ;
  905.      BNew->Uncertain = FALSE ;
  906.      New = (WARP *) BNew ;
  907.      break ;
  908.  
  909.    case TRANSFORM_WARP:
  910.  
  911.      TRNew = (TRANS *)POV_MALLOC(sizeof(TRANS),"pattern transform");
  912.  
  913.      MIdentity (TRNew->Trans.matrix);
  914.      MIdentity (TRNew->Trans.inverse);
  915.  
  916.      New = (WARP *)TRNew;
  917.  
  918.      break;
  919.      
  920. #ifdef DisplaceWarpPatch
  921.    case DISPLACE_WARP:
  922.      DispNew = (DISP_WARP *)POV_MALLOC(sizeof(DISP_WARP),"displace warp");
  923.      DispNew->Pig = Create_Pigment();
  924.      DispNew->type = 0;
  925.      DispNew->dist = 0.05;
  926.      New = (WARP *)DispNew;
  927.      break;
  928. #endif
  929.      
  930. #ifdef PatternWarpPatch
  931.    case SPHERICAL_WARP:
  932.      SNew = (SPHEREW *)POV_MALLOC(sizeof(SPHEREW),"cylindrical warp");
  933.      Make_Vector (SNew->Orientation_Vector, 0.0, 0.0, 1.0) ;
  934.      SNew->DistExp = 0.0;
  935.      New = (WARP *)SNew;
  936.      break;
  937.  
  938.    case PLANAR_WARP:
  939.      PNew = (PLANARW *)POV_MALLOC(sizeof(PLANARW),"planar warp");
  940.      Make_Vector (PNew->Orientation_Vector, 0.0, 0.0, 1.0) ;
  941.      PNew->OffSet = 0.0;
  942.      New = (WARP *)PNew;
  943.      break;
  944.  
  945.    case CYLINDRICAL_WARP:
  946.      CNew = (CYLW *)POV_MALLOC(sizeof(CYLW),"cylindrical warp");
  947.      Make_Vector (CNew->Orientation_Vector, 0.0, 0.0, 1.0) ;
  948.      CNew->DistExp = 0.0;
  949.      New = (WARP *)CNew;
  950.      break;
  951.  
  952.    case TOROIDAL_WARP:
  953.      TorNew = (TOROIDAL *)POV_MALLOC(sizeof(TOROIDAL),"toroidal warp");
  954.      TorNew->MajorRadius = 1.0 ;
  955.      TorNew->DistExp = 0.0;
  956.      Make_Vector (TorNew->Orientation_Vector, 0.0, 0.0, 1.0) ;
  957.      New = (WARP *) TorNew;
  958.      break;
  959.  
  960. #endif
  961.    default:
  962.  
  963.      Error("Unknown Warp type %d.",Warp_Type);
  964.   }
  965. #ifdef TransformableWarpsPatch
  966.   New->Warp_Transform = NULL;
  967. #endif  
  968.   New->Warp_Type = Warp_Type;
  969.   New->Next_Warp = NULL;
  970.   
  971.   return(New);
  972. }
  973.  
  974.  
  975.  
  976. /*****************************************************************************
  977. *
  978. * FUNCTION
  979. *
  980. * INPUT
  981. *   
  982. * OUTPUT
  983. *   
  984. * RETURNS
  985. *   
  986. * AUTHOR
  987. *   
  988. * DESCRIPTION
  989. *
  990. * CHANGES
  991. *
  992. ******************************************************************************/
  993.  
  994. void Destroy_Warps (WARP *Warps)
  995. {
  996.  WARP *Temp1 = Warps;
  997.  WARP *Temp2;
  998.  
  999.  while (Temp1!=NULL)
  1000.  {
  1001.    Temp2 = Temp1->Next_Warp;
  1002.  
  1003. #ifdef DisplaceWarpPatch
  1004.    if(Temp1->Warp_Type == DISPLACE_WARP)
  1005.    {
  1006.        Destroy_Pigment(((DISP_WARP*)Temp1)->Pig);
  1007.    }
  1008. #endif
  1009. #ifdef TransformableWarpsPatch
  1010.     if(Temp1->Warp_Transform != NULL)
  1011.         Destroy_Transform(Temp1->Warp_Transform);
  1012. #endif
  1013.    POV_FREE(Temp1);
  1014.    
  1015.    Temp1 = Temp2;
  1016.  }
  1017. }
  1018.  
  1019.  
  1020.  
  1021. /*****************************************************************************
  1022. *
  1023. * FUNCTION
  1024. *
  1025. * INPUT
  1026. *   
  1027. * OUTPUT
  1028. *   
  1029. * RETURNS
  1030. *   
  1031. * AUTHOR
  1032. *   
  1033. * DESCRIPTION
  1034. *
  1035. * CHANGES
  1036. *
  1037. ******************************************************************************/
  1038.  
  1039. WARP *Copy_Warps (WARP *Old)
  1040. {
  1041.   WARP *New;
  1042.  
  1043.   if (Old != NULL)
  1044.   {
  1045.     New=Create_Warp(Old->Warp_Type);
  1046. #ifdef TransformableWarpsPatch
  1047.     New->Warp_Transform = Copy_Transform(Old->Warp_Transform);
  1048. #endif
  1049.     switch (Old->Warp_Type)
  1050.     {
  1051. #ifdef DisplaceWarpPatch
  1052.        case DISPLACE_WARP:
  1053.          memcpy(New,Old,sizeof(DISP_WARP));
  1054.          ((DISP_WARP*)New)->Pig = Copy_Pigment(((DISP_WARP*)Old)->Pig);
  1055.          break;
  1056. #endif 
  1057. #ifdef PatternWarpPatch
  1058.        case CYLINDRICAL_WARP:
  1059.          memcpy(New,Old,sizeof(CYLW));
  1060.          break;
  1061.      
  1062.        case PLANAR_WARP:
  1063.          memcpy(New,Old,sizeof(PLANARW));
  1064.          break;
  1065.      
  1066.        case SPHERICAL_WARP:
  1067.          memcpy(New,Old,sizeof(SPHEREW));
  1068.          break;
  1069.      
  1070.        case TOROIDAL_WARP:
  1071.          memcpy(New,Old,sizeof(TOROIDAL));
  1072.          break;
  1073. #endif         
  1074.        /* NK 1998 reset_children */
  1075.        case RESET_CHILDREN_WARP:
  1076.          memcpy(New,Old,sizeof(WARP));
  1077.          break;
  1078.        /* NK ---- */
  1079.  
  1080.        case CLASSIC_TURB_WARP:
  1081.        case EXTRA_TURB_WARP:
  1082.          memcpy(New,Old,sizeof(TURB));
  1083.          break;
  1084.      
  1085.        case REPEAT_WARP:
  1086.          memcpy(New,Old,sizeof(REPEAT));
  1087.          break;
  1088.      
  1089.        case BLACK_HOLE_WARP:
  1090.          memcpy(New,Old,sizeof(BLACK_HOLE));
  1091.          break;
  1092.      
  1093.        case TRANSFORM_WARP:
  1094.          memcpy(New,Old,sizeof(TRANS));
  1095.          break;
  1096.     }
  1097.     New->Next_Warp=Copy_Warps(Old->Next_Warp);
  1098.   }
  1099.   else
  1100.   {
  1101.     New=NULL;
  1102.   }
  1103.   return(New);
  1104. }
  1105.  
  1106.  
  1107. /*****************************************************************************
  1108. *
  1109. * FUNCTION
  1110. *
  1111. * INPUT
  1112. *   
  1113. * OUTPUT
  1114. *   
  1115. * RETURNS
  1116. *   
  1117. * AUTHOR
  1118. *   
  1119. * DESCRIPTION
  1120. *
  1121. * CHANGES
  1122. *
  1123. ******************************************************************************/
  1124.  
  1125. #ifdef DisplaceWarpPatch/*Chris Huff 6/25/2000 added ability to warp with pigment colors*/
  1126. static int displace_point(VECTOR EPoint,  DISP_WARP * Warp)
  1127. {
  1128.     COLOUR col;
  1129.     if(Warp->type == 0)
  1130.     {
  1131.         Compute_Pigment(col, Warp->Pig, EPoint, NULL);
  1132.         
  1133.         EPoint[X] += col[0];
  1134.         EPoint[Y] += col[1];
  1135.         EPoint[Z] += col[2];
  1136.     }
  1137.     else
  1138.     {
  1139.         int k = 0;
  1140.         DBL centerVal = 0;
  1141.         DBL tempVal = 0;
  1142.         VECTOR dir;
  1143.         VECTOR evalPoint;
  1144.         Make_Vector(dir, 0, 0, 0);
  1145.         
  1146.         Assign_Vector(evalPoint, EPoint);
  1147.         Compute_Pigment(col, Warp->Pig, evalPoint, NULL);
  1148.         centerVal = GREY_SCALE(col);
  1149.         
  1150.         for(k=0; k<3; k++)
  1151.         {
  1152.             Assign_Vector(evalPoint, EPoint);
  1153.             evalPoint[k] += Warp->dist;
  1154.             Compute_Pigment(col, Warp->Pig, evalPoint, NULL);
  1155.             tempVal = (centerVal - GREY_SCALE(col));/*Warp->dist;*/
  1156.             dir[k] += tempVal;
  1157.             
  1158.             Assign_Vector(evalPoint, EPoint);
  1159.             evalPoint[k] -= Warp->dist;
  1160.             Compute_Pigment(col, Warp->Pig, evalPoint, NULL);
  1161.             tempVal = (centerVal - GREY_SCALE(col));/*Warp->dist;*/
  1162.             dir[k] -= tempVal;
  1163.         }
  1164.         
  1165.         VAddEq(EPoint, dir);
  1166.     }
  1167.     
  1168.     return 1;
  1169. }
  1170. #endif
  1171.