// POV-Ray 3.7 include file "Animator.inc"
// author, date: Josh English 2020-08-29
// 
// The CreateScript macro generates two files. An include file to 
// get the variables needed in the animation, and the INI file to
// render the animation.
// 
// Warning: The INI file assumes the output images will go into a 
// folder with the same name as the input file, and the default
// name for each frame is "frame.png"
//
// EXAMPLE USAGE
// -------------
//
// #declare shotlengths = array[4] {1, 3, 2.4, 0.5}
//
// #declare scriptname = "camerascript.inc";
// #if(!file_exists(scriptname))
//   #include "animator.inc"
//   CreateScript(shotlengths, scriptname, "Example")
// #end // if not file_exists

// #include scriptname
// -------------------- (end of example)
// 
// The inculude file will define the following 8 variables in the scene:
// (the given prefix is "Example")
// ExampleShot // sequential shot number; 1, 2, 3, ...
// ExampleLength // length of clock time (number of seconds if clock=1 is 1 second)
// ExampleSceneClock // clock value starting at 0 and ending at ExampleLength
// ExampleLocalClock // normalized value of 0 to 1 through lenth of shot
// ExampleStart // first clock value
// ExampleEnd // last clock value
// ExampleFirstFrame // first frame number of the scene
// ExampleLastFrame // last frame number of the scene

// The frame numbers are dependent on the value set by Animator_Frame_Rate
//
// The ini file will include commented lines for each shot using
// `Subset_Start_Frame` and `Subset_End_Frame`.
//
// The ini file has the same name as the script, with the ".ini" file extension
// instead of ".inc".

// To reset the scripts, simply remove the include file and run your original source
// file to generate a new include file. This will overwrite the INI file at the
// same time.

//---------------------------------------------------------------------------------------
#ifndef( Animator_Inc_Temp)
#declare Animator_Inc_Temp = version;
#version 3.7;

#ifndef (Animator_Frame_Rate)
#declare Animator_Frame_Rate = 60;
#end // ifndef Animator_Frame_Rate
//--------------------------------------------------------------------///////////////////   
//------------------------------------------------------------------------ macro Animator 
#macro CreateScript(scenelengths, // array of timings in clock units
                    filename, // name of the file to write the script
                    prefix, // string to use as the shot variable name                               
           ) //-------------------------------------------------------------------------- 
//--------------------------------------------------------------------------------------- 
#local start = 0.0;
#local stop = 0.0;
//---------------------------------------------------------------------------------------
// macro items
#local ini_name = concat(substr(filename, 0, strlen(filename)-3), ".ini")
#fopen OUT filename write

#write(OUT, "//", filename, "-- created by animator.inc\n")
#write(OUT, "#switch(clock)\n")

#declare Stops = array[dimension_size(scenelengths, 1)+1]
#declare Stops[0] = 0.0;

#for (idx, 0, dimension_size(scenelengths,1)-1, 1)
  #local start = stop;
  #local stop = stop + scenelengths[idx];
  #write(OUT, "  #range(", start, ", ", stop, ")\n")
  #write(OUT, "    #declare ", prefix, "Shot = ", idx+1, ";\n")
  #write(OUT, "    #declare ", prefix, "Length = ", stop, "-", start, ";\n")
  #write(OUT, "    #declare ", prefix, "SceneClock = clock-", start, ";\n")
  #write(OUT, "    #declare ", prefix, "LocalClock = ", prefix, "SceneClock/(", stop, "-", start,");\n")
  #write(OUT, "    #declare ", prefix, "Start = ", start, ";\n")
  #write(OUT, "    #declare ", prefix, "End = ", stop, ";\n")
  #write(OUT, "    #declare ", prefix, "FirstFrame = ", start*Animator_Frame_Rate+1, ";\n")
  #write(OUT, "    #declare ", prefix, "LastFrame = ", stop*Animator_Frame_Rate, ";\n")
  #write(OUT, "  #break\n")
  #declare Stops[idx+1] = stop;
#end // for

#write(OUT, "  #else\n")
#write(OUT, "    #declare ", prefix, "Shot = 0;\n")
#write(OUT, "    #declare ", prefix, "SceneClock = clock;\n")
#write(OUT, "    #declare ", prefix, "LocalClock = ", prefix, "SceneClock;\n")
#write(OUT, "    #declare ", prefix, "Start = 0;\n")
#write(OUT, "    #declare ", prefix, "End = ", stop, ";\n")
#write(OUT, "    #declare ", prefix, "FirstFrame = 0;\n")
#write(OUT, "    #declare ", prefix, "LastFrame = ", stop*Animator_Frame_Rate, ";\n")

#write(OUT, "#end // switch(clock)\n")
#write(OUT, "// total animation time: ", stop, "\n")
#write(OUT, "#declare ", prefix, "Stops = array[", dimension_size(scenelengths, 1)+1, "]\n")
#for (idx, 0, dimension_size(Stops, 1)-1)
  #write(OUT, "#declare ", prefix, "Stops[", idx, "] = ", Stops[idx], ";\n")
#end
#fclose OUT

#fopen INI ini_name write
#write(INI, "; POV-Ray Animation Control File\n")
#write(INI, "; Generated by animator.inc\n")
#write(INI, "Initial_Frame = 1\n")
#write(INI, "Final_Frame = ", stop*Animator_Frame_Rate, " ; ", Animator_Frame_Rate, " frames per second\n")
#write(INI, "Initial_Clock = 0.0\n")
#write(INI, "Final_Clock = ", stop, "\n")
#write(INI, "Cyclic_Animation=off;\n")

#local start = 0.0;
#local stop = 0.0;
#for (idx, 0, dimension_size(scenelengths,1)-1, 1)
  #local start = stop;
  #local stop = stop + scenelengths[idx];
  #write(INI, "\n; Shot ", idx + 1, " Subsets\n")
  #write(INI, "; Subset_Start_Frame = ", start*Animator_Frame_Rate+1, "\n")
  #write(INI, "; Subset_End_Frame = ", stop*Animator_Frame_Rate, "\n")
#end // for

#write(INI, "\nInput_File_Name = ", input_file_name,"\n")
#local ini_name = concat(substr(filename, 0, strlen(filename)-3), ".ini")
#local output = substr(input_file_name, 0, strlen(input_file_name)-3)
#write(INI, "Output_File_Name = ", output,"/frame.png\n")

#write(INI, "\nAntialias=On\n")
#write(INI, "Antialias_Threshold=0.3\n")
#write(INI, "Antialias_Depth=3\n")
#fclose INI
// --------------------------------------------------------------------------------------
#end// of macro ------------------------------------------------------///// end of macro
//--------------------------------------------------------------------///////////////////  

#version Animator_Inc_Temp;
#end
//------------------------------------------------------------------- end of include file


