/////////(Copyright) (No modificar estas 11 primeras Lineas)  
// Autor: Antonio Castro Snurmacher (E-mail acastro@ctv.es ) 
// 
// Este fuente puede ser utilizado, distribuido, y modificado
// libremente pero siempre se deberá respetar la propiedad
// intelectual de su autor.  El autor renuncia a todo tipo de
// beneficio económico y no se hace responsable de los
// posibles perjuicios derivados del uso del mismo.  Toda
// modificación queda sujeta a las mismas condiciones de uso
// que el original. En caso de traducción deberá conservarse
// el texto original de esta cabecera y añadirse la traducción
// a continuación de ella.
//
// Ce code source peut-être librement utilisé modifié et distribué
// mais doit toujours rester la propriété intellectuelle de l'auteur
// l'auteur renonce à tous bénéfices économiques et ne peut-être
// être tenu responsable des préjudices éventuels causé par son utilisation.
// Toute modification reste sujette aux mêmes conditions que l'original
// En cas de traduction le présent texte doit être conservé et la traduction
// ajoutée à la suite de celui-ci
/////////////////////////////////////////////////// 
  

//-----------------------------------------------------------
//erizo.pov (1-Mayo-1998)
//-----------------------------------------------------------
// Cette version est destinée à la revue LinuxFocus
//-----------------------------------------------------------

#include "colors.inc"
#include "textures.inc"
#include "balistap.inc"

#declare RadioCuerpo = 5
#declare NumEspinasMeridiano = 40

// Nous définissons la tailles des piquants en fonction de la taille du
// corps des oursins de mer Dans la nature ils ont des piquants plus
// grands en haut et plus petits en bas
#declare LongitudMaximaPua  = RadioCuerpo * 2
#declare LongitudMinimaPua  = RadioCuerpo / 4

// Couler de l'oursin
#declare TexturePua = texture { pigment {VeryDarkBrown} }
#declare TextureCuerpo = texture { pigment {DarkBrown} }

// toutes les définitions qui suivent dépendent des définitions
// précédentes. Nous supposons tout d'abord que le corps des 
// oursins est sphérique. Pi est une constante prédéfini
// comme

#declare pi = 3.1415926535897932384626
#declare LongitudMeridiano  = 2 * pi * RadioCuerpo

// nous supposons qu'ils sont totalement recouverts de piquants coniques
// le rayon à la base d'un piquant sera : 'RadioPua'  

#declare MeridianoPua =  LongitudMeridiano / NumEspinasMeridiano
#declare RadioPua     =  MeridianoPua / 2

// Nous utilisons la notation longitude/latitude sur l'oursin en
// faisant l'analogie avec les parallèles et méridiens terrestres
// Pour recouvrir totalement l'oursin de piquants
// on trace différents cercles : les parallèles, et pour chaque
// on prends un point de départ ; le méridien de l'oursin
// Nous appellerons angle vertical l'angle
// formé entre l'axe de l'oursin et le point de départ d'un 
// parallèle. Aux pôles c'est angle vaudra 0 et 180 et à l'équateur
//  90. En incrémentant régulièrement cet angle on passera par tous les 
// piquants d'un parallèle. Pour calculer l'incrément angulaire
// on fait une règle de trois LongitudMeridiano
// ---> 360 MeridianoPua ---> IncAngVert

#declare IncAngVert   = 360 * MeridianoPua / LongitudMeridiano

// pour que l'oursin ne soit pas dans le sable ni ne flotte dans
// l'eau on calcule ladistance du centre au bout des piquants
// situés sur la partie basse de l'oursin.

#declare CorreccionY = RadioCuerpo + LongitudMinimaPua
camera {
        location < -40, 40, -40>
        look_at < 25, CorreccionY , 25>
}

// Au fond de la mer la lumière vient de plusieurs points à cause de
// la houle en surface. Pour simuler cela on utilise plusieurs
// sources de lumière

light_source { <-200, 300, -200> color White}
light_source { <-300, 300, -100> color White}
light_source { <-100, 300, -300> color White}
light_source { <0, 1200, 0> color White}

// Ensuite pour la coloration de l'eau on utilise en effet atmosphérique

fog { distance 250 color SeaGreen   }

// Le sable est défini de couleur Sienne avec des ondulations de
// grande amplitude.

plane { y, 0
  pigment { Sienna }
  normal {
  ripples 1.0
  frequency 300.0
  }
  finish {
  ambient 0.1
  diffuse 0.9
  }
  scale <3000, 3000, 3000>
}

// ******************* Définition de l'oursin ****************

#declare erizo = object {
union {

// On calcule un parallèle pour chaque valeur de AngVert
// en partant de 0. (0 piquants dans la direction de l'axe
// vertical.  La seconde valeur sera à peut prés située sur le premier
// parallèle, la valeur maximale sera pour 
// AngVert == a 90 car c'est dans la zone de l'équateur qu'il y a
// le maximum de piquants.  les piquants sur un même méridien 
// se calcule en faisant varier l'angle horizontal :
// 'AngHoriz'

#declare AngVert=0
#while (AngVert < 180 )
#declare RadParalelo = abs ( RadioCuerpo * sin(radians(AngVert)))
#declare LongitudParalelo = 2 * pi * RadParalelo
#declare NumEspinasParalelo = LongitudParalelo / MeridianoPua
#declare LongitudPua = LongitudMinimaPua + (   \
     (LongitudMaximaPua-LongitudMinimaPua) * ((180-AngVert)/180) )
// #declare LongitudPua = LongitudMaximaPua
#declare IncAngHoriz = 360 / NumEspinasParalelo
#declare Ybase = RadioCuerpo * cos (radians(AngVert))
#debug concat("\nAngVert=", str(AngVert,5,0), \
   " LongitudPua=", str(LongitudPua,5,0),     \
   "Ybase=", str(Ybase,5,0), "  ");
#declare Ypunta = (RadioCuerpo + LongitudPua)* \
                      cos (radians(AngVert))
#declare AngHoriz=0
#while (AngHoriz < 360)
#declare Xbase = RadParalelo * cos (radians(AngHoriz))
#declare Xpunta = (RadParalelo + LongitudPua) * \ 
                      cos (radians(AngHoriz))
#declare Zbase = RadParalelo * sin (radians(AngHoriz))
#declare Zpunta = (RadParalelo + LongitudPua) * \
                      sin (radians(AngHoriz))  
//#debug concat( "Vert=", str(AngVert,5,0), \
//               "  Horiz=", str(AngHoriz,5,0), \
//               "\n")     
cone { , RadioPua, , 0 
texture { TexturePua }
}
#declare AngHoriz =AngHoriz + IncAngHoriz
#end
#declare AngVert=AngVert+IncAngVert
#end


// Le corps est une sphère.
sphere { <0,0,0> RadioCuerpo
texture { TextureCuerpo }
}

} // end union
// On le situe à une altitude convenable.
translate y*CorreccionY

// Mais comme les oursins ne sont pas sphériques, se que l'on fait est
// est de conserver les proportions sur l'axe des Y et nous augmentons 
// dans un rapport 1.5 les dimensions sur les axes X et Z.

scale <1.5, 1, 1.5>
} // end object erizo

// Ca y est nous avons un oursin parfait, nous allons le dupliquer
// d'abord nous définissons une distance minimale entre eux.

#declare DistanciaMinima = 3 * (RadioCuerpo+LongitudMaximaPua)

// Nous allons les disposer sur un carré 5 * 5.  Pour éviter 
// qu'ils donnent une impression trop géométrique, nous les déplaçons 
// légèrement en X d'une quantité aléatoire.

#declare Xi=0
#declare R1 = seed(0);
#while (Xi < 5)
#declare Yi=0
#while (Yi<5)
#declare Xpos= Xi * DistanciaMinima + \
           ( rand(R1) * DistanciaMinima * 0.5 )

#declare Ypos= Yi * DistanciaMinima + \
           ( rand(R1) * DistanciaMinima * 0.5 )

#debug concat ("\nXpos=", str(Xpos, 5, 0), \
               "  Ypos=", str(Ypos, 5,0))

object {erizo
translate
}
#declare Yi= Yi+1
#end
#declare Xi= Xi+1
#end

// Nous allons placer les poissons en utilisant une méthode 
// analogue à celle des oursins. Nous allons les placer en
// trois groupes de 4 * 4. Nous allons tout d'abord définir une
// distance minimale entre eux.

#declare DistanciaMinima = 90
#declare Xi=0
#declare R1 = seed(0);
#while (Xi < 4)
#declare Yi=0
#while (Yi<4)
#declare Xpos= Xi * DistanciaMinima + \
       ( rand(R1) * DistanciaMinima * 0.5 )

#declare Ypos= Yi * DistanciaMinima + \
      ( rand(R1) * DistanciaMinima * 0.5 )

#debug concat ("\nXpos=", str(Xpos, 5, 0), \ 
      "  Ypos=", str(Ypos, 5,0))

object { Balistap 
         scale  1.2
         rotate y*50*rand(R1)
         translate
        }

object { Balistap 
         scale  1.2
         rotate y*50*rand(R1)
         translate
        }

object { Balistap 
         scale  1.2
         rotate y*50*rand(R1)
         translate
        }
#declare Yi= Yi+1
#end
#declare Xi= Xi+1
#end

// Nous allons placer l'un deux comme s'il mangeait des
// algues au fond de l'eau.

object { Balistap
         scale 1.1
         rotate z* -45
         rotate y*200
         translate<80, 19, 360>
        }

/** Ceci peut nous servir à voir le poisson en entier *****

object { Balistap 
         scale  1.1
         rotate y*225
         translate<25, 40, 25>
        }

**********************