#ifndef(SPRAYPAINT_INC)
#declare SPRAYPAINT_INC = version;
#version 3.7;
#end

#ifdef(View_POV_Include_Stack)
   #debug "including spraypaint.inc\n"
#end

#include "rand.inc"
#include "math.inc"

// easyBlob macro curtesy of Rune Johansen
#macro easyBlob(_threshold, _visibleRadius, _blobbiness)
     #local _strength = (1 + 1/_blobbiness)*_threshold;
     #local _actualRadius =
          _visibleRadius / sqrt( 1 - sqrt(_threshold / _strength ) );
          _actualRadius, _strength
#end

/***********************************************************
* Name: SprayCan                        Date: Oct 18, 2012  *
*                                                           *
* Auth: Anthony D. Baye                                     *
* Vers: 1.1.0                                              *
* Desc: Creates a blob object from spheres scattered on     *
*    a surface by using the trace() function. The pattern   *
*    can be limited by using the Template keyword.          *
* Args:                                                     *
*    Object -> The environment to trace against.            *
*    Template -> The pigment used to evaluate the pattern.  *
*         If no template is desired, use pigment { rgb 0 }.
*    ePath -> A spline delineating the path of the emitter. *
*    tPath -> A spline delineating the path of the target.  *
*    FlowRate -> The number of particles per second.        *
*         A good value for a scale of 1 unit = 1 foot is    *
*         20000.                                            *
*    Angle -> Maximum angle for the spray cone.             *
*         with a statistically normal distribution, 99.6%   *
*         of the particles should be inside this angle.     *
*    Duration -> The number of seconds it takes to complete *
*         the path.                                         *
*    File -> Name the file that the resulting object will   *
*         be saved in.  No extension required, .inc will be *
*         appended.  If no file is desired, enter "".       *
* Note: Even with optimizations, this macro can still take  *
*    several minutes to parse.                              *
 **********************************************************/
#macro SprayCan(Object, Template, ePath, tPath, flowRate, Angle, Duration, File)

#declare Clock = 1;
#declare Slice_Delta = 1 / (Duration * 24.0);

#if(File != "")
     #fopen paintFile concat(File, ".inc") write
     #write(paintFile, "#declare sprayPaintObject =\nunion {\n")
#end

#declare Pattern =
union {
//     threshold 0.85
#local i = 0;
#while(i < 1)

     #local pCount = 0;
     #while(pCount < flowRate*Slice_Delta*Duration)

          #local PHI = Rand_Normal(0.0, 0.33, RdmA)*(Angle/2);
          #local THETA = Rand_Normal(0.0, 1.0, RdmB)*180;
          #local Z =  vnormalize(tPath(i) - ePath(i));
          #if(abs(vdot(Z,z)) != 1)
               #local X = vcross(Z,z);
               #local Y = vcross(X,Z);
          #else
               #local X = x;
               #local Y = y;
          #end
//          #debug concat("PHI: " str(PHI, 0, 6) "\n")
//          #debug concat("THETA: " str(THETA, 0, 6) "\n")

          #local T = X*sind(PHI)*cosd(THETA) + Y*sind(PHI)*sind(THETA) + Z*cosd(PHI);
          #local T = vnormalize(T);
//          #debug concat("T: " vstr(3, T, ", ", 0, 6) "\n")

          // Begin trace
          #local Norm = <0, 0, 0> ; // degenerate Normal vector.
          #local Start = ePath(i) ; // The object starts here.

          #local Pos = trace (Object, Start,  T,  Norm) ; // And comes to rest here.
//          #debug concat("Pos: " vstr(3, Pos, ", ", 0, 6) "\n")
          // End trace

               #local dP = eval_pigment(Template, Pos);
               
          #if( vlength( <dP.red, dP.green, dP.blue> ) = 0 )
               sphere { Pos, 0.001 }
               #ifdef(paintFile)
                    #write(paintFile, concat("\tsphere { <" vstr(3, Pos, ", ", 0, 6) "> 0.001 }\n"))
               #end
//              sphere { Pos, easyBlob(0.85, 0.001, 0.98) }
          #end

     #local pCount = pCount + 1;
     #end

#local i = i + Slice_Delta;
#end
     }

#local Extents = concat("paint object extends from " vstr(3, min_extent(Pattern), ", ", 0, 3) " to "
     vstr(3, max_extent(Pattern), ", ", 0, 3) "\n")

#ifdef(paintFile)
     #write(paintFile, "\t}\n")
     #write(paintFile, concat("/*\n" Extents "*/\n"))
     #fclose paintFile
     #debug concat("Spraypaint object saved in file \"" File ".inc\"\n")
#end

#debug Extents

     Pattern

#end