/*****************************************************************************
 *
 * Petri Leskinen, Espoo, Finland, Jan 2008
 * Tube-View 'James Bond-like effect
 * leskinen.petri@luukku.com 
 * - please send me a note if you use the code for anything cool !
 *
 *****************************************************************************/
<languageVersion: 1.0;> // The languageVersion is required in PixelBender files. This was added in the 2nd pre-release, and MUST be declared on the first line (comments excluded)
kernel TubeView
// Added namespace, vendor, version, and description information. A namespace value is required (pre-release 2 and up) and was not supplied.
<   
    namespace : "by Petri Leskinen, Espoo, Finland, Jan 2008"; // namespace was changed from nameSpace in the 2nd pre-release
    vendor : "";
    version : 1;
    description : "Tube-View 'James Bond-like effect";
>

{
   
   input image4 src;
   output float4 pxl;
   
    parameter float radius 
    <       
        minValue:float(40.0);
        maxValue:float(300.0); 
        defaultValue:float(200.0);
    >;

    parameter float turbulence
     <       
        minValue:float(-3.14);
        maxValue:float(3.14); 
        defaultValue:float(1.0);
        description: "Turbulence";
    >;    
    parameter float fade1
     <       
        minValue:float(-1.0);
        maxValue:float(1.0); 
        defaultValue:float(0.2);
        description: "Fading on the edge of the tube";
    >;
    parameter float fade2
     <       
        minValue:float(0.0);
        maxValue:float(2.0); 
        defaultValue:float(0.4);
        description: "Fading by distance";
    >;
    
    parameter float2 center
    <
        minValue:float2(100.0, 0.0);
        maxValue:float2(400.0, 400.0);
        defaultValue:float2(275.0, 200.0);
        description: "Center point";
    >;
    parameter float4 bgColor
    <
        minValue:float4(0.0, 0.0, 0.0, 0.0);
        maxValue:float4(1.0, 1.0,1.0,1.0);
        defaultValue:float4(0.0, 0.0, 0.0, 1.0);
        description: "Background color";
    >;
    
    
    void evaluatePixel()
    {
        // point relative to center
        float2 p = outCoord() -center;
        
        // relative distance from center, rel<0.0 if inside the circle
        float rel = length(p) /radius;
        float tmp = rel*rel;
        rel -= 1.0;
        
        // if outside, modify point location, new coordinates inside circle
        p /= (rel < 0.0) ? 1.0 : tmp ;
        
        // 'turbulence'-rotation
        float rotAngle =  turbulence *( rel < 0.0 ? 0.0 : rel ) ;
        p = float2(p.x*cos(rotAngle)-p.y*sin(rotAngle),
            p.x*sin(rotAngle)+p.y*cos(rotAngle) );
        
        // sample pixel from new location
        pxl= sample(src, center+p);
        
        // mix with bgColor according to distance
        float mx = fade1+ rel*fade2;
        pxl= mix(pxl, bgColor, rel < 0.0 ? 0.0 : mx );
        
   }
}