3.5.2  Objeto Mesh2 (nueva malla)

Un mesh2 es una representación de una malla, que en gran parte es más una representación interna de POV-Ray que el objeto mesh estándar. Como resultado, se interpreta más rápido y el tamaño de archivo es menor.

Debido a su naturaleza, mesh2 no es realmente apropiado para construir mallas a mano, está concebido para ser usado por modeladores y conversores de formatos de archivos. Otra opción es construir las mallas con macros. Aun así, para comprender este formato, crearemos un pequeño ejemplo a mano y veremos todas sus opciones.

para ser escrito como mesh2
para ser escrito como mesh2

Vamos a transformar la malla esbozada arriba en un objeto mesh2. La malla está hecha de 8 triángulos, cada uno con tres vértices, muchos de los cuales son compartidos entre los triángulos. Esto se puede utilizar más tarde para optimizar la malla. Primero la configuraremos directamente.

En un mesh2 todos los vértices están recogidos en una lista denominada vertex_vectors{}. Una segunda lista, face_indices{}, nos dice cómo juntar tres vértices para crear un triángulo, apuntando al número de índice de un vértice. Todas las listas en mesh2 están basadas en 0, el número del primer vértice es 0. El primer apartado en una lista es la cantidad de vértices, normales o vectores_uv que contiene. mesh2 tiene que ser especificado en el orden de VECTORS..., LISTS..., INDICES....

Vayamos a través de la malla descrita arriba, lo haremos en el sentido de las agujas del reloj. El número total de vértices es 24 (8 triángulos * 3 vértices)..

mesh2 {
   vertex_vectors {
      24,
      ...

Ahora podemos añadir las coordenadas de los vértices del primer triángulo:

mesh2 {
   vertex_vectors {
      24, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>
      ..

El siguiente paso, es decirle a la malla cómo deben crearse los triángulos; Habrá un total de 8 face_indices (8 triángulos). El primer punto en la primera cara, apunta al primer vertex_vector (0: <0,0,0>), el segundo al segundo (1: <0.5,0,0>), etc...

mesh2 {
   vertex_vectors {
      24, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>
      ...
   }
   face_indices {
      8, 
      <0,1,2> 
      ...

La malla completa:

mesh2 {
   vertex_vectors {
      24, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>, //1
      <0.5,0,0>, <1,0,0>, <0.5,0.5,0>, //2
      <1,0,0>, <1,0.5,0>, <0.5,0.5,0>, //3
      <1,0.5,0>, <1,1,0>, <0.5,0.5,0>, //4
      <1,1,0>, <0.5,1,0>, <0.5,0.5,0>, //5
      <0.5,1,0>, <0,1,0>, <0.5,0.5,0>, //6
      <0,1,0>, <0,0.5,0>, <0.5,0.5,0>, //7
      <0,0.5,0>, <0,0,0>, <0.5,0.5,0>  //8
   }
   face_indices {
      8, 
      <0,1,2>,    <3,4,5>,       //1 2
      <6,7,8>,    <9,10,11>,     //3 4
      <12,13,14>, <15,16,17>,    //5 6
      <18,19,20>, <21,22,23>     //7 8
   }
   pigment {rgb 1}
}

Como se mencionó anteriormente, muchos vértices son compartidos por los triángulos. Podemos optimizar la malla quitando todos los vértices duplicados menos uno. En este ejemplo se reducen la cantidad de 24 a 9.

mesh2 {
   vertex_vectors {
      9, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>,
      /*as 1*/ <1,0,0>,   /*as 2*/
      /*as 3*/ <1,0.5,0>, /*as 2*/
      /*as 4*/ <1,1,0>,   /*as 2*/
      /*as 5*/ <0.5,1,0>, /*as 2*/
      /*as 6*/ <0,1,0>,   /*as 2*/
      /*as 7*/ <0,0.5,0>, /*as 2*/
      /*as 8*/ /*as 0*/   /*as 2*/
   }
   ...
   ...

El siguiente paso es reconstruir la lista de face_indices, ya que ahora apuntan a índices de la lista vertex_vector{} que han desaparecido.

   ...
   ...
   face_indices {
      8, 
      <0,1,2>, <1,3,2>,
      <3,4,2>, <4,5,2>,
      <5,6,2>, <6,7,2>,
      <7,8,2>, <8,0,2>
   }
   pigment {rgb 1}
}

3.5.2.1  Triángulos suaves y mesh2

En el caso de que queramos una malla suave, los mismos pasos que dimos se aplican a las normales en una malla. Para cada vértice hay un vector de normal listado en normal_vectors{}, los duplicados pueden ser eliminados. Si el número de normales es igual al número de vértices entonces la lista normal_indices{} es opcional y los índices de la lista face_indices{} son utilizados en su lugar.

mesh2 {
   vertex_vectors {
      9, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>,
      <1,0,0>, <1,0.5,0>, <1,1,0>,
      <0.5,1,0>, <0,1,0>, <0,0.5,0>   
   }
   normal_vectors {
      9,
     <-1,-1,0>,<0,-1,0>, <0,0,1>,
      /*as 1*/ <1,-1,0>, /*as 2*/
      /*as 3*/ <1,0,0>,  /*as 2*/
      /*as 4*/ <1,1,0>,  /*as 2*/
      /*as 5*/ <0,1,0>,  /*as 2*/
      /*as 6*/ <-1,1,0>, /*as 2*/
      /*as 7*/ <-1,0,0>, /*as 2*/
      /*as 8*/ /*as 0*/  /*as 2*/ 
   }
   face_indices {
      8, 
      <0,1,2>, <1,3,2>,
      <3,4,2>, <4,5,2>,
      <5,6,2>, <6,7,2>,
      <7,8,2>, <8,0,2>
   }
   pigment {rgb 1}
}

Cuando una malla tiene mezclados triángulos suaves y planos ha de añadirse una lista de normal_indices{} donde cada entrada apunta a los vértices a los que debería aplicarse una normal. En el siguiente ejemplo sólo las cuatro primeras normales se usan en realidad.

mesh2 {
   vertex_vectors {
      9, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>,
      <1,0,0>, <1,0.5,0>, <1,1,0>,
      <0.5,1,0>, <0,1,0>,   <0,0.5,0>
   }
   normal_vectors {
      9,
      <-1,-1,0>, <0,-1,0>, <0,0,1>,
      <1,-1,0>, <1,0,0>, <1,1,0>,
      <0,1,0>, <-1,1,0>, <-1,0,0>
   }
   face_indices {
      8, 
      <0,1,2>, <1,3,2>,
      <3,4,2>, <4,5,2>,
      <5,6,2>, <6,7,2>,
      <7,8,2>, <8,0,2>
   }
   normal_indices {
      4, 
      <0,1,2>, <1,3,2>,
      <3,4,2>, <4,5,2>
   }
   pigment {rgb 1}
}

3.5.2.2  Mapeado_UV y mesh2

El mapeado_uv es un método para pegar texturas 2D en un objeto de manera que éstas se acoplen a la forma del objeto. Respecto al mapeado_uv de triángulos, imagínatelo así: primero cortas una sección triangular de una textura desde el plano xy; después estiras, contraes y deformas el trozo de textura para encajar en el triángulo y lo pegas.

Ahora, en mesh2 primero construimos una lista de vectores 2D que son las coordenadas de las secciones triangulares en el plano xy. Esto es la lista uv_vectors{}. En el ejemplo mapeamos la textura del área rectangular <-0.5,-0.5>, <0.5,0.5> a los triángulos en la malla. Nuevamente podemos omitir todas las coordenadas duplicadas

mesh2 {
   vertex_vectors {
      9, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>,
      <1,0,0>, <1,0.5,0>, <1,1,0>,
      <0.5,1,0>, <0,1,0>,   <0,0.5,0>
   }
   uv_vectors {
      9
     <-0.5,-0.5>,<0,-0.5>,  <0,0>,
      /*as 1*/   <0.5,-0.5>,/*as 2*/
      /*as 3*/   <0.5,0>,   /*as 2*/
      /*as 4*/   <0.5,0.5>, /*as 2*/
      /*as 5*/   <0,0.5>,   /*as 2*/
      /*as 6*/   <-0.5,0.5>,/*as 2*/
      /*as 7*/   <-0.5,0>,  /*as 2*/
      /*as 8*/   /*as 0*/   /*as 2*/       
   }
   face_indices {
      8, 
      <0,1,2>, <1,3,2>,
      <3,4,2>, <4,5,2>,
      <5,6,2>, <6,7,2>,
      <7,8,2>, <8,0,2>
   }
   uv_mapping
   pigment {wood scale 0.2}
}

Igual que con los normal_vectors, si el número de uv_vectors es igual al número de vértices, la lista uv_indices{} es opcional y los índices de la lista face_indices{} son utilizados en su lugar.

Al contrario que la lista normal_indices, si se utiliza la lista uv_indices, la cantidad de índices debe ser igual a la cantidad de face_indices. En el siguiente ejemplo sólo se especifica y usa una sección de textura en todos los triángulos, utilizando uv_indices.

mesh2 {
   vertex_vectors {
      9, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>,
      <1,0,0>, <1,0.5,0>, <1,1,0>,
      <0.5,1,0>, <0,1,0>,   <0,0.5,0>
   }
   uv_vectors {
      3
      <0,0>, <0.5,0>, <0.5,0.5>    
   }
   face_indices {
      8, 
      <0,1,2>, <1,3,2>,
      <3,4,2>, <4,5,2>,
      <5,6,2>, <6,7,2>,
      <7,8,2>, <8,0,2>
   }
   uv_indices {
      8, 
      <0,1,2>, <0,1,2>,
      <0,1,2>, <0,1,2>,
      <0,1,2>, <0,1,2>,
      <0,1,2>, <0,1,2>
   }
   uv_mapping
   pigment {gradient x scale 0.2}
}

3.5.2.3  Una textura diferente por triángulo

Al utilizar la lista texture_list es posible especificar una textura por triángulo o incluso por vértice en la malla. En el último caso, las tres texturas por triángulo se interpolarán. Para decirle a POV-Ray qué textura aplicar a un triángulo, se añade el índice de la textura a la lista face_indices, tras el índice de la cara a la que pertenece.

mesh2 {
   vertex_vectors {
      9, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>,
      <1,0,0>, <1,0.5,0>, <1,1,0>   
      <0.5,1,0>, <0,1,0>, <0,0.5,0> 
   }
   texture_list {
      2,
      texture{pigment{rgb<0,0,1>}}
      texture{pigment{rgb<1,0,0>}}
   }
   face_indices {
      8, 
      <0,1,2>,0,  <1,3,2>,1,
      <3,4,2>,0,  <4,5,2>,1,
      <5,6,2>,0,  <6,7,2>,1,
      <7,8,2>,0,  <8,0,2>,1
   }
}

Para especificar una textura por vértice, se añaden tres índices de la lista texture_list tras face_indices

mesh2 {
   vertex_vectors {
      9, 
      <0,0,0>, <0.5,0,0>, <0.5,0.5,0>,
      <1,0,0>, <1,0.5,0>, <1,1,0>   
      <0.5,1,0>, <0,1,0>, <0,0.5,0> 
   }
   texture_list {
      3,
      texture{pigment{rgb <0,0,1>}}
      texture{pigment{rgb 1}}
      texture{pigment{rgb <1,0,0>}}
   }
   face_indices {
      8, 
      <0,1,2>,0,1,2,  <1,3,2>,1,0,2,
      <3,4,2>,0,1,2,  <4,5,2>,1,0,2,
      <5,6,2>,0,1,2,  <6,7,2>,1,0,2,
      <7,8,2>,0,1,2,  <8,0,2>,1,0,2
   }
}

La asignación de una textura basada en una lista texture_list y la interpolación de texturas se realiza en base a triángulos. Por ello es posible mezclar triángulos con una única textura y triángulos con tres texturas en una malla. Incluso es posible mezclarlo con triángulos sin índices de texturas, estos obtendrán sus texturas de una declaración general texture en la mesh2. El mapeado_uv está soportado para el texturizado utilizando una lista texture_list.