// ======================================================================
// CORES E TEXTURAS

background{ color rgb <0.75, 0.80, 0.85> }

#declare tx_tank_silver_body = 
  texture{
    pigment { color rgb <0.4, 0.4, 0.4> }
    finish { diffuse 0.5 reflection 0.1 *<0.8, 0.8, 0.8> ambient 0.2 }
  }

#declare tx_tank_golden_body = 
  texture{
    pigment { color rgb < 0.7, 0.7, 0.4 > }
    finish { diffuse 0.4 reflection 0.2 *< 1.00, 1.00, 1.00 > ambient 0.1 }
  }


// ======================================================================
// DESCRIÇÃO DA CENA 

#declare s = seed(360);

#declare grid_size = 3;

#declare tank_types = array[3];
#declare tank_types[0] =
  union {
    cylinder {
      <0, 0, 0>, <0, 0, 1>, 1.2
    }

    cylinder {
      <0, 0, 1>, <0, 0, 3>, 0.5

      texture { tx_tank_silver_body }
    }

    cylinder {
      <0, 0, 3>, <0, 0, 4>, 1.2
    }

    cylinder {
      <0, 0, 2>, <2, 0, 2>, 0.15
      texture { tx_tank_silver_body }
    }

    cylinder {
      <0, 0, 2>, <-2, 0, 2>, 0.15
      texture { tx_tank_silver_body }
    }

    cylinder {
      <0, 0, 2>, <0, 2, 2>, 0.15
      texture { tx_tank_silver_body }
    }

    cylinder {
      <0, 0, 2>, <0, -2, 2>, 0.15
      texture { tx_tank_silver_body }
    }

    texture { tx_tank_golden_body }
  }

#declare tank_types[1] =
  union {
    cone {
      <0, 0, 0>, 1.5
      <0, 0, 1.9>, 0.7

      texture { tx_tank_golden_body }
    }

    cone {
      <0, 0, 1.9>, 0.7
      <0, 0, 3.8>, 1.5
    }

    difference {
      sphere {
        <0, 0, 3.8>, 1.8
      }

      box {
        <-3, -3, 2>, <2, 2, 4.8>
      }

      translate <0, 0, -1>

      texture { tx_tank_golden_body }
    }

    cylinder {
      <0, 0, 3>, <2, 0, 3>, 0.15
    }

    cylinder {
      <0, 0, 3>, <-2, 0, 3>, 0.15
    }

    cylinder {
      <0, 0, 3>, <0, 0, 5.5>, 0.15
    }

    texture { tx_tank_silver_body }
  }

#declare tank_types[2] =
  union {
    box {
      <-1.5, -1.5, 0>,
      <-0.3, -0.3, 1.2>
      texture { tx_tank_golden_body }
    }

    box {
      <-1.5, 1.5, 0>,
      <-0.3, 0.3, 1.2>
      texture { tx_tank_golden_body }
    }

    box {
      <1.5, -1.5, 0>,
      <0.3, -0.3, 1.2>
      texture { tx_tank_golden_body }
    }

    box {
      <1.5, 1.5, 0>,
      <0.3, 0.3, 1.2>
      texture { tx_tank_golden_body }
    }

    cylinder {
      <0.9, 0.9, 0>, <0.9, 0.9, 3>, 0.15
    }

    cylinder {
      <-0.9, -0.9, 0>, <-0.9, -0.9, 3>, 0.15
    }

    cylinder {
      <-0.9, 0.9, 0>, <-0.9, 0.9, 3>, 0.15
    }

    cylinder {
      <0.9, -0.9, 0>, <0.9, -0.9, 3>, 0.15
    }

    cylinder {
      <0.9, 0.9, 2.2>, <0.9, -0.9, 2.2>, 0.15
    }

    cylinder {
      <0.9, 0.9, 2.2>, <-0.9, 0.9, 2.2>, 0.15
    }

    cylinder {
      <-0.9, -0.9, 2.2>, <0.9, -0.9, 2.2>, 0.15
    }

    cylinder {
      <-0.9, -0.9, 2.2>, <-0.9, 0.9, 2.2>, 0.15
    }

    texture { tx_tank_silver_body }
  }

#macro connect_outputs (connections, pipes, pipe_count, scale_ratio)
  union {
    #for (pipe_index, 0, connections - 1)
      #local socket_1 = floor(pipe_count * rand(s));
      #local output_position_1 = pipes[socket_1];
      #local pipes[socket_1] = pipes[pipe_count - 1];
      #local pipe_count = pipe_count - 1;

      #local socket_2 = floor(pipe_count * rand(s));
      #local output_position_2 = pipes[socket_2];
      #local pipes[socket_2] = pipes[pipe_count - 1];
      #local pipe_count = pipe_count - 1;

      #local height = 6 * scale_ratio + 4 * rand(s);

      union {
        cylinder {
          output_position_1,
          <output_position_1.x, output_position_1.y, height>,
          0.15 * scale_ratio
        }

        cylinder {
          <output_position_1.x, output_position_1.y, height>,
          <output_position_2.x, output_position_2.y, height>,
          0.15 * scale_ratio
        }

        cylinder {
          <output_position_2.x, output_position_2.y, height>,
          output_position_2,
          0.15 * scale_ratio
        }

        texture { tx_tank_silver_body }
      }
    #end
  }
#end

#macro tank_grid (m, n, connections)
  #local pipe_count = 0;
  #local pipes = array[m * n * 4];
  #local scale_ratio = 0.5;

  union {
    #for (coord_y, 0, m - 1)
      #for (coord_x, 0, n - 1)
        #local type_index = floor(3 * rand(s));
        #local grid_x = -5 + coord_x * grid_size + grid_size / 2;
        #local grid_y = -5 + coord_y * grid_size + grid_size / 2;

        object {
          tank_types[type_index]
          scale scale_ratio
          translate <grid_x, grid_y, 0>
        }

        #switch (type_index)
          #case (0)
            #local pipes[pipe_count] = <grid_x + 2 * scale_ratio, grid_y, 2 * scale_ratio>;
            #local pipes[pipe_count + 1] = <grid_x - 2 * scale_ratio, grid_y, 2 * scale_ratio>;
            #local pipes[pipe_count + 2] = <grid_x, grid_y + 2 * scale_ratio, 2 * scale_ratio>;
            #local pipes[pipe_count + 3] = <grid_x, grid_y - 2 * scale_ratio, 2 * scale_ratio>;
            #local pipe_count = pipe_count + 4;
          #break
          #case (1)
            #local pipes[pipe_count] = <grid_x, grid_y, 5.5 * scale_ratio>;
            #local pipes[pipe_count + 1] = <grid_x - 2 * scale_ratio, grid_y, 3 * scale_ratio>;
            #local pipes[pipe_count + 2] = <grid_x + 2 * scale_ratio, grid_y, 3 * scale_ratio>;
            #local pipe_count = pipe_count + 3;
          #break
          #case (2)
            #local pipes[pipe_count] = <grid_x + 0.9 * scale_ratio, grid_y + 0.9 * scale_ratio, 2.2 * scale_ratio>;
            #local pipes[pipe_count + 1] = <grid_x - 0.9 * scale_ratio, grid_y + 0.9 * scale_ratio, 2.2 * scale_ratio>;
            #local pipes[pipe_count + 2] = <grid_x + 0.9 * scale_ratio, grid_y - 0.9 * scale_ratio, 2.2 * scale_ratio>;
            #local pipes[pipe_count + 3] = <grid_x - 0.9 * scale_ratio, grid_y - 0.9 * scale_ratio, 2.2 * scale_ratio>;
            #local pipe_count = pipe_count + 4;
          #break
        #end
      #end
    #end

    object { connect_outputs(connections, pipes, pipe_count, scale_ratio) }
  }
#end

#include "eixos.inc"

union {
  object { tank_grid(4, 4, 15) }
}

#include "camlight.inc"
#declare centro_cena = < 0.00, 0.00, 1.00 >;
#declare raio_cena = 12.0;
#declare dir_camera = < 14.00, 7.00, 6.00 >;
#declare dist_camera = 5*raio_cena;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)