Prototipos, DEF y USE.
PROTO
Cuando se modelan objetos para un entorno, nos podemos encontrar que necesitemos definir un tipo de objeto que será utilizado de formas diferentes en diferentes sitios del entorno. Para poder definir un objeto genérico y poder utilizarlo con parámetros diferentes en diferentes lugares, VRML97 dispone de los prototipos.Debe quedar claro que PROTO no es un node de VRML97, sino un mecanismo para definir nuevos nodes. Lo que se hace al definir un prototipo, es definir un tipo de objeto nuevo para poderlo utilizar de la misma forma en que utilizamos los node Box, node Sphere, node Material, node Appearance, etc. Veamos un ejemplo para entender las diferentes partes.
Ejemplo1: Definición de un prototipo de Paraguas. Se define el nuevo tipo de node Paraguas.
PROTO Paraguas [
field SFColor colorBaston 0.1 0.1 0
field SFColor colorTela 0 0.2 1
]
{
Group {
children [
Shape {
geometry Cylinder { height 3 radius 0.1 }
appearance Appearance { material Material { diffuseColor IS colorBaston } }
}
Transform {
translation 0 1.75 0
children Shape {
geometry Cone { height 0.5 bottomRadius 3 }
appearance Appearance { material Material { diffuseColor IS colorTela } }
}
}
]
}
}
Paraguas { } #Creamos un objeto Paraguas con los valores por defecto
Transform {
translation 8 0 0
children Paraguas { colorBaston 0.2 0 0 colorTela 0 0.2 0.1 }
}
Transform {
translation -8 0 0
children Paraguas { colorBaston 0 0 0.3 colorTela 0.4 0 0.1 }
}
|
Para empezar, utilizamos un nuevo node que es el node Group. Este node sirve para agrupar en un solo objeto, varios subobjetos. Este node nos agrupará el objeto bastón y el objeto tela de nuestro paraguas. Si no los agrupásemos y definiésemos el objeto bastón y a continuación el objeto tela, el prototipo estaría formado por un bastón visible y una tela invisible. En la definición de un prototipo se pueden poner tantos objetos com se quiera, pero siempre se tomará el primero para determinar el tipo de node que se está definiendo y para visualizarlo. El resto de objetos pueden servir para muchas cosas, pero no serán visualizados.
Así pués, definimos un cilindro que nos hará de bastón. Como se puede observar, la geometría del cilindro está fijada. En cambio, la apariencia es lo que deseamos poder variar. Por lo tanto, definimos una apariencia con un material y con un color. La forma de conseguir que el color sea el que nosotros deseamos al definir un paraguas concreto, es utilizando la palabra clave IS. Esta palabra hace que podamos definir que el field diffuseColor de nuestro objeto sea en realidad (IS) el field colorBaston que hemos definido en los parámetros. De forma análoga se define la parte de la tela que definimos mediante un cono trasladado hacia arriba para que encaje bien con el bastón.
Hasta aquí hemos definido el prototipo y como tal, no es un objeto que exista. Si no pusiéramos nada más en el archivo de VRML97, y lo cargásemos en un browser, obtendríamos una escena vacía. Esto es por qué un PROTO es tan solo un molde del cual queremos sacar objetos concretos. Para esto lo que hacemos a continuación es lo que se llama instanciar un objeto a partir del prototipo. Por el solo hecho de poner el nombre del nuevo node Paraguas, ya estamos creando una instancia del prototipo. Como en este primer caso tan solo ponemos unas llaves vacías ({}), no estamos definiendo parámetros para este objeto en concreto. En este caso se utilizan los parámetros por defecto que havíamos establecido dentro del prototipo.
Las otras dos instanciaciones, se hacen trasladando el paraguas a un lado y otro del primero, y dando colores diferentes de los colores por defecto. Debe quedar claro que al instanciar los tres paraguas obtenemos tres objetos diferenciados y que si modificamos uno los otros no se verán alterados.
A continuación mostramos un ejemplo más complejo:
Ejemplo2: Definición de un prototipo de banquillo. Se define el nuevo tipo de node Banquillo.
PROTO Banquillo [
field SFColor colorPatas 1 1 0
field SFColor colorAsiento 0 0 1
field SFVec3f proporciones 1 1 1
field SFVec3f posicion 0 0 0
]
{
PROTO Pata [
field SFColor colorPata 1 1 0
field SFVec3f posicion 0 0 0
]
{
Transform {
translation IS posicion
children Shape {
geometry Cylinder { radius 0.1 height 1 }
appearance Appearance { material Material { diffuseColor IS colorPata } }
}
}
}
Transform {
translation IS posicion
scale IS proporciones
children [
Shape { # Asiento
geometry Box { size 1 0.2 1 }
appearance Appearance { material Material { diffuseColor IS colorAsiento } }
}
Pata { posicion 0.4 -0.6 0.4 colorPata IS colorPatas }
Pata { posicion -0.4 -0.6 0.4 colorPata IS colorPatas }
Pata { posicion -0.4 -0.6 -0.4 colorPata IS colorPatas }
Pata { posicion 0.4 -0.6 -0.4 colorPata IS colorPatas }
]
}
}
Banquillo { } #Creamos un objeto Banquillo con los valores por defecto
Banquillo { colorPatas 1 0.5 0 colorAsiento 0.5 0 1 posicion -2 0 0 }
Banquillo { colorPatas 0.5 1 0 colorAsiento 1 0.5 0 posicion 2 0 0 }
Banquillo { colorPatas 1 0 0.8 colorAsiento 1 0.5 0 posicion 0 2 0 proporciones 3 1 1 }
|
Cabe resaltar como los nombres de los fields no se solapan entre el PROTO padre y el hijo. Es decir, que por ejemplo, podemos tener como field el nombre posicion tanto en uno com en el otro, y se sabe perfectamente a quien se está haciendo referencia en cada momento debido al ámbito donde se encuentra.
DEF y USE
Cuando queremos definir un objeto que se utiliza en muchos sitios y nos satura el código por el hecho de repetir y repetir un mismo bloque de código, entonces podemos utilizar DEF y USE. No debemos confundir estos dos comandos con PROTO. DEF y USE no definen un objeto genérico que se instancía como objeto particular al llamarlo con unos ciertos parámetros. Lo que estos dos nuevos comandos permiten es dar nombre a un cierto nodo que posteriormente utilizaremos con la misma estructura y definición en diversos sitios. Veamos un ejemplo:Ejemplo3: Utilización de DEF y USE.
DEF MiRojo Appearance {
material Material {
diffuseColor 0.8 0.2 0.4
}
}
Transform {
translation -2 0 0
children Shape {
geometry Box { size 3 3 3 }
appearance USE MiRojo
}
}
Transform {
translation 2 0 0
children Shape {
geometry Sphere { radius 2 }
appearance USE MiRojo
}
}
|
Por ejemplo, si queremos que nuestro color MiRojo en relidad sea más rojo solo tenemos que variar su DEFinición:
Ejemplo4: Modificamos ejemplo anterior.
DEF MiRojo Appearance {
material Material {
diffuseColor 1 0.2 0
}
}
Transform {
translation -2 0 0
children Shape {
geometry Box { size 3 3 3 }
appearance USE MiRojo
}
}
Transform {
translation 2 0 0
children Shape {
geometry Sphere { radius 2 }
appearance USE MiRojo
}
}
|








0 comentarios:
Publicar un comentario