#include "colors.inc"     
#include "math.inc"     
#include "transforms.inc"      


//--------------------------------------
#ifndef (use_campfire_rocks)
#declare use_campfire_rocks = yes;
#end
#ifndef (use_campfire_logs)
#declare use_campfire_logs = yes;
#end
#ifndef (use_campfire_flames)
#declare use_campfire_flames = yes;
#end
#ifndef (use_campfire_sparks)
#declare use_campfire_sparks = yes;
#end
#ifndef (use_campfire_smoke)
#declare use_campfire_smoke = yes;
#end

#ifndef (simple_campfire_rocks)
#declare simple_campfire_rocks = no;
#end
#ifndef (simple_campfire_logs)
#declare simple_campfire_logs = no;
#end
#ifndef (simple_campfire_flames)
#declare simple_campfire_flames = no;
#end
#ifndef (simple_campfire_sparks)
#declare simple_campfire_sparks = no;
#end
#ifndef (simple_campfire_smoke)
#declare simple_campfire_smoke = no;
#end
//--------------------------------------


#declare n_rocks = 15;
#declare R_rocks = seed(12346);
#declare min_rock_rad = .08;
#declare max_rock_rad = .15;

#declare n_logs = 8;
#declare R_logs = seed(1235);
#declare min_log_rad = .03;
#declare max_log_rad = .10;

#declare use_campfire_flames = yes;
#declare use_campfire_sparks = no;
#declare use_campfire_smoke = no;



#macro draw_rock(rad)
// rad: Radius of rock  
  sphere {
    0, rad
    texture {
      pigment {color <.9, .8, .7>}
      normal {agate scale .3*rad rotate 180*rand(R_rocks)}
    } 
    scale <1, .5, 1>
  }
#end

#macro draw_log(len, rad)
// v1: Vector that points to one end of the log.
// v2: Vector that points to other end of the log.
// rad: Radius of log      
  cylinder {
    <0,rad,0>, <len,rad,0> , rad
    no_shadow
    texture {
      pigment {
        crackle
        color_map {     
          [.0 Brown/2]
          [.9 Red+Yellow]
        } 
        scale .1
      } 
      finish {ambient .5}
      normal {bumps 2 scale <.1, .01, .01>}
    }
  }
#end

#macro new_log(v1, v2, rad)
object {
  #declare vv = v2 - v1;
  draw_log(vlength(vv), rad)
  #if (v2.z > v1.z)   
    #declare sign = -1;
  #else
    #declare sign = +1;
  #end
  rotate sign * VAngleD(vv,x)*y
  translate v1  
}
#end

#declare campfire = 
union {                                

  // ----- ground, ashes, charcoal, and embers ----- 
  
  disc {
    0, y, 1
    texture {
      pigment {
        onion
        color_map {  
          [.10 Red+Yellow+White]
          [.22 Black]
          [.25 White]
          [.30 White]
          [.50 Clear]
        } 
        scale 2 
        turbulence .1
      }    
      normal {bozo 2 scale .05} 
      translate <-.1, 0, -.1>
    }
  }

  // ----- rocks -----
  #if (use_campfire_rocks)
    #declare i = 0;
    #while (i < n_rocks)
      #declare rad = min_rock_rad + (max_rock_rad - min_rock_rad) * rand(R_rocks);
      #declare dist = 1 + min_rock_rad;
      #declare angl = 360/n_rocks * (i + .7 * (rand(R_rocks) - .5));
      #declare vpos = vrotate(dist*x, angl*y);

      object {draw_rock(rad) translate vpos}

    #declare i = i + 1;
    #end
  #end

  // ----- logs -----
  #if (use_campfire_logs)
    #declare i = 0;
    #while (i < n_logs)
      #declare rad = min_log_rad + (max_log_rad - min_log_rad) * rand(R_logs);
      #declare dist = rand(R_logs) - 2*max_rock_rad;
      #declare angl = 360 * rand(R_logs);
      #declare v1 = vrotate(dist*x, angl*y);
      
      #declare v2 = v1;
      #while (vlength(v2-v1) < max_log_rad)
        #declare dist = rand(R_logs) - 2*max_rock_rad;
        #declare angl = angl + 90 + 180 * rand(R_logs);
        #declare v2 = vrotate(dist*x, angl*y);
      #end
      
      #ifndef (log_union)
        #declare log_union = 
        object {new_log(v1, v2, rad)} 
      #else        
        
                               
        // use trace() to find the _actual_ position of the log                
        #declare height = 0;  
        #declare trans = transform {translate 0}
        #declare j = 0.0;
        #while (j < 1.0)       
          #declare norm = <0, 0, 0>;
          #declare vv = v1 + j*(v2-v1);   
          #declare j = j + .1;          
          #declare h = trace(log_union, vv+10*y, -y, norm).y;
          
          #if (vlength(norm) = 0)
            #declare h = 0;
          #end                             
          
          #if (h > height)
            #declare height = h;       
            #if (j < .5)              
              #declare angl = i*10*vnormalize(vcross(y, v2-v1));
            #else               
              #declare angl = i*10*vnormalize(vcross(y, v1-v2));
            #end   
            #declare trans =
            transform {   
              Rotate_Around_Trans(angl, vv)
              translate h*y
            }
          #end
        #end    
        
        
        #declare log_union =
        union {
          object {log_union}
          object {new_log(v1, v2, rad) transform {trans}}
        } 
      #end 

    #declare i = i + 1;
    #end           
    object {
      log_union
      clipped_by {
       plane {y, .5}
      }
    }
  #end               

  // ----- flames -----
  #if (use_campfire_flames)
    #include "particle\particle.inc"
    #declare particle_start  = 0;
    #declare particle_end    = 60;
    #declare particle_cyclic = no;
    #declare particle_steps  = 50;

    #declare particle_frequency = 60;
    #declare particle_life      = 0.7;
    #declare particle_lifeturb  = 0.3;
    #declare particle_seed      = 45648;

    #macro particle_gravity  (Clock,Point) 20*y #end 
    #macro particle_emitting (Clock) on      #end
    #macro particle_emitter  (Clock) <0,0,0> #end
    #macro particle_emitvect (Clock) <0,0,0> #end
    #macro particle_emitturb (Clock) 1.5     #end
    #macro particle_emitobj  (Clock) disc {0, y, .5} #end
    #macro particle_emitobjn (Clock) 0.0     #end

    particle_system ("fire")
    #include "particle\fire.inc"
   
    #declare fire_method     = 1;
    #declare fire_color      = <0.85,0.45,0.15>;
    #declare fire_intensity  = 2.0;
    #declare fire_highlight  = 2.0;
    #declare fire_samples    = 5;
    #declare fire_turbulence = 1.0;
    #declare fire_size       = 1.2;
    #declare fire_stretch    = 0.2;
   
    object {fire_create("fire") scale .25}
  #end

  // OPTIONAL
  // ----- sparks -----
  #if (use_campfire_sparks)
    #declare all_particle_settings = ...;
    particle_system()
  #end

  // ----- smoke -----
  #if (use_campfire_smoke)
    #declare all_particle_settings = ...;
    particle_system()
  #end   
  
}

/*
global_settings {
  max_trace_level 50
  //ambient_light 0
}
   
camera {
  location <0, 1, -3>
  look_at <0, .5, 0>
}
       
light_source {
  <10, 5, -10>
  color White
}   

light_source {
  <-10, 5, 10>
  color White/2
  shadowless
}                                

plane {y, 0 pigment{color White}}

/*    
sphere {
  0, 10000
  pigment{color rgb <.2,0,0>}
  finish {ambient 1}
  hollow
} 
*/

/*
    #declare galaxy_seed = 23339;
    
    #declare star_count = 10000; 
    #declare star_scale = .5;
                                
    #declare galaxy_colouration = 0.6; 
    #declare galaxy_intensity = .7; 
    #declare galaxy_pattern_scale = 2; 
    #declare galaxy_rotate = -60 * y;   
    #declare galaxy_bgstars = false;  
    
    #include "Galaxy.inc"
*/

object {campfire}

*/