(Prima parte: i concetti)
Come detto nel precedente capitolo, l'uso di Java combinato a VRML rappresenta
un mezzo potentissimo per la gestione di mondi virtuali su internet. Come vedremo
tra breve il suo impiego all'interno di un file VRML è abbastanza semplice,
anche se viene richiesta una discreta conoscenza del linguaggio Java per la
creazione dell'applet.
In questo capitolo verrà presentata la modalita' standard JSAI che prevede
l'impiego del nodo Script. Per motivi di spazio, il capitolo è stato fisicamente
diviso in due parti: qui ci occuperemo soprattutto di analizzare come il file
VRML e il la classe Java possano interagire tra loro; mentre i sorgenti completi
dei file vengono presentati nella seconda parte.
Procurarsi il JDK e trovare i packages VRML
Va detto subito che, per ovvi motivi, non possiamo affrontare in questa sede
le questioni riguardanti l'installazione e il settaggio di un set per la programmazione
Java. Questo set è meglio conosciuto come JDK (Java Development Kit).
Si tratta di un kit, appunto, che permette di realizzare programmi e applet
scritte in java. Inoltre egli contiene anche il compilatore che consente di
tradurre il codice sorgente .java in codebyte .class. Il JDK è
scaricabile gratuitamente presso il sito http://www.javasoft.com/.
Per la realizzazione del nostro esempio si è utilizzato il JDK 1.1.8. Per quanto
riguarda la sua installazione (peraltro molto semplice) si rimanda alla sezione
Java del nostro sito.
Come anticipato nel precedente capitolo, Java in un mondo VRML non gira come
un applet; infatti la classe deve essere definita come estensione di una classe
Script che viene fornita con il browser VRML. Assieme al browser infatti
vengono distribuite tutte le classi che servono per interfacciare il mondo VRML
con la classe. Con la versione 2.1.1 di Cosmo Player, le classi in questione
vengono fornite automaticamente all'atto dell'installazione del player stesso,
sotto forma di archivio compresso: per il browser Internet Explorer questo archivio
è chiamato npcosmop211.zip, ed è situato in genere nella cartella di
installazione CosmoPlayer.
Come si è detto, una volta scritto il codice sorgente di un file java, questo
deve essere compilato. Per fare ciò, il compilatore java deve necessariamente
sapere dove si trovano i packages VRML. A tale scopo occorre apportare una semplice
modifica alla CLASSPATH del sistema, aggiungendo all'elenco l'indirizzo
presso il quale sono reperibili. Nel nostro caso:
SET CLASSPATH= C:ProgrammiCosmoSoftwareCosmoPlayernpcosmop211.zip;
Una volta apportata la modifica e riavviato il sistema, si è finalmente in
grado di programmare VRML con Java.
Un semplice esempio
Supponiamo ora di volere realizzare una scena VRML che funzioni nel seguente
modo: cliccando alternativamente su alcuni oggetti, si può ottenere che altri
oggetti della nostra scena subiscano una serie di cambiamenti. Nel nostro esempio,
per semplificare il tutto si è deciso di realizzare una scena contenente un
semplice cono e tre pulsanti. Cliccando su di essi potremo cambiare il colore
del cono.
Analisi del codice VRML
Occupiamoci in primo luogo di stabilire quali sono le caratteristiche del cono
che si vogliono cambiare. Sappiamo che il colore di un oggetto è descritto all'interno
del nodo Material:
[...]
Shape {
appearance Appearance {
material DEF conoMaterial Material { diffuseColor 0.75 0.75
0.75}
}
geometry Cone { bottomRadius 1.5
height 3}
}
[...]
Ora possiamo definire il nodo Script e dichiarare tre campi di tipo
eventIn relativi ai colori rosso, verde e blu. Questi campi riceveranno
dai rispettivi sensori l'informazione del momento in cui sono stati cliccati
(la trasmissione di questi dati avviene, ovviamente, grazie al comando ROUTE).
Si noti che si è dichiarato un field di tipo SFNode che "clona" il colore
del cono in base ai valori del campo diffuseColor sopra impostati.
L'url, infine, indica il collegamento alla classe java che gestirà le
operazioni:
[...]
DEF cambio_colore Script {
directOutput trUE
field SFNode coloreMaterial USE conoMaterial
eventIn SFTime set_rosso
eventIn SFTime set_verde
eventIn SFTime set_blu
url "RGB.class"
}
[...]
Per concludere il file .wrl, si impostano gli adeguati ROUTE.
Ognuno di essi si incarica di rilevare il momento in cui ogni sensore è attivato
dal "click" e di trasmetterlo al campo corrispondente:
[...]
ROUTE sensore_rosso.touchTime TO cambio_colore.set_rosso
ROUTE sensore_verde.touchTime TO cambio_colore.set_verde
ROUTE sensore_blu.touchTime TO cambio_colore.set_blu
[...]
Analisi del sorgente java
Cerchiamo ora di analizzare i punti fondamentali del sorgente.
- Inizialmente si importano i packages necessari. Si tratta di una serie di
classi che ci servono per gestire all'interno di una classe java i tipi VRML,
nonchè l'arrivo di eventi dal mondo VRML:import vrml.*;
import vrml.field.*;
import vrml.node.*; - Segue la dichiarazione della classe che chiameremo RGB, che come si vede
è un estensione della superclasse Script:public class RGB extends Script {
Ora si tratta di gestire l'evento "click" sulla parola "Rosso", di modo che
si abbia come risposta il cambiamento desiderato del colore del cono. - Quando, all'interno della scena VRML, clicchiamo sulla parola "Rosso" il
nodo Script riceve dal comando ROUTE un valore di tipo eventIn
per il campo set_rosso. A questo punto il browser VRML invoca il
metodo processEvent dichiarato nella classe:public void processEvent(Event e) {
Questo processo in pratica, si incarica di modificare il valore del campo diffuseColor
che descrive il colore del cono. Per fare questo lo script effettua innanzitutto
una chiamata getField al campo coloreMaterial.SFNode coloreMaterial = (SFNode) getField("coloreMaterial");
Successivamente, il nodo coloreMaterialNode acquisisce il valore del
nodo coloreMaterial, recuperato con la chiamata getValue.Node coloreMaterialNode = (Node) coloreMaterial.getValue();
Il nodo coloreColor viene collegato al campo diffuseColor del
nodo conoMaterial, a sua volta contenuto nel nodo Material dell'oggetto
che abbiamo chiamato cono. Ciò si ottiene con il metodo getExposedField
:SFColor coloreColor = (SFColor)
coloreMaterialNode.getExposedField("diffuseColor");L'ultima operazione dichiara di settare (setValue) un nuovo valore RGB
(in questo caso il rosso) per il nodo coloreColor, il quale a sua volta
lo trasmetterà al campo diffuseColor al quale è precedentemente stato
collegato.coloreColor.setValue(new SFColor(1,0,0));
Ecco la porzione di codice completa. Si tenga presente che quanto realizzato
per l'evento "click" sulla parola "Rosso", va ripetuta con le opportune modifiche
anche per gli altri due pulsanti "Verde" e "Blu".
[...]
public void processEvent(Event e) {
if(e.getName().equals("set_rosso")) {
SFNode coloreMaterial = (SFNode) getField("coloreMaterial");
Node coloreMaterialNode = (Node) coloreMaterial.getValue();
SFColor coloreColor = (SFColor)
coloreMaterialNode.getExposedField("diffuseColor");
coloreColor.setValue(new SFColor(1,0,0));
}
[...]