Objetos del Deseo |
Es estupendo poder hacer todas estas cosillas, pero si solo somos capaces de crear cajas, conos, esferas y cilindros, ¿hasta donde podrémos llegar? No semasiado lejos. Ese es el motivo por el que VRML posee unos cuantos nodos geométricos más. Puedes usarlos para construir formas sencillas o complejas para tus mundos. Voy a cubrir ahora los campos básicos de estos nodos, para que puedas usarlos. Cubriré campos más complejos que te permitan cambiar el aspecto de estos nodos más adelante, en el próximo capítulo. Bueno, comenzaremos con el el nodo fundamental de los que pertenecen a la geometría avanzada: el nodo IndexedFaceSet.
IndexedFaceSet
El nodo IndexedFaceSet es una colección de caras, que puedes
definir manualmente, y permiten construir tus propios objetos con cualquier
forma. La idea básica es muy sencilla, y se muestra en el diagrama
inferior:
Supon que quieres definir un cubo, o parte de un cubo. Primero necesitas definir los ocho vértices, numerados del 0 al 7 en el diagrama. Ahora necesitas definir las caras. Si quieres definir la cara que tiene pintada la cruz azul, debes decir que usa los vértices 1,2,6 y 5. Y esto es todo lo que hay. Haz lo mismo para cada cara, y lo habrás acabado. Una palabra de aviso: si los vértices de una cara no son coplanares (esto es, no definen un área plana), entonces los navegadores se harán un lío y los resultados serán indefinidos. Es mejor usar caras triangulares, con solo tres vértices por cara, y de esta manera estarás seguro de que siempre serán coplanares. Si quieres más vértices por cara, sé cuidadoso. En cualquier caso, simpre puedes construir tus figuras a partir de caras triangulares, lo que es probablemente lo mejor que puedes hacer.
La sintaxis actual de un nodo IndexedFaceSet básico es tal y como sigue:
IndexedFaceSet { SFNode coord NULL MFInt32 coordIndex [] SFBool solid TRUE }
El campo coord contiene un nodo Coordinate, que consiste en una simple lista de puntos 3D, tal y como se muestra en el ejemplo de abajo. Estos son los puntos en que consistirá tu indexedFaceSet El siguiente campo es coordIndex. Es la lista de las caras. Para definir una cara, debes introducir el índice de cada punto en la llista, seguido de un -1 para indicar que una cara ha acabado y que otra puede comenzar. El índice del punto es el número en que aparece en la lista. Si estás de frente a la cara, los valores de los índices deben introducirse en sentido contrario a las agujas del reloj. El único campo aparte de estos es solid (macizo). Si tu objeto no está completamente cerrado, deberás decir al navegador que se preocupe en mostrar también el "envés" de las caras, de otro modo no lo hará. De manera que puedes dejar solid a FALSE en este caso. El ejemplo inferior define una caja sin dos de sus caras, por lo que no es maciza. Podrás ver el resultado del ejemplo al final del capítulo. Hay más cosas que puedes hacer en un indexedFaceSet, pero implica uso de normales y colores, que todavía no hemos visto. Lo crubriremos en el próximo capítulo.
coord Coordinate {
point [ -2 0 2, 2 0 2, 2 0 -2,
-2 0 -2
-2 4 2, 2 4 2, 2 4 -2, -2 4 -2]
}
coordIndex [0 4 7 3 -1
1 2 6 5 -1
4 5 6 7 -1
2 3 7 6 -1 ]
solid FALSE
}
IndexedLineSet
Un nodo relativamente similar al IndexedFaceSet es el IndexedLineSet. Este nodo define un número de líneas que se dibujan entre una serie de coordenadas. Esto es útil para tener líneas muy delgadas, o para representar sólo la malla de un objeto. Se realiza exactamente de la misma manera que con los indexedFaceSet, excepto por el hecho de que no hay un campo solid y el campo coordIndex especifica el índice del punto entre cada línea, con un -1 entre cada una.
IndexedLineSet { SFNode coord NULL MFInt32 coordIndex [] }
las "cuerdas" del ejemplo se realizan con un IndexedLineSet. Las líneas son infinitamente delgadas. Pueden colorearse, pero no mapear con texturas, ya que no hay nada sobre lo que pueda ponerse una textura. Si el campo color del IndexedLineSet está vacío, el color se especifica por el campo emissiveColor del nodo Appearance. Las líneas no son afectadas por detecciones de colisión, de manera que el usuario puede caminar a través suya.
PointSet
Una vez más, de manera prácticamente idéntica al IndexedLineSet, PointSet define un grupo de puntos en el espacio. Estos son dibujados con el tamaño que decide el navegador, y no hay manera de cambiar éste tamaño hasta el momento. Este nodo es idéntico al anterior, salvo por el hecho de que carece del campo coordIndex, dado que no hay conexión entre los puntos. Los puntos se dibujan de la misma manera que lasa líneas, y no son afectadas por las colisiones.
PointSet { SFNode coord NULL }
ElevationGrid
Los siguientes dos nodos son versiones especializadas y optimizadas del IndexedFaceSet. El primero que cubriré es ElevationGrid. En una palabra, es habitual querer mostrar un suelo. Ahora, un suelo plano no resulta particularmente interesante, de modo que puedes usar un ElevationGrid en su lugar. Esto te permite crear un suelo irregular con distintas alturas. Esto se hace especificando un número de alturas, que se asignan a una cuadrícula. El tamaño de la cuadrícula se especifica con los campos xDimension y zDimension , y xSpacing and zSpacing. Estos definen las dimensiones y espaciadoentre los puntos en las direcciones X y Z. La lista de puntos comienza con aquel que está más alejado en la izquierda, preocediendo hacia el que está más cercano a la derecha, cuando se mira hacia el eje -Z. si el campo solid es TRUE el objeto no podrá ser visto desde abajo.Si es necesario que lo sea, dejalo a FALSE. La sintaxis básica se muestra abajo.
ElevationGrid { MFFloat height [] SFBool solid TRUE SFInt32 xDimension 0 SFFloat xSpacing 0.0 SFInt32 zDimension 0 SFInt32 zSpacing 0.0 } ElevationGrid { xDimension 6 zDimension 6 xSpacing 5.0 zSpacing 5.0 height [ 1.5, 1, 0.5, 0.5, 1, 1.5, 1, 0.5, 0.25, 0.25, 0.5, 1, 0.5, 0.25, 0, 0, 0.25, 0.5, 0.5, 0.25, 0, 0, 0.25, 0.5, 1, 0.5, 0.25, 0.25, 0.5, 1, 1.5, 1, 0.5, 0.5, 1, 1.5] }
En este ejemplo, hay seis puntos las direcciones X y Z, y los puntos están alejados 5 metros en ambas direcciones.Esto genera una cuadrícula de 25 metros a cada lado. Los valores del campo son las alturas de cada punto. El primero se coloca en 0,0, y el último a +25, +25. Este objeto posee también campos más avanzados que podremos ver más tarde.
Extrusion
El último de estos nodos geométricos que vamos a cubrir es Extrusion. Esto toma una forma o sección en 2D, y la estira a lo largo de una ruta, llamada spine. Puedes alterar incluso el tamaño de cada punto, comprimiendo y expandiendo la sección. La sintaxis se muestra abajo:
Extrusion { SFBool beginCap TRUE MFVec2f crossSection [1 1, 1 -1, -1 -1, -1 1, 1 1] SFBool endCap TRUE MFVec2f scale 1 1 SFBool solid TRUE MFVec3f spine [0 0 0, 0 1 0] MFRotation orientation 0 0 1 0 }
El campo crossSection es una lista de puntos, en sentido contrario a las agujas del reloj, que definen la forma 2D de el objeto a extruir. Esta sección se alarga a través de la linea definida por el campo spine, que es una lista de puntos 3D. A cada punto de esta linea, puedes definir un factor de escala, en el campo scale, que toma por valor una lista de pares de números flotantes, uno por cada para las direcciones X y Z. El campo solid es igual que antes, y los campos beginCap y endCap definen si la extrusión posee o no una "tapa" al comienzo o al final. El campo orientation define una lista de rotaciones, una para cada punto de la linea. Esto te permite un mayor control sobre la forma de tu extrusión. Si no hay rotaciones suficientes para cada punto, los puntos restantes usan la última rotación de la lista. Así, este ejemplo, crearía una extrusión de un cauadradoa través de una linea de cuatro puntos con distintos factores de escala:
Extrusion { crossSection [1 1, 1 -1, -1 -1, -1 1, 1 1] spine [0 0 0, 0 2 0, 1 3 0, 2 3 0] scale [1 1, 1 0.5, 0.5 1, 0.5 0.5] }
Puedes ver cómo queda esta extrusión observando el ejemplo y el código correspondiente. Una cosa importante para tener en cuenta con estrusiones como esta es que al crear la sección 2D, debes repetir el punto de comienzo al final si deseas tener una figura cerrada.
Al Viento
Puedes ver los efectos de todo este material echando un ojo al escenario
de ejemplo. La "tienda" es un IndexedFaceSet, las "cuerdas" son
IndexedLineSet, el suelo es un ElevationGrid y la "cosa"
es un Extrusion. No hay PointSet ya que no se me ha ocurrido
nada decente para introducirlo. En cualquier caso, no necesitas un ejemplo
para todo esto, es todo muy sencillo. En cualquier caso, écha un
ojo al ejemplo de este capítulo:
Tutorial 2.4 World y el
código.
Bien, esto es lo básico sobre los objetos avanzados. En el próximo capítulo cubriremos las normales, colores, y cosas así para que estos objetos luzcan mejor apariencia.