You are on page 1of 47

Para crear un mundo de realidad virtual se utiliza un fichero de texto, creado

con un procesador cualquiera de textos que se debe guardar con la


extensin .wrl
Este fichero constituye un documento VRML, que ser ejecutado por el
visualizador, de manera completamente anloga a los documentos HTML, que
son ficheros de texto con la extensin .html y que son ejecutados por los
navegadores para visualizar las pginas del Web.
Tambin se pueden crear estos documentos utilizando ciertos progamas
editores de VRML, que los generan automticamente, sin necesidad de saber
programar en este lenguaje. Se hablar sobre estos programas ms adelante.

Estructura de los documentos VRML


En lneas generales, un documento VRML contiene los siguientes elementos:

Lnea de cabecera

Comentarios al cdigo

Nodos

Lnea de cabecera
Todo documento VRML debe comenzar necesariamente con la siguiente lnea:
#VRML V2.0 utf8

Con esta lnea inicial se hace la declaracin de que el estndar empleado es


el VRML 2.0. El identificativo utf8 sirve para permitir el uso de caracteres
internacionales.
No se debe dejar ningn espacio en blanco antes del comienzo de la lnea
(antes del smbolo #), pues en caso contrario el visualizador no la reconocera,
y dara error al ejecutar el documento VRML.

Comentarios al cdigo
En todos los lenguajes se utilizan comentarios al cdigo, no visibles en la
pantalla, que son muy tiles como recordatorio de lo que se ha hecho y que
facilitan los cambios futuros.
En este lenguaje los comentarios se escriben en una sola lnea que comienza
con el smbolo #. Ejemplo:
# Este es un comentario al cdigo

Nodos
Los nodos son bloques de informacin que definen las caractersticas de un
objeto concreto (su forma, su apariencia, etc.), o la relacin entre distintos
objetos. Sirven tambin para crear sonidos, el panorama de fondo, enlaces a
otros mundos o a pginas Web, etc.
Es decir, son las unidades bsicas que forman el mundo virtual, y pueden ser
afinadas hasta el detalle deseado.
Los nodos son los bloques de informacin bsicos con los que se construye un
mundo virtual. Vamos a ver la sintaxis de los nodos partiendo de los ms
sencillos, los nodos de geometra primitiva, o nodos primitivos, que son:

Box - caja

Cone - cono

Cylinder - cilindro

Sphere - esfera

Con estas figuras geomtricas bsicas, agrupndolas y modificndolas


convenientemente se pueden construir formas ms complicadas.
Para formas realmente complejas, hay otros procedimientos para crear objetos,
partiendo de puntos, lneas o caras.

Box
La estructura ms general de un nodo es:

Box { ... }

Se escribe el nombre del nodo, en este caso Box, seguido del smbolo
de apertura {

A continuacin se escribe el campo, que es un atributo del nodo que


podemos cambiar a voluntad, poniendo los valores que nos interesen.
En este caso servir para establecer las dimensiones de la caja, como
se ver a continuacin.

A continuacin se escribe el smbolo de cierre }

Con respecto a los nombres, y en general cualquier otro comando usado en


este lenguaje, se debe tener muy en cuenta que son sensibles a
las maysculas y minsculas. Es decir, se debe escribir Box y no box, o
fontStyle y no fontstyle, etc.
Sustituyendo ahora los puntos suspensivos por el campo que define este nodo,
que es size (tamao) con sus valores correspondientes (las dimensiones),
queda el nodo completado de esta forma:

Box {size 2 0.5 3}

Los nmeros representan respectivamente la anchura, la altura y el fondo. Son


dimensiones abstractas, pero es conveniente, aunque no obligatorio, suponer
que son metros. El nodo, por tanto, define un paralelepdo (una caja) de 2 m.
de ancho, 0.5 m de alto y 3 m de fondo.
Se ha escrito el nodo en una sla lnea, debido a su sencillez y a que slo tiene
un campo, pero se podra haber escrito de esta otra forma:

Box {

size 2 0.5 3

Cone
Veamos un ejemplo de este nodo, que define la geometra de un cono:

Cone {
}

height 3
bottomRadius 0.75

Como se puede observar, tiene dos campos: height (altura), al que se le ha


puesto el valor de 3, y bottomRadius (radio de la base) el de 0.75. Con estos
dos valores queda perfectamente definido el cono.

Cylinder
Ejemplo del nodo que define un cilindro:

Cylinder {

height 2
radius 1.5
}

Tiene dos campos: height (altura) y radius (radio)

Sphere
Ejemplo del nodo que define una esfera:

Sphere {
radius 1
}

Tiene un solo campo, radius (radio) pues es suficiente para definir con l una
esfera.

Utilizacin de estos nodos


Estos cuatro nodos de geometra primitiva, que acabamos de ver, no se
pueden utilizar directamente ellos solos, sino que son parte integrante de otro
nodo ms general, el nodo Shape (forma), que veremos en el captulo
siguiente.
Es decir, si queremos crear el cono del ejemplo, sera incorrecto crear este
documento VRML:

#VRML V2.0 utf8


#Este documento es incorrecto
Cone {
}

height 3
bottomRadius 0.75

Suponiendo que lo guardramos con el nombre de cono.wrl, por ejemplo, y


tratramos de ejecutarlo en un visualizador, nos dara error o no se vera nada.
El motivo de esto es que estos nodos definen nicamente la geometra de
estos cuerpos, pero no dan ninguna indicacin de cul deber ser
su apariencia, es decir, su color, textura, iluminacin, etc.
En cambio el nodo Shape se encarga de ambas cosas, ya que tiene dos
campos: la apariencia y la geometra, en donde utiliza precisamente estos
nodos que acabamos de ver. Es decir, estos nodos irn incrustados en el
nodo Shape.

Sintaxis de los nodos


Con los ejemplos anteriores podemos entender ms fcilmente el concepto y la
sintaxis (reglas para la correcta escritura) de los nodos, desde un punto de
vista general.

Nombre {
campo1 x y z
campo2 x
...
}

El nodo es un bloque de informacin que tiene un Nombre (Box, Cone,


etc.) Obsrvese que comienzan siempre por una letra mayscula.

Englobados entre los smbolos { y } el nodo tiene uno o


varios campos (size para el nodo Box, height y bottomRadius para el
nodo Cylinder, etc.) Los campos son los atributos variables del nodo.
Obsrvese que comienzan con una letra minscula.

A continuacin est el valor que le asignamos a ese campo, que es un


nmero (o conjunto de nmeros) Estos nmeros se escriben con punto
flotante (es decir, con decimales).

En ocasiones, en lugar de colocar como valor un nmero (o conjunto de


nmeros) se coloca todo un nodo.

para crear un objeto visible se debe utilizar el nodo Shape.


Este nodo tiene dos campos: appearance y geometry. Con el primero se
controla la apariencia del objeto (color, textura, iluminacin, etc.) y con el
segundo su geometra.
Por tanto, la estructura general del nodo es:

Shape {
appearance ...
geometry ...
}

Los puntos suspensivos representan los valores de cada campo.


El primer campo (appearance) es opcional, y se puede prescindir de l, lo que
vamos a hacer de momento por motivo de sencillez en la explicacin. O sea,
que el nodo quedara de esta manera:

Shape {
geometry ...
}

Pero el valor del campo geometry (los puntos suspensivos) es precisamente


uno de los cuatro nodos primitivos que hemos visto en el captulo anterior
(Box, Cone, Cylinder y Sphere).
Escojamos el primero de ellos (Box), del ejemplo del captulo anterior, y
pongmoslo como valor del campo geometry:

Shape {
geometry Box {size 2 0.5 3}
}

Con esto hemos definido un objeto visible (aunque todava sin ningn atributo
de apariencia definido), que tiene la geometra de una caja de medidas 2x0.5x3
Hemos puesto el nodo Box en una sola lnea, pero conviene que lo pongamos
desarrollado en varias lneas, para irnos acostumbrando, pues es muy
importante que los smbolos { y } estn colocados en el orden que les
corresponde, y no olvidarse de ninguno de ellos:

Shape {
geometry Box {
size 2 0.5 3
}
}

Ahora ya estamos en condiciones de crear el primer documento VRML con el


que se podr ver el objeto con el visualizador, aunque todava en unas
condiciones bastante imperfectas, ya que todava no tiene definido ningn
atributo de apariencia.
Para crear el documento VRML slo falta ponerle la lnea de cabecera, y algn
comentario si queremos:

#VRML V2.0 utf8

#Primer documento VRML


#Caja sin apariencia definida
Shape {
geometry Box {
size 2 0.5 3
}
}

Se guarda con el nombre que se quiera, con la extensin .wrl


En este caso, va a ser cap05_caja.wrl Para verlo en el visualizador, basta con
abrir este fichero en el navegador (con el men Archivo/Abrir).
A la derecha se puede ver el resultado.
Como se puede observar en la imagen, las caras del objeto son de color blanco
y no se distinguen unas de otras, pudindose apreciar slamente el contorno
del objeto.
Ahora vamos a dar el siguiente paso: suministrar al objeto unas cualidades de
apariencia (aunque de momento slo van a ser las que existen por defecto)

Poniendo la apariencia por defecto


Como se ha visto al comienzo del captulo, el nodo Shape tiene tambin el
campo appearance, del que habamos prescindido de momento:

appearance ...

Tenemos que poner un valor (los puntos suspensivos) al campo appearance.


No va a ser un nmero (o un conjunto de nmeros), sino
un nodollamado Appearance.
Obsrvese la A mayscula de Appearance, que indica que se trata de un nodo,
mientras que en el caso de appearance la a minscula indica que es
un campo (del nodo Shape).
Veamos, primero por separado, la estructura de este nuevo nodo Appearance:

Appearance {
material Material {
}

Vemos que el nodo Appearance tiene, a su vez, un campo llamado material,


cuyo valor es otro nodo, llamado Material, en el que se ha dejado en blanco su
contenido (no hay nada entre los smbolos { y } del nodo Material), lo que hace
que estn definidas las caractersticas por defecto de este nodo.

Encajando todas las piezas


Todo lo anterior puede parecer a primera vista como algo muy complicado.
Pero no lo es, si consideramos que, en realidad, los nodos son
como mdulos de informacin que encajan unos en otros, formando una red
(de ah su nombre).
Es decir, algo que puede ser muy complejo, tal como un mundo virtual, est
compuesto de pequeas y simples unidades de informacin (los nodos) que
actan como las piezas de un mecano.
Centrndonos en el caso concreto de la caja, vamos a ensamblar las distintas
piezas. Primero, coloquemos el nodo Appearance como el valor
del campo appearance:

appearance Appearance {
material Material {
}

Ahora ya podemos colocar este campo dentro del nodo Shape, en el


documento VRML, con algunos comentarios que faciliten su comprensin:

#VRML V2.0 utf8


#Caja con la apariencia por defecto
Shape {
#Campo appearance:
appearance Appearance {
material Material {
}

#Campo geometry:
geometry Box {
size 2 0.5 3
}
}
Se guarda como cap05_caja1.wrl
A la derecha se puede ver el resultado.
Como se puede apreciar en la figura (y an ms manipulndola con el visualizador), la
diferencia es notable. Ahora se distinguen perfectamente las caras de la caja, debido a que
tienen una iluminacin y textura adecuadas.
Siguiendo un proceso similar para el nodo primitivo Cone, visto en el captulo anterior, el
documento VRML para visualizarlo (tambin con la apariencia por defecto), sera el siguiente:

#VRML V2.0 utf8


#Cono con la apariencia por defecto
Shape {
#Campo appearance:
appearance Appearance {
material Material {
}

#Campo geometry:
geometry Cone {
height 3
bottomRadius 0.75
}
}
Como se puede observar, el campo appearance es idntico al caso anterior, slo cambia
el valor del campo geometry, que es el nodo Cone.
En los mundos virtuales ser a menudo necesario utilizar textos para guiar al visitante (en
forma de carteles, comentarios, paneles de control, etc.) Para ello existe un nodo especfico,
el nodo Text que, al igual que los nodos primitivos, ir incrustado en el nodo Shape, como se
ver ms adelante.
Los textos son siempre planos y no tienen espesor. Se puede determinar el tipo de fuente, su
estilo y tamao, etc.

Estructura del nodo Text


Su estructura general es la siguiente:

Text {
string ...
fontStyle ...
}
Tiene, por tanto, dos campos:

string: (en ingls, fila). Su valor (los puntos suspensivos) es precisamente el texto que
se quiere poner.

fontStyle: su valor (los puntos suspensivos) es un subnodo llamado FontStyle (obsrvese una vez ms que el primero empieza por
minscula, por ser un campo, mientras que el segundo lo hace por mayscula, por ser
un nodo).

El campo fontStyle es opcional. Si se omite, el texto tendr el estilo de fuente por defecto.
Veamos cada campo por separado:

Valor del campo string (el texto)


Se pone de esta manera:

string ["Esta es la primera fila de texto",


"esta es la segunda fila",
"etc."]
Como se puede ver, cada fila de texto va entre comillas, con una coma al final de cada lnea, y
todo ello englobado entre corchetes: [ y ]

Nodo FontStyle
Veamos su estructura con un ejemplo:

FontStyle {
family "SERIF",
style "BOLD",
size 1
spacing 1
}
En este ejemplo, el nodo FontStyle tiene los siguientes campos:

family: Determina la familia de fuente. Se puede escoger


entre "SERIF", "SANS" o "TYPEWRITER" (en ingls, mquina de escribir).
Obsrvese que los nombres estn en maysculas.

style: Se puede escoger entre "BOLD" (negrita), "ITALIC" (cursiva), "BOTH" (ambas,
es decir, negrita y cursiva), o "NONE" (ninguna, es decir, ni negrita ni cursiva).

size: Determina el tamao de la fuente, pero en unidades VRML. Es decir, que si se


adopta que la unidad equivale a un metro (escala aconsejada, pero no obligatoria), en
el caso del ejemplo las letras se supone que tienen un metro de altura.

spacing: Determina la separacin entre lneas, tambin en unidades VRML.

Existen ms campos que los que aparecen en este ejemplo, con los que se puede afinar an
ms la disposicin del texto:

justify: Determina la justificacin del texto. Puede ser "BEGIN" (al comienzo, es decir
a la izquierda), "MIDDLE" (en el medio, es decir, centrado) o "END" (al final, es decir,
a la derecha).

otros: que se omiten aqu, pues estn pensados para idiomas exticos, como el chino
(escritura en vertical), el rabe (escritura de derecha a izquierda), etc. Para la lista
completa, se puede consultar la RFC 1766

Nodo Text completo


Poniendo ahora el nodo texto completo, con sus dos campos, queda de esta forma:

Text {
string ["Esta es la primera fila de texto",
"esta es la segunda fila",
"etc."]
fontStyle FontStyle {
family "SERIF",
style "BOLD",
size 1
spacing 1
}
}

Integrando el nodo Text en el nodo Shape


El nodo Text se incrusta en el nodo Shape, de la misma manera que se haca con los nodos
primitivos. En el captulo anterior vimos que el nodo Shape tena esta estructura:

Shape {
appearance ...
geometry ...
}
Vimos que los nodos primitivos se ponan como valor del campo geometry. Es lo mismo que
vamos a hacer ahora:

Shape {
appearance ...
geometry Text { ... }
}
Aqu est de una manera resumida. Para desarrollarlo completamente, hay que poner como
campo de appearance la apariencia por defecto, y lgicamente, el nodo Text completo.

Como se puede ver en la imagen, el texto se puede manipular como cualquier otro objeto
(girndolo, etc.), ya que, en realidad, es un elemento plano de espesor cero.
Las letras tienen el color por defecto, ya que se ha utilizado la apariencia por defecto. Pero se
puede hacer que tengan el color que se desee, segn veremos ms adelante.

Agrupacin de nodos
Hasta ahora hemos visto los objetos aisladamente. Veamos ahora cmo podemos agrupar un
conjunto de ellos para conseguir formas ms complejas. En los prximos tres captulos se van
a ver diferentes nodos que sirven para agrupar otros nodos:

Nodo Group (cap. 7)

Nodo Transform (cap. 8)

Nodo Switch (cap. 8a)

Nodo Billboard (cap. 8a)

Nodo Group
Existe el nodo Group que permite tratar a un conjunto de nodos como una entidad nica, pero
sin efectuar ninguna transformacin en ellos.
Su estructura general es la siguiente:

Group {
children [ ... ]
}
Tiene un campo llamado children (en ingls, nios o hijos), cuyo valor (los puntos
suspensivos) va entre corchetes [ y ], y que como veremos a continuacin, es la listade los
objetos que se quieren agrupar, representados por sus nodos Shape respectivos:

Group {
children [
Shape { ... },
Shape { ... },
...
]
}

Veamos un ejemplo: Vamos a agrupar los ejemplos de una caja y de un cono vistos
anteriormente:

#VRML V2.0 utf8


#Ejemplo de agrupacin de una caja y un cono
Group {
children [
#Aqu empieza la caja:
Shape {
appearance Appearance
material Material
}
geometry Box {
size 2 0.5 3
}
},
#Aqu empieza el cono:
Shape {
appearance Appearance
material Material
}
geometry Cone {
height 3
bottomRadius 0.75
}
}
]
}

{
{

{
{

Vase el resultado en la imagen de la derecha. Se puede observar que la caja y el cono


estn superpuestos. Esto es debido a que los objetos son creados todos en el mismo punto:
en el centro del escenario de realidad virtual.
Para colocar un objeto, o grupo de objetos, en otros puntos que no sean el centro, se deber
utilizar otro tipo de nodo, como se ver ms adelante.

Consejos prcticos para escribir el cdigo


A lo largo de los captulos hemos ido viendo la sintaxis de cada nodo y la manera de cmo se
incrustan unos nodos dentro de otros, etc., para poder confeccionar los correspondientes
documentos VRML.
Si observamos el ltimo ejemplo, parece como si el cdigo se complicara ms y ms (a pesar
de tratarse de un ejemplo relativamente sencillo).
No hay tal complicacin, pero s es muy importante seguir unas cuantas reglas prcticas, pues
es absolutamente imprescindible que las cosas estn colocadas en elorden debido, y que no
sobre ni falte ninguno de los smobolos de apertura y de cierre { y }, [ y ]

Utilizar una lnea distinta para cada nodo, para cada campo y para cada valor de
cada campo.
No es que sea obligatorio, pues de hecho se podra escribir todo el cdigo en una sola
lnea, aunque esto no sera muy prctico e inducira a cometer errores.

Indentar cada lnea, segn su jerarqua.


(Para indentar, es muy til utilizar la tecla tabuladora, que desplaza el cursor un nmero
fijo de espacios).
Veamos lo que se quiere decir, observando el ejemplo anterior. El nodo Group, que es
el nodo raz, no est indentado. Este nodo tiene un slo campo (children), que se
indenta una vez. Children tiene como valor dos nodos Shape, que se indentan dos
veces (o sea que ambos estn al mismo nivel). Cada nodo Shape tiene a su vez dos
campos (appearance y geometry), que se indentan tres veces. Estos ltimos tienen sus
respectivos campos, que se indentan cuatro veces, etc. etc.

Colocar cada smbolo de cierre en el nivel de indentacin que le corresponda.


As vemos en el ejemplo que el smbolo de cierre } de Group no tiene ninguna
indentacin (est situado al final del todo). El smbolo de cierre ] de children tiene una
indentacin (como el campo children). Los de los nodos Shape, tienen dos
indentaciones, etc.
De esta manera, vemos que los smbolos de cierre estn situados exactamente debajo
del comienzo de la lnea que le corresponde. De esta manera estn perfectamente
identificados, y sirve como control para no olvidarse de ninguno de ellos.

Poner las lneas de comentario necesarias al mismo nivel que lo que se comenta.
As, en el ejemplo, el comentario "#Aqu empieza la caja:" se indenta dos veces, para
que est situado en el mismo nivel que el nodo Shape, que es el objeto del comentario.

Poniendo nombres propios a los nodos


Podemos observar en el ejemplo que se ha repetido dos veces el nodo Appearance, para
dotar de la misma apariencia por defecto a los dos objetos (la caja y el cilindro).
No es tan grave en este caso, pero imaginemos que se quiere dotar de esa misma apariencia,
por ejemplo a cinco objetos distintos (como va a ser el caso del ejemplo prctico de este
captulo). Entonces, habra que repetir cinco veces todo el nodo Appearance en cada uno de
los cinco objetos, lo cual sera bastante engorroso, adems de complicar innecesariamente el
cdigo.
Hay una solucin prevista para simplificar estas repeticiones, y es que se puede definir un
nodo que se piensa repetir en el cdigo, ponindole un nombre arbitrario.
Supongamos, por ejemplo, que se van a utilizar repetidamente en un escenario unos cilindros
exactamente iguales (que podran ser las columnas de una casa), y que dichos cilindros tienen
el siguiente cdigo:

Shape {
appearance Appearance {
material Material { }
}

geometry Cylinder {
height 2
radius 0.5
}
}
(Este es el cdigo de un cilindro con la apariencia por defecto, de 2 unidades de alto y una
base de radio 0.5)
Se puede definir, para el mbito de un documento VRML, que este tipo de cilindro tenga
un nombre arbitrario, por ejemplo ColumnaRepetida (o como se quiera, con tal de que
comience por mayscula), de la siguiente manera:

DEF ColumnaRepetida Shape {


appearance Appearance {
material Material { }
}
geometry Cylinder {
height 2
radius 0.5
}
}
Entonces, cada vez que se quiera usar este nodo en otra parte del documento, basta con poner
lo siguiente:

USE ColumnaRepetida
En el ejemplo anterior de la caja y el cono, lo que est repetido es el nodo Appearance. Vamos
a definirlo, en la primera ocasin que se utiliza con el nombre, por ejemplo, PorDefecto y en la
segunda vez utilizar slo el comando USE (se omiten las lneas de comentarios):

#VRML V2.0 utf8


#Ejemplo de agrupacin de una caja y un cono,
#haciendo uso de los comandos DEF y USE.
Group {
children [
Shape {
appearance DEF PorDefecto Appearance {
material Material { }
}
geometry Box {
size 2 0.5 3
}
},
Shape {
appearance USE PorDefecto
geometry Cone {
height 3
bottomRadius 0.75

}
}
]
}
En este caso concreto, la simplificacin no ha sido muy grande (slo un par de lneas menos de
cdigo), pero ha servido para ilustrar el concepto.

Como se ha mencionado en el captulo anterior, por defecto, todos los objetos son creados en
el centro del escenario de realidad virtual.
Ahora vamos a ver cmo posicionarlos en otros puntos. Pero para ello, es necesario antes
comprender la nocin de los sistemas de coordenadas.
Un punto en el espacio est definido por su posicin con respecto al centro de coordenadas.En
el lenguaje VRML se adopta la convencin de que sea X la distancia que ese punto est
desplazado a la derecha o a la izquierda del centro, Y la distancia por encima o por debajo,
y Z la distancia hacia delante o hacia atrs. Se puede ver en la imagen de la derecha una
representacin tridimensional de los ejes de coordenadas. Pulsndola se carga el
escenario. (Se ha confeccionado utilizando cilindros muy finos, convenientemente girados para
representar los ejes)
Un mundo virtual tiene su sistema de coordenadas situado en el centro. Con el nodo Group,
visto en el captulo anterior, se consigue agrupar un conjunto de objetos, que son creados
haciendo coincidir su centro con el centro del sistema de coordenadas, como se puede apreciar
en la figura de la derecha. (Se ha superpuesto el conjunto de objetos a los ejes coordenados)
Con el nodo Transform, que vamos a ver a continuacin, se determina un nuevo sistema de
coordenadas para un grupo de objetos.

Este nuevo sistema de coordenadas sufre unas transformaciones: puede ser trasladado a un
punto determinado, puede ser girado un determinado ngulo, y puede tener
una escala (tamao relativo) distinta a la original.
El grupo de objetos especificados en el nodo sufrirn las mismas transformaciones, es decir,
sern trasladados, girados y variados de escala.

Estructura del nodo Transform


Su estructura general es la siguiente:

Transform {
translation . . .
rotation . . .
scale
...
children [ . . . ]
}
Como se puede ver, tiene tres campos con los que se determina su posible traslado, rotacin o
nueva escala, y un cuarto campo children, en donde se especifican cules son los objetos
agrupados que sufrirn esas transformaciones.

No tienen por qu estar los tres campos a la vez. Por tanto, para simplificar, vamos a ver cada
uno de ellos por separado.

Traslacin
Poniendo slo el campo translation, queda el nodo Transform de esta manera:

Transform {
translation 20 0 0
children [ . . . ]
}
Se ha puesto un valor al campo translation. El orden para el traslado de las coordenadas es X,
Y, Z. Por tanto, en este caso, hay una traslacin de 20 unidades hacia la derecha (si hubiera
sido hacia la izquierda se habra puesto -20.0)
Por supuesto que se podran haber variado las tres coordenadas, no slo la X como en este
caso.

Con respecto al campo children, se aplica lo dicho anteriormente, para el nodo Group.

Rotacin
Poniendo ahora slo el campo rotation, queda el nodo Transform de esta manera:

Transform {
rotation 1 0 0 1.57
children [ ... ]
}
Tal como se ha puesto el valor del campo rotation quiere decir lo siguiente: rotacin de 90
alrededor del eje X.
Explicacin: Las tres primeras cifras slo pueden tener el valor 0 1, y representan la
rotacin alrededor de cada eje, en este orden: X, Y, Z.
Es decir:

Rotacin alrededor del eje X: 1 0 0

Rotacin alrededor del eje Y: 0 1 0

Rotacin alrededor del eje Z: 0 0 1

La cuarta cifra representa el ngulo girado, expresado en radianes.


Para calcular la correspondencia entre grados y radianes, hay que tener en cuenta
que 180 equivalen al nmero pi en radianes, es decir a 3.14 radianes. Por tanto, 90 sera la
mitad de 3.14, es decir 1.57 radianes.

El sentido del giro es el de un sacacorchos avanzando en la direccin positiva de los ejes.


En la figura de la derecha se puede ver al grupo de objetos, trasladados 20 unidades hacia la
derecha y girados 90 alrededor del eje X (pulsar la imagen para cargar el escenario), cuyo
cdigo es:

Transform {
translation 20 0 0
rotation 1 0 0 1.57
children [ ... ]
}

Variacin de la escala
Poniendo ahora en el nodo Transform slo el campo scale, para variar la escala de los objetos,
queda de la siguiente forma:

Transform {
scale 0.5 2 0.5
children [ ... ]
}
Los valores del campo scale representan las variaciones de las dimensiones con respecto a
los ejes X, Y , Z.
Por tanto, en el ejemplo que se ha puesto, se reducen las dimensiones en la direccin de las X
a la mitad (0.5), se duplican en la direccin del eje Y (2), y se reducen a la mitad en la direccin
del eje Z (0.5).
Si se hubiera variado la misma cantidad en los tres valores (por ejemplo, 0.5) se habra
mantenido las proporciones de la pieza.
Se puede ver en la figura de la derecha la pieza despus de sufrir los tres cambios.

Nodo Switch
Este nodo Switch (en ingls, bascular o conmutar) sirve para agrupar otros nodos, pero con
una diferencia: slo ser utilizado uno de los hijos agrupados.
Su estructura es la siguiente:

Switch {
whichChoice 0
choice [...]
choice [...]

choice [...]
}
Como se puede ver, este nodo tiene un campo whichChoice (en ingls, cul eleccin) cuyo
valor es un nmero que indica cal hijo choice es el elegido (0, 1, 2, etc.). Si este valor es -1,
entonces se indica que no est elegido ninguno.
Qu utilidad tiene este nodo? Un posible uso de este nodo es el de tener preparadas
diferentes versiones del nodo Shape, es decir, diferentes formas de un objeto. Bastar con
variar el valor de whichCoice para pasar rpidamente de una forma a otra.
Esta variacin se har utilizando los eventos, que es algo que se ver ms adelante.

Nodo Billboard
Este nodo Billboard (en ingls, cartel) sirve para agrupar otros nodos hijos. Todos los nodos
agrupados sern visibles (al contrario del anterior, en el que slo es visible uno de ellos).
La particularidad de este nodo es que crea un sistema de coordenadas para los nodos
agrupados que est siempre de cara al espectador.
Su estructura es la siguiente:

Billboard {
axisOfRotation 0 1 0
children [ . . . ]
}
Tiene un campo, axisOfRotation (eje de rotacin), cuyo valor es un grupo de tres cifras que
indican cul es eje alrededor del cual se efecta automticamente el giro para permanecer
siempre de cara. La convencin que se utiliza es la misma que la vista anteriormente para la
rotacin, excepto que en este caso no hace falta poner un cuarto valor para expresar el ngulo:

Rotacin alrededor del eje X: 1 0 0

Rotacin alrededor del eje Y: 0 1 0

Rotacin alrededor del eje Z: 0 0 1

Formas complejas
Hasta ahora, para crear los distintos objetos que forman un escenario de realidad virtual, se
han utilizado exclusivamente las formas primitivas (caja, cono, cilindro y esfera).
Tal como se ha visto en los anteriormente, agrupando y modificando estas formas primitivas se
pueden conseguir otras formas ms complejas.
Pero esta tcnica tiene un lmite. Supongamos que se quiere representar un automvil, por
ejemplo. Con la sola utilizacin de las formas primitivas sera demasiado complicado de crear, y
se generaran ficheros VRML demasiado voluminosos.
Hay un mtodo ms eficaz para construir las formas complejas, que consiste en definir una
serie de puntos en el espacio y luego unirlos entre s para crear lneas osuperficies.

Nodo Coordinate
Este nodo sirve simplemente para definir una serie de puntos en el espacio tridimensional. En
s mismo no sirve para representarlos, sino que se utilizar dentro de otros nodos, como se va
a ver a continuacin.
La estructura de este nodo es la siguiente:

Coordinate {
point [
12 11 17.1,
20.5 13.8 5.3,
14 6.1 22.9
]
}
Como se puede ver, tiene un campo point, cuyo valor son grupos de tres cifras, separadas por
comas, englobadas entre corchetes [ y ].
Cada grupo de tres cifras representa un punto en el sistema de coordenas. En el ejemplo
estn definidos tres puntos, pero se pueden poner tantos como se quiera.
Este nodo se utiliza dentro de otros nodos, para conseguir cosas distintas:

PointSet - para crear puntos aislados

IndexedLineSet - para crear lneas

IndexedFaceSet - para crear caras (superficies)

Nodo PointSet, para crear puntos aislados


Su estructura es:

PointSet {
coord Coordinate {
point [ . . . ]
}
}
Como se puede ver, tiene un campo coord cuyo valor es el nodo Coordinate visto
anteriormente.
Aplicando al ejemplo del nodo Coordinate, quedara de esta manera:

PointSet {
coord Coordinate {
point [

12 11 17.1,
20.5 13.8 5.3,
14 6.1 22.9
]
}
}
Si incluyramos este cdigo, tal como est, en un documento VRML, no podramos ver ninguno
de los puntos todava. La razn es que, como se vi anteriormente, para crear un objeto
visible se debe utilizar el nodo Shape.

Inclusin del nodo PointSet en el nodo Shape


Como se vi en el captulo 5, la estructura general del nodo Shape es:

Shape {
appearance ...
geometry ...
}
Con el campo appearance se define la apariencia del objeto (color, textura, etc.) y con el
campo geometry su forma.
Por tanto, es evidente que la inclusin del nodo PointSet deber hacerse en este ltimo
campo, ya que la geometra de este objeto es la de un grupo de puntos. De manera
resumida, quedar de esta manera:

Shape {
appearance ...
geometry PointSet { ... }
}
Desarrollando totalmente el ejemplo:
#VRML V2.0 utf8
#Ejemplo de un grupo de tres puntos
Shape {
appearance Appearance {
material Material { }
}
geometry PointSet {
coord Coordinate {
point [
12 11 17.1,
20.5 13.8 5.3,
14 6.1 22.9
]
}
}
}

Color en los puntos

Hasta ahora hemos considerado que el nodo PointSet tena un solo campo (coord), que sirve
para definir la posicin de los puntos. Pero puede tener tambin otro campo (color), que sirve
para definir el color de cada uno de los puntos.
Es decir, el nodo PointSet puede tener esta estructura (resumida):

PointSet {
coord Coordinate {
point [ . . . ]
}
color Color {
color [ . . . ]
}
}
Como se puede observar, el campo color tiene como valor el nodo Color, que a su vez tiene
como valor el campo color de nuevo.
Desarrollando totalmente el ejemplo:

#VRML V2.0 utf8


#Ejemplo de un grupo de tres puntos con colores
Shape {
geometry PointSet {
coord Coordinate {
point [
12 11 17.1,
#1 punto
20.5 13.8 5.3, #2 punto
14 6.1 22.9
#3 punto
]
}
color Color {
color [
1 0 0, # 1 punto rojo
0 1 1, # 2 punto verde
1 1 0 # 3 punto amarillo
]
}
}
}
Obsrvese que se ha prescindido del campo appearance del nodo Shape, que haba en el
ejemplo anterior, ya que no es necesario, pues los puntos no van a tener la apariencia por
defecto, sino la que se determina en el campo color.
En el campo color se puede observar que hay (entre corchetes) tres grupos de nmeros,
separados por comas. Cada grupo de tres cifras representa un color, para cada punto
expresado en el campo point, y correspondindose en el mismo orden.

Nodo IndexedLineSet, para crear lneas

Con este nodo se crean lneas, uniendo una serie de puntos determinados. Su estructura
resumida es la siguiente:

IndexedLineSet {
coord Coordinate {
point [ . . . ]
}
coordIndex [ . . . ]
}
Como se puede ver, tiene dos campos:

coord, cuyo valor es el nodo Coordinate, y que sirve para determinar las coordenadas
de los puntos aislados que se van a unir entre s para formar las lneas.

coordIndex, con este campo se define el orden con el que se unen los puntos entre s,
dnde empieza y acaba una lnea, etc., como vamos a ver a continuacin.

Veamos primero un ejemplo sencillo: tres puntos que se unen ordenadamente entre s, para
formar una lnea:

IndexedLineSet {
coord Coordinate {
point [
5 5 0, # este es el punto 0
15 9 0, # este es el punto 1
20 18 0 # este es el punto 2
]
}
coordIndex [
0, 1, 2, -1
]
}
En el campo coord se establecen las coordenadas de los tres puntos A cada coordenada se ha
aadido una lnea de comentario para indicar cul es la numeracin que le corresponde al
punto. Obsrvese que se comienza por 0 (y no por 1).
En el campo coordIndex se establece el orden en el que se unen los tres puntos. En este
caso la lnea empieza en el primero (el 0), sigue con el segundo (el 1) y acaba en el tercero (el
2). Con el valor -1 se indica que ah acaba la lnea.

Inclusin del nodo IndexedLineSet en el nodo Shape


Como se vi anteriormente, para que un nodo pueda verse, debe estar incrustado en el
nodo Shape. Por tanto, de manera resumida, la inclusin del nodo IndexedLineSet en el nodo
Shape se har de esta manera:

Shape {
geometry IndexedLineSet { ... }
}
No se ha especificado ningn campo para su apariencia ni color, lo que se ver ms adelante.
Desarrollando el ejemplo, quedar de esta manera:

#VRML V2.0 utf8


#Ejemplo de linea uniendo tres puntos, sin definicion del color
Shape {
geometry IndexedLineSet {
coord Coordinate {
point [
5 5 0, #este es el punto 0
15 9 0, #este es el punto 1
20 18 0 #este es el punto 2
]
}
coordIndex [
0, 1, 2, -1
]
}
}
En el ejemplo, se han unido los puntos segn el orden en el que estn especificados en el
campo point (0,1,2), pero se pueden unir en el orden que se desee, como por ejemplo (0,2,1),
con lo que resultar una lnea distinta. Habra que modificar el campo coordIndex, que
quedara de esta manera:

coordIndex [
0, 2, 1, -1
]
Se pueden crear simultneamente diversas lneas. Supongamos que en el campo point se
han especificado las coordenadas de 12 puntos (por tanto, del 0 al 11), y queremos crear dos
lneas, la primera con los 6 primeros puntos y la segunda con los 6 ltimos. El
campo coordIndex quedara de esta manera:

coordIndex [
0, 1, 2, 3, 4, 5, -1, #esta es una lnea
6, 7, 8, 9, 10, 11, -1 #esta es otra lnea
]

El color en las lneas

Para determinar el color de cada uno de los segmentos que compone la lnea, hay que hacer
uso de tres campos ms:

color

colorIndex

colorPerVertex

Con el campo color se especifican cuntos y qu colores se van a usar (en el caso de que
haya ms de una lnea).
Con el campo colorIndex se atribuye a cada una de las lneas existentes alguno de los colores
expresados en el campo anterior.
Con el campo colorPerVertex se especifica si los colores sern colores continuos, o un
gradiente entre dos colores.
Veamos una aplicacin en el ejemplo anterior: una nica lnea quebrada que une tres puntos,
se va a hacer que sea toda ella de color verde.

#VRML V2.0 utf8


#Ejemplo de linea de color verde, uniendo tres puntos
Shape {
geometry IndexedLineSet {
coord Coordinate {
point [
5 5 0, #este es el punto 0
15 9 0, #este es el punto 1
20 18 0 #este es el punto 2
]
}
coordIndex [
0, 1, 2, -1
]
color Color {
color [
0 1 0 #este es el color 0 (verde),
]
#el unico posible pues solo hay una linea
}
colorIndex [
0 #a la unica linea se le atribuye el unico color 0
]
colorPerVertex FALSE
}
}
En el campo color se especifica el color (o los colores, si hay ms de una lnea)
En el campo colorIndex se atribuye el color a la la lnea (o lneas, si hay ms de una). Este
campo hace una funcin anloga con los colores y las lneas a la del campocoordIndex con
los puntos y las lneas.

En este ejemplo slo hay una lnea con un nico color. En el ejercicio prctico se va ver un
caso de dos lneas con dos colores.

Nodo IndexedFaceSet para obtener caras


La idea es unir una serie de puntos para que formen una polilnea cerrada, que es la que
definir la cara.
Su estructra resumida es:

IndexedFaceSet {
coord Coordinate {
point [ . . . ]
}
coordIndex [ . . . ]

Observamos dos campos (puede tener ms, como se ver):

coord, cuyo valor es el nodo Coordinate, y que sirve para determinar las coordenadas
de los puntos aislados que se van a unir entre s para formar las caras.

coordIndex, con este campo se define el orden con el que se unen los puntos entre s
para formar las distintas caras, como vamos a ver a continuacin.

Veamos primero un ejemplo sencillo: tres puntos que se unen ordenadamente entre s para
formar una cara:

IndexedFaceSet {
coord Coordinate {
point [
5 5 0, # este es el punto 0
15 9 0, # este es el punto 1
20 18 0 # este es el punto 2
]
}
coordIndex [
0, 1, 2, -1
]
}
En el campo coord se establecen las coordenadas de los tres puntos. A cada coordenada se
ha aadido una lnea de comentario para indicar cul es la numeracin que le corresponde al
punto. Obsrvese que se comienza por 0 (y no por 1).
En el campo coordIndex se establece el orden en el que se unen los tres puntos que van a
formar la polilnea cerrada que va a formar la cara. Con el valor -1 se indica que ah acaba la
cara.

Inclusin del nodo IndexedFaceSet en el nodo Shape


Como se vi anteriormente y en repetidas ocasiones, para que un nodo pueda verse, debe
estar incrustado en el nodo Shape. Por tanto, de manera resumida, la inclusin del nodo
IndexedFaceSet en el nodo Shape se har de esta manera:

Shape {
geometry IndexedFaceSet { ... }
}
No se ha especificado ningn campo para su apariencia ni color, lo que se ver ms adelante.
Desarrollando el ejemplo, quedar de esta manera:

#VRML V2.0 utf8


#Ejemplo de cara uniendo tres puntos, sin definicion del color
Shape {
geometry IndexedFaceSet {
coord Coordinate {
point [
5 5 0, #este es el punto 0
15 9 0, #este es el punto 1
20 18 0 #este es el punto 2
]
}
coordIndex [
0, 1, 2, -1
]
}
}
A la derecha puede verse el resultado (pulsarla para cargar el escenario). Se han aadido
unos ejes coordenados y modificado el punto de vista inicial.
Se puede observar que se ha creado una cara triangular, sin color ni apariencia definida. Si se
manipula el escenario, se puede comprobar que la cara slo es visible por un lado.

Se pueden definir ms de una cara simultneamente, como veremos ms adelante.

El color en las caras


Para determinar el color de la cara hay que hacer uso de tres campos ms:

color

colorIndex

colorPerVertex

Con el campo color se especifican cuntos y qu colores se van a usar (en el caso de que
haya ms de una cara).
Con el campo colorIndex se atribuye a cada una de las caras existentes alguno de los colores
expresados en el campo anterior.
Con el campo colorPerVertex se especifica si los colores sern colores continuos, o un
gradiente entre dos colores.
Veamos una aplicacin en el ejemplo anterior: vamos a hacer que la cara tenga un color
verde.

#VRML V2.0 utf8


#Ejemplo de cara, uniendo tres puntos, de color verde
Shape {
geometry IndexedFaceSet {
coord Coordinate {
point [
5 5 0, #este es el punto 0
15 9 0, #este es el punto 1
20 18 0 #este es el punto 2
]
}
coordIndex [
0, 1, 2, -1
]
color Color {
color [
0 1 0 #este es el color 0 (verde),
]
#el unico posible pues solo hay una cara
}
colorIndex [
0 #a la unica cara se le atribuye el unico color 0
]
colorPerVertex FALSE
}
}
En el campo color se especifica el color (o los colores, si hay ms de una cara)
En el campo colorIndex se atribuye el color a la la cara (o caras, si hay ms de una).
En este ejemplo slo hay una cara con un nico color.

A la derecha puede verse el resultado. Se han aadido unos ejes coordenados y modificado el
punto de vista inicial.
Si se manipula el escenario, se puede observar que la cara verde es visible slo por un lado, el
que est de frente.

Determinando una cara visible


Por defecto, la cara visible es la perpendicular a la parte positiva de los ejes coordenados. En
el ejemplo anterior, la cara es perpendicular a la parte positiva del eje Z.
Pero puede haber ocasiones que nos interese que sea visible la otra cara. Para determinar una
cosa o la otra, el nodo IndexedFaceSet puede tener el campo ccw(abreviatura
de counterclockwise: contrario a la agujas del reloj). Hay dos posibilidades:

ccw TRUE Es la opcin por defecto, por tanto no es obligatoria ponerlo. La cara visible
es la perpendicular a la parte positiva de los ejes coordenados.

ccw FALSE En este caso, la cara visible es la opuesta a la parte positiva de los ejes
coordenados

Si en el ejemplo anterior se aade el campo ccw FALSE. Para poder ver la cara verde hay que
girar 180 el escenario.

Determinando ambas caras visibles


Se puede hacer que ambas caras sean visibles simultneamente. Para ello el
nodo IndexedFaceSet puede tener el campo solid, que tiene dos posibilidades:

solid TRUE Es la opcin por defecto: slo una cara es visible (la determinada por el
campo ccw), y por tanto no es obligatorio ponerlo.

solid FALSE En este caso, ambas caras son visibles simultneamente.

Si al ejemplo anterior de la cara verde, se le aade el campo solid FALSE. Girando el


escenario, se ver que ambas caras son visibles.

Utilizacin de este nodo para crear un suelo


Un uso muy til del nodo IndexedFaceSet es el de crear un suelo para un escenario de
realidad virtual.
Supongamos que queremos crear un suelo de color azul para nuestro mundo, de dimensiones
100x100. Entonces, las coordenadas de las cuatro esquinas sern:

50,0,50
-50,0,50
-50,0,-50
50,0,-50
Vamos a aadir el campo solid FALSE. Pero si se carga el escenario, en principio no se ver
nada. Esto es debido a que el punto de vista por defecto est precisamente a nivel cero, es
decir, en el mismo suelo. Slo se ver el suelo si se hace girar todo el escenario.
Determinando un punto de vista inicial elevado sobre el suelo (se ver ms adelante cmo
conseguirlo), y superponiendo unos ejes coordenados, obtenemos el resultado que se puede
ver en la imagen de la derecha.

Obsrvese que al cargar el escenario, se "aterriza" sobre el suelo, y que se puede desplazar
por l, pero no se pueden efectuar movimientos de elevacin. Esto es debido, a que
automticamente se determina que existe gravedad en el mundo. Para poder flotar, hay que
pulsar el mando "Float", que inhabilita la gravedad.
Con este mtodo obtenemos un suelo del color que queramos, pero se pueden obtener suelos
que tengan una textura determinada (hierba, piedra, etc.), lo que se ver ms adelante.
Con el nodo IndexedFaceSet se crean suelos planos. En el siguiente captulo se ver cmo
crear suelos accidentados (terrenos con ditintas elevaciones, colinas, etc.).

Nodo ElevationGrid para crear suelos accidentados


El nodo ElevationGrid (en ingls: rejilla de elevaciones) determina una rejlla de puntos, es
decir, una cuadrcula de puntos de separacin uniforme en el plano horizontal XZ, a los que se
atribuyen distintas cotas de altura. Se generer una superficie irregular uniendo dichas cotas.
Veamos su estructura general con un ejemplo:

ElevationGrid {
xDimension 6
xSpacing 4
zDimension 3
zSpacing 8
height [
0.25, 4, 7, 3, 1.5, 0.25,
1.5, 2.5, 1.5, 2.1, 1, 0,
0.3, 0.3, 0, -2.7, -1.5, -3.7
]
}
Observamos los siguientes campos (puede tener otros ms, como veremos):

xDimension es el nmero de puntos de la rejilla, en la direccin del eje X (en este


caso, 6 puntos)

xSpacing es la separacin de los puntos de la rejilla, en la direccin del eje X (en este
caso, 4)

zDimension es el nmero de puntos de la rejilla, en la direccin del eje Z (en este


caso, 3 puntos)

zSpacing es la separacin de los puntos de la rejilla, en la direccin del eje Z (en este
caso, 8)

height es la altura de cada uno de los puntos de la rejilla. En este caso, la rejilla tiene
6x3=18 puntos, por lo tanto, hay que poner las 18 cotas de altura que correspondan a
cada punto.

La rejilla debe comenzar siempre en el origen de coordenadas y crecer en el sentido positivo


de los ejes X y Z.
En el ejemplo se puede observar que habr un pico mximo de valor 7 en el centro de la hilera
trasera, y una depresin mxima de -3.7 a la derecha de la hilera delantera.

Inclusin del nodo ElevationGrid en el nodo Shape


Como se ha dicho repetida veces, para que un nodo que define una forma (como es el caso
del nodo ElevationGrid) sea visible, debe incluirse dentro del nodo Shape.
La estructura general del nodo Shape es:

Shape {
appearance ...
geometry ...
}
El nodo ElevationGrid ser el valor del campo geometry, quedando por tanto as (de manera
resumida):

Shape {
appearance ...
geometry ElevationGrid { ... }
}
Y desarrollando totalmente el ejemplo:

#VRML V2.0 utf8


#Ejemplo del nodo ElevationGrid,
#con la apariencia por defecto
Shape {
appearance Appearance {
material Material { }
}
geometry ElevationGrid {
xDimension 6
xSpacing 4
zDimension 3
zSpacing 8
height [

0.25, 4, 7, 3, 1.5, 0.25,


1.5, 2.5, 1.5, 2.1, 1, 0,
0.3, 0.3, 0, -2.7, -1.5, -3.7
]
}
}
Como el punto inicial (el origen de coordenadas) no es demasiado conveniente para visualizar
la superficie generada, a la derecha se puede ver una imagen de este ejemplo en donde se ha
modificado el punto de vista inicial a uno ms conveniente. Tambin se han aadido unos ejes
coordenados.
Obsrvese que la superficie generada es slida y existe gravedad, por lo que si se camina por
la supeficie se "escalar" por las elevaciones.
Si se gira completamente el escenario, se puede comprobar tambin que la superficie slo
es visible por su parte delantera.

Determinando una cara visible


Por defecto, la cara visible es la perpendicular a la parte positiva de los ejes coordenados. En
el ejemplo anterior, la cara es perpendicular a la parte positiva del eje Z.
Pero puede haber ocasiones que nos interese que sea visible la otra cara. Para determinar una
cosa o la otra, el nodo ElevationGrid puede tener el campo ccw(abreviatura
de counterclockwise: contrario a la agujas del reloj). Hay dos posibilidades:

ccw TRUE Es la opcin por defecto, por tanto no es obligatoria ponerlo. La cara visible
es la perpendicular a la parte positiva de los ejes coordenados.

ccw FALSE En este caso, la cara visible es la opuesta a la parte positiva de los ejes
coordenados

Si en el ejemplo anterior se aade el campo ccw FALSE Para poder ver la superficie hay que
girar 180 el escenario.

Determinando ambas caras visibles


Se puede hacer que ambas caras sean visibles simultneamente. Para ello el
nodo ElevationGrid puede tener el campo solid, que tiene dos posibilidades:

solid TRUE Es la opcin por defecto: slo una cara es visible (la determinada por el
campo ccw), y por tanto no es obligatorio ponerlo.

solid FALSE En este caso, ambas caras son visibles simultneamente.

Si al ejemplo anterior de la cara verde, se le aade el campo solid FALSE Girando el


escenario, se ver que ambas caras son visibles.

Poniendo color a la superficie generada


En el ejemplo visto anteriormente se ha utilizado la apariencia por defecto, sin un color
definido.

Pero en este caso concreto, hay una manera de determinar el color de partes determinadas de
la superficie, como vamos a ver a continuacin.
En este caso, la rejilla est formada por dos hileras de 5 cuadrculas, es decir, en total 10
cuadrculas. Se puede determinar el color de la superficie generada sobre cada cuadrcula.
A continuacin est la representacin de la rejilla vista desde arriba. Adems, se ha escrito en
cada cuadrcula el color que se desea para la parte de la superficie que le corresponda y un
nmero (del 1 al 10), para sealar el orden de atribucin de colores.
Se ha escogido el color blanco para las zonas ms altas, el rojo para las intermedias, el verde
para las bajas y el azul para las ms bajas.
Hay que aadir dos campos al nodo ElevationGrid:

color que contiene el nodo Color, que a su vez contiene el campo color, en donde se
especifican los 10 colores atribuidos a cada cuadrcula.

colorPerVertex que puede ser TRUE, para colores en gradiente (no se estudiar este
caso). O puede ser FALSE, en cuyo caso los colores son continuos. Se aplicar esta
posibilidad.

El ejemplo anterior quedar de esta manera:

#VRML V2.0 utf8


#Ejemplo del nodo ElevationGrid,
#con colores en las caras
Shape {
appearance Appearance {
material Material { }
}
geometry ElevationGrid {
xDimension 6
xSpacing 4
zDimension 3
zSpacing 8
height [
0.25, 4, 7, 3, 1.5, 0.25,
1.5, 2.5, 1.5, 2.1, 1, 0,
0.3, 0.3, 0, -2.7, -1.5, -3.7
]
color Color {
color [
1 0 0 #rojo para la cuadr. 1
1 1 1 #blanco para la cuadr. 2
1 1 1 #blanco para la cuadr. 3
1 0 0 #rojo para la cuadr. 4
0 1 0 #verde para la cuadr. 5
0 1 0 #verde para la cuadr. 6
0 1 0 #verde para la cuadr. 7
0 1 0 #verde para la cuadr. 8
0 1 0 #verde para la cuadr. 9
0 0 1 #azul para la cuadr. 10

]
}
colorPerVertex FALSE #colores continuos (no degradados)
solid FALSE #ambas caras visibles
}
}
A la derecha puede verse el resultado. Se han aadido unos ejes coordenados y modificado el
punto de vista inicial.

Concepto bsico de la extrusin


En lneas generales, una forma extruida se obtiene de la siguiente manera:

En el plano XZ (horizontal) se define, mediante una serie de puntos, un polgono


cerrado: la seccin transversal o crossSection. Esta seccin es, por tanto, plana.

Mediante otra serie de puntos, se define un recorrido en el espacio tridimensional:


la espina dorsal o spine.

El objeto extruido se obtiene desplazando la seccin transversal a lo largo de la espina


dorsal. Durante este desplazamiento, la seccin transversal puede permanecer
invariable, o bien se pueden ir modificando tanto su escala (tamao), como su
orientacin.

Vanse a continuacin un ejemplo de extrusiones: una hlice de dimetro variable:

Estructura general del nodo Extrusion


La estructura bsica de este nodo es la siguiente:

Extrusion {
crossSection [
1 0,
0 6.5,
.......
]
spine [
10 0 3,
15 1 5,
............
]
solid FALSE
}
Se pueden observar los campos:

crossSection, cuyo argumento es una serie de puntos que definen la seccin


transversal. Ntese que estos puntos estn definidos por dos coordenadas, y no por
tres, que es lo habitual. Veremos a continuacin el motivo de sto.

spine, cuyo argumento es otra serie de puntos que definen la espina dorsal del objeto
extruido. Cada uno de estos puntos est definido por tres coordenadas, como no poda
ser menos, puesto que la espina dorsal es un recorrido en el espacio tridimensional.

solid, tiene dos opciones: TRUE (la opcin por defecto) con la que se ven slo un lado
de las caras. FALSE: se vern ambos lados.

Ejemplo sencillo de extrusin: un cubo


Veamos a continuacin con ms detalle cmo se define la seccin transversal. Como se ha
dicho antes, se encuentra en el plano XZ, es decir, en el plano horizontal formado por los ejes
coordenados X y Z.
A la derecha se puede ver la representacion de los ejes coordenados.
La seccin transversal es una superficie plana, definida en el el plano XZ. Por tanto, se van a
utilizar slo dos coordenas (x,z).
Vamos a ver un ejemplo muy sencillo de extrusin, para comprender este concepto: un
cubo. (Recurdese que existe el nodo Box para conseguirlo directamente)

La seccin transversal de un cubo es un cuadrado definido en el plano XZ.


Para definir la seccin transversal, se debe sealar un polgono cerrado, es decir, comenzando
desde un vrtice cualquiera (p. ej. 10,10), y siguiendo el sentido de las agujas del reloj, el
siguiente ser (-10,10), luego (-10,-10), a continuacin (10,-10) y finalmente (10,10) de nuevo,
con lo que el polgono se ha cerrado.

crossSection [
10 10,
-10 10,
-10 -10,
10 -10,
10 10
]
Ahora falta por definir la espina dorsal. La espina dorsal define el recorrido que la seccin
transversal deber efectuar para crear le forma extruida.
Vamos a hacer que la seccin transversal comience en el punto (0,-10,0) y se mueva hasta el
punto (0,10,0).
En la siguiente figura se muestra el camino recorrido por la seccin transversal a lo de la espina
dorsal del cubo (en rojo):

El campo spine queda de la siguiente manera:

spine [
0 -10 0,
0 10 0
]

Inclusion del nodo Extrusion en el nodo Shape


Como se ha dicho repetida veces, para que un nodo que define una forma (como es el caso
del nodo Extrusion) sea visible, debe incluirse dentro del nodo Shape.
Por tanto, el documento VRML de este ejemplo quedar de esta forma:

#VRML V2.0 utf8


#Ejemplo de extrusin: cubo
Shape {
appearance Appearance {
material Material {}
}
geometry Extrusion {
crossSection [
10 10,
-10 10,
-10 -10,
10 -10,
10 10
]
spine [
0 -10 0,
0 10 0
]
solid FALSE
}
}
A la derecha puede verse el resultado. (Se han aadido unos ejes coordenados y modificado
el punto de vista inicial)

Aberturas en la superficie extruida


En el ejemplo del cubo visto anteriormente, todas las caras eran visibles. Pero, si se desea, se
puede hacer que no existan algunas de ellas, es decir, que haya aberturasen la superficie
extruida.
Existen dos campos que determinan si la forma extruida est abierta o cerrada en los extremos:

beginCap: si se establece como FALSE, no existir la seccin transversal inicial (en el


ejemplo del cubo, la cara inferior).

endCap: si se establece como FALSE, no existir la seccin transversal final (en el


ejemplo del cubo, la cara superior).

Aadiendo estos dos campos al nodo Extrusion, en el ejemplo anterior:

beginCap FALSE
endCap FALSE
dar el resultado que se ve a la derecha.

Otra posibilidad es la de dejar deliberadamente sin cerrar el polgono que determina la


superficie transversal.

crossSection [
-10 10,
-10 -10,
10 -10,
10 10
]
queda sin cerrar el polgono, con lo que el cubo extruido carece de la cara frontal, como se
puede ver en la imagen de la derecha.

Complicando la espina dorsal


En los ejemplos vistos anteriormente, la espina dorsal siempre es perpendicular a la seccin
transversal y adems justo en su centro. Pero esto no tiene por qu ser as necesariamente.
La espina dorsal puede estar situada en cualquier sitio, formar una recta inclinada, estar
formada por ms de dos puntos o tener cualquier forma espacial que se desee.
Veamos una espina dorsal que sea una recta inclinada con respecto a la seccin transversal.
La espina dorsal ha sido representada en rojo y la seccin transversal en verde.

A la derecha puede verse el resultado..

Y ahora veamos un ejemplo de espina dorsal formada por tres puntos:

Superficies de revolucin

Si la espina dorsal es un crculo, entonces el cuerpo engendrado es una superficie de


revolucin. Veamos un ejemplo: un toro definido por 8 puntos.
A la derecha puede verse la imagen que representa la seccin transversal (en verde) y que
est situada, como debe ser, en plano horizontal XZ. Esta seccin transversal es un crculo de
radio 5 y est representada por 8 puntos.
Tambin est representada (en blanco) una espina dorsal formada por otros ocho puntos que
forman un crculo de radio 10, y que tambin est situada en el plano XZ, porque as lo hemos
querido.

El campo crossSection es el siguiente:

crossSection [
5 0,
3.53 3.53,
0 5,
-3.53 3.53,
-5 0,
-3.53 -3.53,
0 -5,
3.53 -3.53,
50
]
Recurdese que en el campo crossSection los puntos se expresan con dos corrdenadas (x,z),
y que adems hay que repetir al final el primer punto, para cerrar la seccin transversal.
El campo spine es el siguiente:

spine [
10 0 0,
7.07 0 7.07,
0 0 10,
-7.07 0 7.07,
-10 0 0,
-7.07 0 -7.07,
0 0 -10,
7.07 0 -7.07,
10 0 0
]
En este caso, los puntos vienen expresados por tres coordenadas (x,y,z). Y tambin se repite
el ltimo para cerrar el toro
A la derecha puede verse el resultado.
Es evidente que los ocho puntos que se han utilizado para definir los dos crculos (el de la
seccin transversal y el de la espina dorsal) no son suficientes, pues ms que crculos son
octgonos.

Variacin de la escala de la seccin transversal


Hasta ahora, en todos los casos vistos, la seccin transversal parmaneca inalterable en su
forma y tamao a lo largo de la espina dorsal.
Existe el campo scale que permite modificar la escala de la seccin transversal en cada uno de
los puntos de la espina dorsal.
As, en el primer ejemplo del cubo, la espina dorsal estaba constituda por dos puntos.
Podemos hacer que en el segundo punto, la escala de la seccin transversal se reduzca a la
mitad, con lo que la figura resultante sera un tronco de prisma. Basta con aadir el
campo scale de la siguiente forma:

scale [
1 1,
0.5 0.5
]
El argumento del campo scale es un par de parmetros (que varan de 0 a 1) y que
representan la variacin de las coordenadas x z. Hay que especificarlo por cada punto que
hay en la espina dorsal.
En el ejemplo anterior, quiere decir que en el primer punto de la espina dorsal, queremos que
permanezcan inalterables las medidas de las x (factor 1), as como de las z (factor 1). En
el segundo punto de la espina dorsal, en cambio, queremos que las x se reduzcan a la mitad
(factor 0.5), as como las z (factor 0.5). Se poda haber modificado slo uno, pasando en vez de
a un cuadrado menor, a un rectngulo.
A la derecha puede verse el resultado.

Variacin de la orientacin de la seccin transversal


Hasta ahora, en todos los casos vistos se ha considerado que la seccin transversal se
traslada paralelamente a s misma (variando o no su tamao).
Existe el campo orientation que permite girar la seccin transversal en cada punto de la
espina dorsal un ngulo determinado.
Veamos un ejemplo: en el cubo vamos a hacer que la seccin transversal gire 45 en el
segundo punto de la espina dorsal, con lo que se obtendr un cubo "retorcido". Para
conseguirlo, vamos a aadir el campo orientation de la siguiente manera:

orientation [
0 1 0 0,
0 1 0 0.875
]
El argumento del campo orientation est formado por un grupo de 4 parmetros. Los tres
primeros indican el eje alrededor del cual se va a girar la seccin transversal. Y el cuarto
parmetro indica el ngulo girado, expresado en radianes (esto ya se vi para el
campo rotation). Esto hay que especificarlo por cada punto de la espina dorsal.

En el ejemplo anterior, en el primer punto de la espina dorsal expresamos que la rotacin


alrededor del eje Y (parmetros 0 1 0) sea nula (cuarto parmetro 0). En cambio, en el segundo
punto de la espina dorsal, queremos que la rotacin alrededor del eje Y (parmetros 0 1 0) sea
de 45 (cuarto parmetro, que es 3.14/4=0.875)
Puede verse el resultado en la figura siguiente a la izquierda.

Color y transparencia con el nodo Material


Como el nodo Material est vaco, se obtiene la apariencia por defecto:

Material { }
pero puede tener diversos campos, con los que se determinan el color y grado de
transparencia. Los m importantes son:

Material {
diffuseColor ...
emissiveColor ...
transparency ...
}

Con el campo diffuseColor se determina el color externo (o difuso) del objeto.

Con el campo emissiveColor se determina el color interno (o emisivo), para los


objetos iluminados desde dentro.

Con el campo transparency se determina el grado de transparencia.

Vemoslos separadamente:

Color externo (o difuso) de los objetos

Material {
diffuseColor 1 0 0
}
El campo diffuseColor determina el color externo (o difuso) del objeto, y tiene un valor
representado con tres nmeros, que se corresponden con el cdigo de colores.

Cdigo de colores
Un color se representa por un grupo de tres cifras. La primera cifra se refiere a la cantidad de
color rojo, la segunda a la cantidad de color verde y la tercera a la cantidad de color azul.

Las cifras pueden oscilar desde 0.0 (nada de ese color) hasta 1.0 (todo de ese color), pasando
por cualquier valor intermedio. Por tanto, en el ejemplo anterior se trata de un color rojo puro.
He aqu algunos ejemplos de colores:

Color

Rojo

Verde

Azul

Rojo

Verde

Azul

Blanco

Negro

Amarillo

Violeta

Marrn

0.5

0.2

Veamos una aplicacin de sto a un, donde tena la apariencia por defecto. Ahora va a tener un
color externo rojo:

#VRML V2.0 utf8


#Cono de color externo rojo
Shape {
appearance Appearance {
material Material {
diffuseColor 1 0 0
}
}
geometry Cone {
height 3
bottomRadius 0.75
}
}
Este es el resultado.

Color interno (o emisivo)

Material {
emissiveColor 1 0 0
}

El campo emissiveColor determina el color interno (o emisivo) del objeto, para cuando se
quiere dar la impresin de que el objeto est iluminado por dentro con un color determinado (en
este caso tambin de color rojo).
Para que se puedan comparar, a la derecha estn representados dos conos, el de la izquierda
con un color externo (o difuso) en rojo, y el de la derecha con un color interno (o emisivo),
tambin en color rojo.

Un cuerpo puede tener ambos campos a la vez, y con colores distintos. Es decir, puede tener
un color difuso determinado y otro color emisivo distinto.
A la derecha hay una imagen con un tercer cono que tiene su color difuso rojo y adems su
color emisivo en azul.

Transparencia

Material {
transparency 0.5
}
El campo transparency determina el grado de transparencia del objeto. Su valor est
representado por un nico nmero, que puede variar desde 0.0 (objeto totalmenteopaco)
hasta 1.0 (objeto totalmente transparente, lo que de hecho le hace ser invisible), pasando por
cualquier valor intermedio.
Veamos un ejemplo: un objeto en forma de pared (una caja alta y delgada de dimensiones
2.5x2.5x0.3 de color amarillo y grado de transparencia de 0.5):

#VRML V2.0 utf8


#Pared amarilla semi-transparente
Shape {
appearance Appearance {
material Material {
diffuseColor 1 1 0
transparency 0.5
}
}
geometry Box {
size 2.5 2.5 0.3
}
}
Si ponemos este objeto l solo en un escenario, no se puede juzgar su grado de transparecia,
pues necesitamos otros objetos, para poder ver a su travs.
Para poder comparar, se han colocado tres paredes iguales delante de los conos del ltimo
ejemplo, con valores de transparencia (de izquierda a derecha de 0.0, 0.5 y 0.7
respectivamente), segn se puede ver en la imagen de la derecha.

Otros campos para definir el color


Adems de los campos vistos anteriormente (diffuseColor, emissiveColor y transparency)
existen otros tres campos ms que se pueden utilizar para refinar an ms la apariencia del
color de los objetos:

specularColor: define el color de los puntos brillantes de los objetos. Su valor son las
tres cifras correspondientes a las cantidades de rojo, verde y azul.

shininess: controla la intensidad de la emisi de luz de los puntos brillantes. Su valor


es una nica cifra que vara desde 0.0 a 1.0

ambientIntensity: define la cantidad de luz reflejada por el objeto. Su valor es una


nica cifra que vara desde 0 a 1

Hasta ahora, para definir un objeto visible se ha utilizado el nodo Shape de la siguiente forma:

Shape {
appearance Appearance {
material ...
}
geometry ...
}

en donde el nodo Appearance tiene un solo campo, material, con el que se definen el color y la
transparencia, segn se ha visto en el captulo anterior.
Pero en realidad puede tener tambin otros dos campos: texture y textureTransform, con los
que se define la textura de los objetos:

Shape {
appearance Appearance {
material ...
texture ...
textureTransform ...
}
geometry ...
}
Vamos a centrarnos en el segundo campo exclusivamente (texture):

Shape {
appearance Appearance {
texture ...
}
geometry ...
}

Qu es la textura?
La textura es la posibilidad que tenemos de envolver un objeto con:

una imagen existente, usando el campo ImageTexture

una pelcula, usando el campo MovieTexture

una imagen creada por nosotros pixel a pixel, usando el campo PixelTexture

Se van a ver los dos primeros (ImageTexture y MovieTexture) en este captulo, y el tercero
(PixelTexture) en el captulo siguiente.

Textura con ImageTexture


Tomemos como ejemplo la imagen de la derecha: monalisa.jpg
Vamos a envolver con ella los objetos primitivos (caja, cono, cilindro y esfera).
Para ello, se hace uso del nodo ImageTexture, como valor del campo texture, de la siguiente
manera:

Shape {
appearance Appearance {
texture ImageTexture {
url ["monalisa.jpg"]
}
}
geometry ...
}
Como se puede ver, el nodo ImageTexture tiene el valor url ["monalisa.jpg"] (se supone que
la imagen est en el mismo directorio que el documento VRML. Si no fuera as, se pondra
entre comillas la ruta del fichero de imagen)
Aplicando esto a una caja de dimensiones 1.5x2.2x0.5:

#VRML V2.0 utf8


# Ejemplo de caja con textura de una imagen
Shape {
appearance Appearance {
texture ImageTexture {
url ["monalisa.jpg"]
}
}
geometry Box {
size 1.5 2.2 0.5
}
}

Imgenes distintas en un mismo objeto


Puede interesar que un objeto tenga imgenes diferentes en alguna o algunas de sus caras.
Este objeto, que representa una lata de bebida (que en realidad es un cilindro), tiene una
imagen para su superficie lateral, y otra distinta para los fondos superior e inferior.

Si nos limitamos a ponerlo de esta manera:

Shape {
appearance Appearance {
texture ImageTexture {
url ["etiqueta.jpg"]
}
}
geometry ...
}
se reproducira la imagen de la etiqueta tambin en los fondos superior e inferior (como se ha
podido comprobar en el caso del cilindro con la imagen monalisa.jpg)
Nos interesa que en los fondos superior e inferior tenga la imagen de la derecha (fondo.jpg)
La operacin se hace de la siguiente manera:

Se define el cilindro con la imagen etiqueta.jpg, pero se anulan las superficies superior
e inferior:

Shape {
appearance Appearance {
texture ImageTexture {
url ["etiqueta.jpg"]
}
}
geometry Cylinder {
height 2
radius 0.6
top FALSE
bottom FALSE
}
}
Lo que anula las superficies superior e inferior son los comandos top FALSE y bottom
FALSE respectivamente.

Se define otro cilindro idntico con la imagen fondo.jpg, pero se anula la superficie lateral.

Shape {
appearance Appearance {
texture ImageTexture {
url ["fondo.jpg"]
}
}
geometry Cylinder {
height 2
radius 0.6
side FALSE
}
}
En este caso, lo que anula la superficie lateral es el comando side FALSE

Por medio del nodo Group se agrupan ambos cilindros, con lo que el resultado es
aparentemente un cilindro con imgenes distintas.

Formatos de las imgenes


Los formatos de imagen soportados para ser utilizados como texturas son:

JPG ( JPEG)

GIF

PNG

Textura con MovieTexture


En lugar de usar imgenes estticas como textura de los objetos, se pueden
utilizar videos (pelculas), en formato MPEG, haciendo uso del nodo MovieTexture, en vez de
ImageTexture, de la siguiente manera:

Shape {
appearance Appearance {
texture MovieTexture {
url "mivideo.mpg"
speed 1
loop FALSE
}
}
geometry ...
}
Con el comando speed se controla la velocidad (1, velocidad normal, 2 doble velocidad, etc.).
Con valores negativos el video se ejecutara hacia atrs.
Con el comando loop se controla si el video funciona ininterrumpidamente (TRUE) o una sola
vez (FALSE).

volver