background{ color rgb <0.53, 0.81, 0.92> }

#declare roleta = seed(31415);

#declare raio_canos = 0.25;
#declare comprimento_tocos = 0.5;

#declare A = array[1000];
#declare N = 0;

#declare tx_tq =
  texture {
    pigment { color rgb <1, 0.1, 0.1> }
    finish { diffuse 0.9 ambient 0.1 }
  }

#declare tx_cano =
  texture {
    pigment { color rgb <0.2, 0.2, 0.2> }
    finish { diffuse 0.7 ambient 0.1 metallic reflection 0.05 }
  }

#macro tanque_1(xx, yy)
  #local q1 = <0, 0, 3 + comprimento_tocos>;
  #local q2 = <1 + comprimento_tocos, 0, 1>;
  #local q3 = <-1 - comprimento_tocos, 0, 1>;
  #local q4 = <0, 1 + comprimento_tocos, 1>;
  #local q5 = <0, -1 - comprimento_tocos, 1>;

  #local tanque =
    union {
      // tanque
      union {
        cylinder {
          <0, 0, 0>,
          <0, 0, 2>,
          1
        }
        cone {
          <0, 0, 2>, 0.5
          <0, 0, 3>, 0.25
        }

        texture { tx_tq }
      }

      // canos
      union {
        cylinder {
          <0, 0, 3>,
          q1,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q2,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q3,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q4,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q5,
          raio_canos 
        }

        texture { tx_cano }
      }

    }
  
  #declare A[N] = q1; #declare N = N + 1;
  #declare A[N] = q2; #declare N = N + 1;
  #declare A[N] = q3; #declare N = N + 1;
  #declare A[N] = q4; #declare N = N + 1;
  #declare A[N] = q5; #declare N = N + 1;

  tanque translate <xx, yy, 0>
#end

#macro tanque_2(xx, yy)
  #local q1 = <0, 0, 3 + comprimento_tocos>;
  #local q2 = <1 + comprimento_tocos, 0, 1>;
  #local q3 = <-1 - comprimento_tocos, 0, 1>;
  #local q4 = <0, 1 + comprimento_tocos, 1>;
  #local q5 = <0, -1 - comprimento_tocos, 1>;

  #local tanque =
    union {
      // tanque
      union {
        box {
          <-1, -1, 0>, <1, 1, 2>        
        }
        cylinder {
          <0, 0, 2>,
          <0, 0, 3>,
          1
        }

        texture { tx_tq }
      }

      // canos
      union {
        cylinder {
          <0, 0, 3>,
          q1,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q2,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q3,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q4,
          raio_canos 
        }

        cylinder {
          <0, 0, 1>,
          q5,
          raio_canos 
        }

        texture { tx_cano }
      }
    }

  #declare A[N] = q1; #declare N = N + 1;
  #declare A[N] = q2; #declare N = N + 1;
  #declare A[N] = q3; #declare N = N + 1;
  #declare A[N] = q4; #declare N = N + 1;
  #declare A[N] = q5; #declare N = N + 1;

  tanque translate <xx, yy, 0>
#end

#macro tanque_3(xx, yy)
  #local q1 = <0, 0, 3 + comprimento_tocos>;
  #local q2 = <1 + comprimento_tocos, 0, 2>;
  #local q3 = <-1 - comprimento_tocos, 0, 2>;
  #local q4 = <0, 1 + comprimento_tocos, 2>;
  #local q5 = <0, -1 - comprimento_tocos, 2>;

  #local tanque =
    union {
      // tanque
      union {
        cone {
          <0, 0, 0>, 1
          <0, 0, 2>, 0.25
        }
        sphere {
          <0, 0, 2>, 1
        }

        texture { tx_tq }
      }

      // canos
      union {
        cylinder {
          <0, 0, 3>,
          q1,
          raio_canos 
        }

        cylinder {
          <0, 0, 2>,
          q2,
          raio_canos 
        }

        cylinder {
          <0, 0, 2>,
          q3,
          raio_canos 
        }

        cylinder {
          <0, 0, 2>,
          q4,
          raio_canos 
        }

        cylinder {
          <0, 0, 2>,
          q5,
          raio_canos 
        }

        texture { tx_cano }
      }
    }

  #declare A[N] = q1; #declare N = N + 1;
  #declare A[N] = q2; #declare N = N + 1;
  #declare A[N] = q3; #declare N = N + 1;
  #declare A[N] = q4; #declare N = N + 1;
  #declare A[N] = q5; #declare N = N + 1;

  tanque translate <xx, yy, 0>
#end

#macro tubulacao(p, q)
  // Conecta dois canos (funcional)
  #local altura = 10*rand(roleta);
  #local tubo =
    union {
      cylinder {
        <p.x, p.y, p.z>,
        <p.x, p.y, altura>,
        raio_canos
      }

      sphere {
        <p.x, p.y, altura> raio_canos
      }
      
      cylinder {
        <q.x, q.y, q.z>,
        <q.x, q.y, altura>,
        raio_canos
      }

      sphere {
        <q.x, q.y, altura> raio_canos
      }

      cylinder {
        <p.x, p.y, altura>,
        <q.x, q.y, altura>,
        raio_canos
      }

      texture { tx_cano }
    }

  tubo
#end

#macro gera_tubulacoes()
  #local a = 0;
  #local b = N - 1;
  union {
    #while (a < b)
      object { tubulacao(A[a], A[b]) }

      #local a = a + 1;
      #local b = b - 1;
    #end
  }
#end

#macro gera_tanques(m, n)
  #local tam_grade = 4;

  #local i = 0;
  union {
    #while (i < m)
      #local j = 0;
      #while (j < n)
        #declare tipo_tq = int(3 * rand(roleta));

        #if (tipo_tq = 0)
          object { tanque_1(i * tam_grade, j * tam_grade) }
        #else
          #if (tipo_tq = 1)
            object { tanque_2(i * tam_grade, j * tam_grade) }
          #else
            object { tanque_3(i * tam_grade, j * tam_grade) }
          #end
        #end

        #local j = j + 1;
      #end
      #local i = i + 1;
    #end
  }

#end

object { gera_tanques(3, 4) }

//object { gera_tubulacoes() }

// object { tanque_1(-2, -2) }
// object { tanque_2(2, -2) }
// object { tanque_3(2, 2) }

// object { tubulacao(<-2, -2, 3>, <2, -2, 3>) }

#include "camlight.inc"
#declare centro_cena = < 0.00, 0.00, 9.00 >;
#declare raio_cena = 15.0;
#declare dir_camera = < -3.00, -4.00, 7.00 >;
#declare dist_camera = 5*raio_cena;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)