Como Por Arte De Magia |
Hasta ahora en este tutorial hemos cubierto lo básico en programación ECMAscript y cómo se relacciona con VRML. También hemos echado un ojo a los objetos preconstruidos VRML incluidos como standard en los navegadores. Ahora, profundizaremos en un objeto concreto, y veremos como llevar todo esto a su máxima potencia. Es el objeto Browser.
El objeto Browser
El objeto Browser es un objeto ECMAScript que se proporciona dentro del intérprete de ECMAScript de tu navegador VRML. Todos los navegadores deben proporcionarlo, pero esto es sólo un deben. Desgraciadamente, las cuestiones de scripts con respecto al VRML son muy inconsistentes, y generalmente no todos los navegadores soportan lo que deberían. Ésto es una auténtica pena, dado que éste es el aspecto más poderoso del VRML. En cualquier caso, el objeto Browser es un objeto preconstuido por el navegador, como estaba diciendo. Es un objeto estático, lo que significa que no necesitas crear una variable para comenzar a utilizar sus métodos y propiedades. Para usar un método del objeto Browser, debes usar, sencillamente, la sintaxis Browser.metodo (). Esto ejecutará el método que sea del objeto Browser. Este tiene muchas utilidades. Es una fuente de información, y también proporciona varias maneras de cambiar el mundo que estás viendo. En primer lugar, vamos a ver cómo obtener información del navegador del cliente.
Antes de todo esto, sin embargo, recordemos un par de cosas. Recuerdas que el nodo Script tiene dos campos llamado directOutput y mustEvaluate ¿no?. Éstos pueden ser bastante importantes al usar la interface del Browser, por lo que te recordaré levemente lo que hacen.
Vale, entonces vamos allá...
La Tecnología de la información
Bien. Lo primero que vamos a hacer es ver los métodos que permiten recoger información del usuario. Voy a enumerarlos, junto con una descripción corta de cada uno...
Puedes preguntarte para qué se usa realmente toda esta información. Bueno, puedes preparar scripts que funcionen en navegadores particulares, o tener versiones diferentes del mismo script según el navegador, o puedes proporcionar un arreglo de nivel de detalle dinámico dónde tu mundo se vuelve menos detallado si la proporción de fps cae demasiado.
Fuera del aire delgado...
Ahora cubriremos material más complejo, claro que mucho más útil también. Esto implica principalmente el cambio del mundo actual, de una manera u otra. De nuevo, cubriremos estas funciones una por una.
Como puedes ver, estos métodos también son bastante básicos, no hacen nada realmente asombroso. ¡Ahora, sin embargo, nos meteremos en la parte que nos permite crear VRML dinámicamente de la nada!
createVrmlFromX ()
Hay dos funciones que permiten crear nuevos fragmentos de código VRML de la nada, conocidas comunmente como las funciones createVrmlFromX. Estos son:
Ambos métodos funcionan de manera ligeramente distinta, como puedes ver por sus descripciones. Por qué es así, es algo que no sé. Quizás pensabas que funcionarían de la misma manera, pero no es así.createVrmlFromString toma una cadena como parámetro y devuelve un objeto MFNode que contiene el VRML de la cadena. Esta cadena debe ser VRML válido, y es completamente autónomo. Esto significa no puedes emplear USE de cosas cuyo DEF se encuentra fuera de esta cadena de texto, y lo mismo digo para las definiciones de PROTO. Puedes, sin embargo, incluir Routes en la cadena. Esencialmente, la cadena sería como un archivo separado, y como tal seguiría todas sus normas a excepción de la cabecera. Un ejemplo rápido de esto; Supongamos que estamos dentro de un script que tiene un MFNode eventOut llamado newChildren que va al evento addChildren de algun Group
newVRML = 'Shape {'; newVRML += ' appearance Appearance {'; newVRML += ' material Material {'; newVRML += ' diffuseColor 1 0 0'; newVRML += ' }'; newVRML += ' }'; newVRML += ' geometry Box {'; newVRML += ' }'; newVRML += '}'; newChildren = Browser.createVrmlFromString(newVRML);
Esto crea la cadena de texto que vamos a usar (No tienes por qué indentar las líneas, yo solo lo hago por que así me resulta más facil de leer), y entonces crea un nuevo MFNode a partir suyo. Este MFNode se asigna inmediatamente al eventOut newChildren, y se envía al nodo Group. No se reemplazan los children actuales del Group, el nuevo simplemente se agrega a ellos.
Sencillo por el momento, ¿no es así? El otro método de creación, sin embargo, es un poco más complejo. createVrmlFromString () trabaja de una manera muy simple y flexible. Por alguna razón, createVrmlFromURL () es más complejo y menos flexible. Con este método, creas un MFString que contiene una lista de URLs como primer parámetro, que el navegador tratará de cargar sucesivamente. Estos archivos deben contener VRML totalmente válido, obedeciendo todas las reglas normales. El script lee los nodos que hay dentro del archivo y éstos se convierten en los nuevos nodos del archivo original. Hasta aquí, bien, lo malo viene cuando tratas de envíar el nuevo MFNode a un nodo Group. Con un createVrmlFromString obtienes un objeto MFNode simple que puedes manipular como te de la gana, asignando variables como partes de esa cadena con operaciones simples de concatenación. createVrmlFromURL no devuelve nada. En cambio, manda al MFNode solo, desde dentro de la función. Esto es para lo que valen los otros dos parámetros. El primero es una referencia al nodo al que quieres agregarle nos nuevos, y el segundo es el nombre de un eventIn MFNode que recibirán los nuevos nodos. Creo que un ejemplo es lo mejor.
DEF GROUP Group { } Script { field SFNode group USE GROUP url "javascript: function initialize() { urlString = new MFString('cone.wrl'); Browser.createVrmlFromURL(urlString,group,'addChildren'); } " }
Como ves, los parámetros son el nombre del archivo a usar (en un MFString), la referencia del SFNode, y el nombre del eventIn. La función hace el resto, introduciendo los nuevos nodos en el eventIn del addChildren de group. No estoy bastante seguro por qué es de esta manera, pero estoy seguro de que el tipo que lo hizo tenía sus motivos. ¡Te los contaré si los averiguo! Como alternativa, puedes ignorar el createVRMLFromURL() y usar createVRMLFromString() con un nodo inLine que contenga el archivo que quieras cargar, así:
newVRML = 'Inline { url "cone.wrl" }';
newChildren = Browser.createVrmlFromString(newVRML);
Esto ofrece la funcionalidad de createVRMLFromURL() con el modo de empleo típico del CreateVRMLFromString(). Gracias a Eyal Teler por esta sugerencia.
Volviendo al trabajo, echa un ojo a este ejemplo, junto con el código. Como puedes ver, tenemos un bonito juguete con el que poder jugar y hacer bonitas composiciones. Pulsa los botones del fondo para crear un nuevo objeto. Puede arrastrar ese objeto dentro del área gris, construyendo modelos. Esto se hace creando un nuevo PlaneSensor junto con cada nueva Shape, y proporcionando todas las Route apropiadas dentro del string o archivo. Creamos el cubo y esfera de las cadenas de caracteres, mientras que el cono se crea directamente de un archivo VRML. Echa una mirada al código fuente de cone.wrl. Esto explicará cómo se usan estas útiles funciones, creo.
De A a B
Hay dos métodos más en el objeto Browser que sirven para la creación dinámica de mundos; son los métodos addRoute() y deleteRoute (). Curiosamente, agregan o anulan Rutas entre nodos. Son así...
Estos métodos tienen parámetros muy similares a los de createVrmlFromUrl(). El primero y el tercero son referencias SFNode que tienes que declarar previamente de algún modo, y el segundo y cuarto son cadenas de caracteres que identifican los eventos para unirlos. Son bastante simples en su concepto, la dificultad viene cuando intentas obtener las referencias los SFNode. Esto podría isignificar revisar el archivo entero buscando el nodo correcto que quieres modificar. Pueden ser, sin embargo, vitales si quieres añadir nuevas interfaces de usuario, o simplemente comunicar nodos dinámicamente. Por ejemplo, puedes crear nodos con createVrmlFromX (), y entonces unirlos al mundo con el método addRoute().
Vaporizado
Bueno, creo que está explicado todo, o al menos, yo lo veo así. Si quieres más información sobre la interface de scripts del Browser, te sugiero que miras en la sección 4.12.10 de la especificación. Explica todos los conceptos del objeto Browser. La sección C.6.3 explica lo cubierto de este objeto en ECMAScript. También en la página de las especificaciones tienes una referencia rápida de los objetos, propiedades y parámetros de EcmaScript, que pueden resultarte muy útiles.
Bien, creo que esto es todo lo que puedo enseñarte sobre el scripting en ECMAScript, realmente, y como tal es el fin de esta parte del tutorial. En la próxima parte, voy a revisar algo de Java que usted puedes usar para realizar tareas de script más complejas y estructuradas. Sin embargo, es otro lenguaje de programación entero. Sin embargo, creo que estás preparado, así que, ¡nos vemos allí!