MokaByte
Numero 18 - Aprile 1998
|
|||
|
|
||
|
|
||
Introduzione
Nell'articolo del mese di marzo ci siamo soffermati su un esempio di programmazione Java-Vrml abbastanza complesso: la creazione di un oggetto di forma umana in vrml e relativo controllo (animazioni inlcuse).
Proseguiamo ora con un altro esempio di applicazione java-vrml non banale. L'intento è quello di fornire una idea delle potenzialità offerte dall'uso combinato di Java e vrml (e spero che a questo punto del corso ciò sia abbastanza chiaro a tutti i lettori che mi hanno seguito). Inoltre rappresenta un'ottima occasione sia per rivedere concetti visti nei mesi scorsi, sia per affrontare nuovi aspetti tralasciati in precedenza.
L'esempio analizzato
in questo articolo riguarda la creazione di una applet Java in grado di
consentire all'utente la generazione di semplici ambienti vrml: in pratica
una sorta di tool visuale.
Ovviamente quello
che si otterrà alla fine non potrà essere paragonato con
i vari strumenti di authoring vrml presenti in circolazione: questo non
è l'intento che si vuole conseguire. Tant'è che in questa
prima versione dell'applicazione non è neppure prevista la possibilità
di salvare gli ambienti creati. Questa limitazione è senz'altro
pesante ed è connessa alle varie restrizioni imposte dai browsers
html nella gestione dei files. Nel prossimo articolo mi riprometto di analizzare
meglio la questione, cercando di trovare una soluzione.
Quale potrebbe essere allora l'utilità di una tale applicazione? Questa domanda ha senso soprattutto in considerazione del fatto che non riusciremo certo ad ottenere un tool comparabile ai vari strumenti di authoring già presenti.
L'aspetto veramente
interessante è fornito dal fatto che la creazione del mondo avviene
on-line. Tralasciando il fatto che la Telecom sarebbe senz'altro contenta
se tutti noi creassimo mondi vrml on-line, va notato il fatto che in questo
modo si aprono scenari decisamente interessanti.
Potremmo infatti
pensare ad ambienti vrml modificati e costruiti da più persone.
Ogni utente fornisce il proprio apporto specifico, aggiungendo qualche
pezzo al mondo vrml. I navigatori che accedono al mondo successivamente
alla modifica vedranno l'ambiente modificato e potranno a loro volta effettuare
aggiunte.
Un'altra applicazione
potrebbe essere rappresentata dalla collaborazione tra più utenti
connessi allo stesso mondo per la creazione di un certo oggetto. La cooperazione
on-line rappresenta uno dei settori della realtà virtuale di maggiore
interesse e sul quale si incentrano diverse attività di ricerca.
Alla conclusione
di questo articolo certamente non sarete in grado di realizzare applicazioni
di questo tipo (o quantomeno non lo sarete se vi affidate solo a quanto
in questo articolo è raccontato ;) ).
Come sempre,
è però meglio iniziare da qualche parte. Questo articolo
fornirà quindi le basi per costruirsi un proprio semplice tool di
creazione di mondi vrml, dove per semplice intendo che verrà data
la possibilità di creare banali oggetti (coni, sfere, cilindri,
box), di spostarli e ruotarli nell'ambiente e di modificare il loro colore.
Il tutto in modo visuale e interattivo.
Cosa manca? Moltissimo!
In primo luogo manca la possibilità di rendere persistenti le modifiche
(e con questo potremmo realizzare il mondo costruito da più persone
cui accennavo prima).
Per quanto riguarda
invece la creazione di ambienti nei quali gli utenti possono collaborare
alla creazione di oggetti/prototipi, manca ancora molto: in particolare
si devono toccare vari argomenti legati al networking, necessari per consentire
a più utenti di condividere gli stessi ambienti. Per quanto riguarda
quest'ultimo argomento, che rientra nella sfera degli ambienti virtuali
condivisi, sto valutando l'opportunità di uno o più articoli
futuri che trattino l'argomento. Presso il gruppo VRML DREAMERS (http://www.lucia.it/vrml)
stiamo realizzando un progetto di questo tipo e un prototipo funzionante
è già presente presso il sito http://multidream.logicom.it.
Si tratta del primo ambiente in multi-utenza vrml on-line presente in Italia.
Vi invito a farci un salto: sul sito troverete anche un po' di documentazione
sull'argomento. Per chi fosse interessato a provarlo, periodicamente il
gruppo organizza delle 'assemblee' virtuali che solitamente vengono comunicate
sul newsgroup it.comp.lang.vrml. Chiusa parentesi.
Torniamo ora
all'argomento di questo articolo: semplice tool visuale per la creazione
di ambienti vrml.
Specifiche del tool
Come dicevo in precedenza il tool sarà molto semplice. In particolare l'utente potrà creare oggetti dei seguenti tipi:
Gli oggetti aggiunti devono poter essere posizionati all'interno dell'ambiente. A tal fine si è optato di concedere all'utente la possibilità di effettuare operazioni di drag and drop. In pratica basterà trascinare l'oggetto nella posizione desiderata. (In realtà vi sono delle problematiche non banali per raggiungere questo obiettivo, ma le vedremo al momento opportuno).
L'applet deve inoltre concedere la possbilità di ruotare e scalare gli oggetti introdotti.
Deve essere possibile riselezionare un oggetto preesistente in modo da modificarne le caratteristiche.
Infine, si deve concedere all'utente la possibilità di modificare il colore associato ad un oggetto.
Come potete notare le specifiche imposte al progetto sono abbastanza semplici. La relativa implementazione richiede però di superare problematiche di una certa difficoltà, legate soprattutto alle operazioni di drag and drop.
Si procede ora
ad analizzare le diverse parti di cui si compone l'applicazione.
Layout dell'applet
Partiamo dall'aspetto più semplice; probabilmente il meno importante. E' comunque utile rendersi subito conto di come dovrà apparire l'applicazione finale.
La figura seguente mostra il layout dell'applet.
Nella parte destra
dell'applet si trova una casella di scelta per la selezione degli oggetti
da aggiungere. Il pulsante Add consente di aggiungere di fatto l'oggetto
selezionato al mondo vrml.
Sempre in altro,
si trovano tre barre di scorrimento che consentono di modificare le componenti
R (rosso) G (verde) B (blu) del colore da assegnare ad un oggetto.
I sei pulsanti
di rotazione consentono di ruotare l'oggetto selezionato lungo i 3 assi
principali. I sei pulsanti di scale consentono di scalarlo. Gli step di
rotazione e di scala possono essere specificati attraverso i campi di input
posti in basso.
I pulsanti 'Up'
e 'Down' sono necessari per completare le operazioni di spostamento degli
oggetti. Infatti una traslazione mediante drag & drop con il mouse
può coprire al massimo due dei tre gradi di libertà necessari.
Si è scelto di sfruttare i movimenti del mouse per posizionare gli
oggetti su un piano x,z (ricordo che l'asse z è perpendicolare allo
schermo). Per modificare il piano x,z su cui muoversi (in pratica per alzare
o abbassare l'oggetto) si deve agire con i pulsanti 'Up' e 'Down'.
Cosa manca? Mancano almeno due pulsanti:
Aggiungere oggetti a run-time
L'aggiunta di oggetti a run-time è già stata analizzata nella quarta lezione di questo corso. In quell'articolo abbiamo visto come sia possibile creare dinamicamente dei nodi vrml e aggiungerli alla scena. A questo punto viene dunque data per scontata la conoscenza di questo argomento.
Partendo da un mondo vrml vuoto (o quasi, poi vedremo cosa dovrà essere presente in partenza), l'utente può aggiungere dinamicamente semplici oggetti. Si dovrà dunque invocare il metodo createVrmlFromString passando come parametri delle stringhe opportune. La costruzione delle stringhe dipende dalla particolare geometria selezionata (box, cono, cilindro o sfera).
Sugli oggetti
aggiunti devono essere possibili diverse operazioni, in particolare: traslazione,
rotazione, cambio di colore, cambio di scala. Risulta dunque necessario
acquisire le references ai campi che controllano questi parametri.
Tutte queste
operazioni vanno ovviamente effettuate per qualunque oggetto presente nella
scena.
A questo punto
è necessario analizzare in dettaglio la tecnica utilizzata per effettuare
le operazioni di drag and drop, in quanto da essa dipendono molte delle
operazioni da effettuare per aggiungere un oggetto.
Traslazione degli oggetti
Per traslare un oggetto abbiamo scelto la via più complicata: sarebbe stato certamente molto più semplice introdurre altri quattro bottoni in grado di controllare gli spostamenti lungo x e z. Abbiamo deciso di utilizzare il mouse in quanto il risultato finale offre certamente una maggiore comodità e rapidità di azione: dovremo però pagare in termini di complessità.
Per monitorare il movimento del mouse a pulsante premuto, sfruttiamo un nodo vrml visto un paio di lezioni fa: il nodo PlaneSensor.
Tale nodo è in grado di emettere la variazione di posizione del mouse su un piano x,y (a pulsante premuto sopra l'oggetto cui il sensore è associato). Dato che vogliamo controllare la posizione dell'oggetto su un piano x,z (per alzare/abbassare usiamo i pulsanti Up e Down) rimappiamo le traslazioni su x,y in traslazioni su x,z (la componente y viene mappata sulla z).
Cliccando sull'oggetto e trascinando verso l'alto si ottiene dunque l'effetto di allontanare l'oggetto.
Nasce subito una subdola complicazione.
Seguitemi per
bene in questo punto: quando associamo un PlaneSensor ad un oggetto, piazziamo
un piano invisibile che 'attraversa' l'oggetto. Il piano, senza trasformazioni
esterne, è definito normale all'asse z.
Supponiamo ora
che l'utente prema sull'oggetto (il sensore inizia quindi ad emettere eventi)
e trascini il mouse verso l'alto. Le traslazioni positive lungo y vengono
rimappate in traslazioni negative su z: l'oggetto, correttamente, si allontana.
Fin qui tutto bene. Ma a questo punto l'utente decide di ruotare attorno
all'oggetto e si pone alle sue spalle (sta ora guardando nella direzione
positiva delle z). Una traslazione positiva sulle y in uscita dal sensore
DEVE rimapparsi in una traslazione POSITIVA (e non più negativa)
delle z: per coerenza l'oggetto dovrà allontanarsi e non avvicinarsi!
In pratica l'uscita del sensore è in entrambi i casi identica (in
quanto in entrambi i casi ho fatto un drag verso l'alto), ma l'uscita deve
essere diversa (devo sempre allontanare l'oggetto dall'utente).
Per risolvere questa situazione introduco nell'ambiente un sensore di prossimità. Questo sensore non è ancora stato analizzato. Il suo funzionamento è molto semplice: rileva gli spostamenti dell'utente all'interno del mondo.
Per esempio:
Questo breve sorgente vrml definisce un sensore di prossimità centrato nell'origine e in grado di monitorare tutto il volume di una Box di lato 1000 (con buona approssimazione tutto il mondo vrml se l'utente non esce mai al di fuori di questo volume).DEF sensore ProximitySensor {
center 0 0 0
size 1000 1000 1000
}
Il sensore emette due eventi molto interessanti:
L'evento translation_changed è di tipo SFVec3f e contiene la nuova posizione dell'utente. Ad ogni spostamento dell'utente il sensore emette un nuovo valore riportante la sua posizione in coordinate assolute.
L'evento orientation_changed è di tipo SFRotation e contiene il nuovo orientamento dell'utente. Ad ogni cambio di orientamento si genera un evento di questo tipo.
A questo punto è chiaro a cosa possa servirci un tale nodo. All'interno dell'applet ci mettiamo in ascolto degli eventi translation_changed in uscita dal sensore. Per ogni evento arrivato aggiorniamo un paio di variabili interne che fungono da immagine della posizione attuale dell'utente. Quando sopraggiunge un evento dal PlaneSensor (e quindi è in atto una operazione di drag sull'oggetto), si verifica la posizione dell'utente rispetto all'oggetto; in base ad essa si potrà dunque decidere come rimappare le y sulle z (se cioè renderle negative oppure conservarle positive).
Primo problema risolto... e anche senza eccessiva fatica.
Problema numero 2: supponiamo ora di camminare attorno all'oggetto sino a quanto ci troviamo ad osservarlo ad un angolo di 90 gradi rispetto alla posizione iniziale (lo stiamo guardando di lato). Se pensiamo ancora al nostro piano invisibile su cui agisce il PlaneSensor, scoprirete che adesso vi sta passando attraverso. Il sensore opera sull'oggetto, quindi quando cliccate il mouse sopra l'oggetto e fate un drag qualcosa in uscita lo otterrete senz'altro. Il problema qui è che a piccolissime variazioni lungo x, corrispondono ENORMI variazioni in uscita dal PlaneSensor (questo perchè l'angolo tra voi e il piano è molto piccolo, tendente a zero: rifletteteci un attimo e capirete il motivo di questo problema: la prima volta che mi capitava restavo allibito davanti ad un oggetto che alla minima traslazione veniva catapultato a migliaia di metri di distanza!!!).
Il problema non è di così semplice soluzione come il precedente. O almeno questa soluzione semplice io non l'ho ancora trovata: per cui vi sottopongo quella che sono riuscito a mettere insieme dopo qualche notte insonne ;) .
Sarebbe moooolto bello che il piano ruotasse assieme all'osservatore. Fare cioè in modo che esso risulti sempre normale rispetto alla congiungente utente-oggetto. In questo modo avremmo risolto i problemi relativi alle traslazioni lungo x.
Esiste un nodo
Vrml che fa decisamente al caso nostro: Billboard.
Consente infatti
di ruotare automaticamente l'oggetto presente all'interno del suo campo
children in modo da presentarsi sempre di fronte all'osservatore. Il suo
orientamento dipende dunque dalla posizione che l'utente assume all'interno
del mondo.
Per esempio:
In questo modo avrete una Box sempre rivolta verso l'utente. L'osservatore vedrà sempre la faccia frontale e non potrà mai vederne gli spigoli laterali. L'asse attorno al quale ruotare viene specificato dal campo axisOfRotation: 0 1 0 indica l'asse y.Billboard {
axisOfRotation 0 1 0
children [
Shape {
appearance Appearance {
material Material { diffuseColor 1 0 0 }
}
geometry Box { size 10 10 10 }
}
]
}
Inserendo il nodo PlaneSensor all'interno di un campo children di un nodo Billboard il gioco è fatto. Il piano relativo al PlaneSensor ruoterà assieme all'utente e sarà sempre perpendicolare alla congiungente osservatore-oggetto.
Fatto questo nasce però un secondo problema: non possiamo più associare il PlaneSensor all'oggetto da traslare. Perchè? semplice! Dato che l'oggetto da associare al PlaneSensor deve essere presente all'interno dello stesso campo children cui il sensore appartiene, si avrebbe un effetto Billboard anche sull'oggetto introdotto. Il risultato è semplice da immaginare, con l'oggetto stesso che ruota in funzione della posizione dell'osservatore, e con l'utente di fronte al monitor a domandarsi del perchè il programmatore abbia introdotto dei pulsanti di rotazione, visto che poi l'oggetto si mette a ruotare da solo!
La soluzione
che ho scelto di seguire è la seguente:
non fare il
drag direttamente sull'oggetto, ma su un apposito cursore ad esso associato.
Sarà il cursore ad essere inserito nel campo children del nodo Billboard
e sarà dunque lui a ruotare in funzione degli spostamenti dell'utente.
L'oggetto aggiunto sarà al di fuori del nodo Billboard e quindi
se ne resterà tranquillamente fermo.
Spero che a questo punto non vi siate persi. Comunque, sappiate che abbiamo finito: l'operazione di drag and drop adesso funziona che è una meraviglia ;).
Per concludere questa parte, riporto il codice vrml che deve essere presente nel mondo vrml 'vuoto', quello cioè presente prima di iniziare a costruire.
Tralasciamo i nodi relativi a luci e punti di vista.
#VRML V2.0 utf8
Viewpoint {
position 7 2 8
orientation 0 1 0 .5
description "inizio"
}
NavigationInfo {
headlight FALSE
avatarSize [.5 2.0 .5]
}
DirectionalLight{
direction -.5 -1 .2
intensity 1
}
DirectionalLight {
direction 0 0 -1
intensity .5
}
DEF sensore ProximitySensor {
center 0 0 0
size 1000 1000 1000
enabled TRUE
}
DEF Root Group {
children [
DEF Cursor Transform {
children [
DEF Bill Transform {
children [
Shape {
appearance Appearance {
material Material { diffuseColor 0 0 1 }
}
geometry Box { size 3 .2 .2 }
}
Shape {
appearance Appearance {
material Material { diffuseColor 0 0 1 }
}
geometry Box { size .2 .2 3 }
}
]
}
DEF Sens PlaneSensor {}
]
}
]
}
La parte più
interessante riguarda il nodo Root.
Questo nodo
è destinato ad ospitare tutti i nodi creati a run-time e contenenti
i vari oggetti aggiunti dall'utente. Ogni oggetto che verrà creato
verrà aggiunto come figlio diretto di questo nodo. Si badi dunque
che si trova ad un livello gerarchico superiore rispetto al nodo Billboard.
Il nodo Root
contiene anche un nodo predefinito di nome Cursor. Tale nodo definisce
il cursore da associare all'oggetto attivo in un certo istante (quello
su cui si ripercuotono le varie operazioni di scala, rotazione, cambio
colore, ecc.).
Come si può
notare il nodo Cursor incapsula un nodo Billboard, il quale a sua volta
contiene la descrizione fisica del cursore (un paio di Box messe in croce)
e il PlaneSensor ad esso associato.
Il nodo Transform
che avvolge il nodo Billboard è necessario per poter traslare il
cursore da un oggetto ad un altro in conseguenza della selezione da parte
dell'utente di un certo oggetto.
Concludendo,
rimane appunto da analizzare quest'ultimo aspetto: la possibilità
cioè di riselezionare un oggetto aggiunto precedentemente in modo
da modificare alcuni dei suoi parametri.
L'oggetto selezionato
correntemente viene evidenziato dal cursore. Per selezionare un altro oggetto
basta cliccarci sopra: in conseguenza di questo fatto il cursore si sposta
sull'oggetto selezionato. Sarà dunque indispensabile associare un
sensore di tocco quando si procede ad aggiungere a run-time i nodi vrml
che costituiscono le varie entità di cui si compone la scena.
Costruzione dell'applet Java
Analizziamo ora molto velocemente l'applet Java che consente di controllare il tutto.
L'applet si compone di due classi:
In occasione della creazione di una nuova entità (box, sfera, cono o cilindro), si istanzia un oggetto dell'altra classe. Quindi in un certo momento saranno attivi un oggetto della classe Builder e tanti oggetti della classe Oggetto.
La classe Oggetto incapsula al suo interno tutti i dati relativi ad un particolare oggetto introdotto (con il nome della classe uguale ad 'Oggetto' qui le ripetizioni si sprecano: sorry, ma l'importante è che alla fine si capisca qualcosa ;) ). Oltre ai dati specifici di ogni entità aggiunta, la classe esporta una serie di metodi che consentono di traslare, ruotare, scalare e cambiare di colore ad un certo oggetto.
Tutte le problematiche principali legate all'applicazione sono state analizzate nel paragrafo precedente. Tralasciamo ora il codice relativo alla classe Builder: è molto banale e di fatto non fa altro che recepire gli eventi AWT, instanziare oggetti della classe Oggetto quando serve e invocare gli opportuni metodi per modificare alcune caratteristiche dell'entità selezionata.
Unico aspetto
da notare è rappresentato dalla modalità di acquisizione
della reference al browser vrml. E' meglio abbandonare la tecnica che ho
seguito sino a questo momento nel corso (sfruttare cioè le classi
di Netscape). Sul sito della Silicon Graphics e sulle FAQ EAI è
consigliato utilizzare la seguente forma:
browser = Browser.getBrowser(this);
Questo dovrebbe
conferire anche maggiore portabilità alle vostre applet EAI.
Sino ad ora
avevo seguito l'approccio alternativo in quanto era quello utilizzato all'interno
delle specifiche EAI come scritte da Chris Marrin.
La parte più interessante della classe Oggetto è quella relativa alla creazione della nuova entità.
Qui di seguito riporto il sorgente corrispondente:
Non spaventatevi! Non è poi così complicato.
try {
// Nodo per il planeSensor
plane = browser.getNode("Sens");
// Nodo Billboard
bill = browser.getNode("Bill");
// Nodo per il cursore
cursor = browser.getNode("Cursor");
// evento in uscita dal nodo PlaneSensor
translation_changed = (EventOutSFVec3f) plane.getEventOut("translation_changed");
translation_changed.advise(this, new Integer(3));
// campi per settare la traslazione e la rotazione del cursore
cursor_translation = (EventInSFVec3f) cursor.getEventIn("set_translation");
cursor_rotation = (EventInSFRotation) cursor.getEventIn("set_rotation");
bill_scale = (EventInSFVec3f) bill.getEventIn("set_scale");
// risetto a 0
cursor_translation.setValue(position);
bill_scale.setValue(scale_cursor);
// nodo radice al quale devono essere aggiunti i vari oggetti
rootNode = browser.getNode("Root");
rootChildren = (EventInMFNode) rootNode.getEventIn("addChildren");
rootRemoveChildren = (EventInMFNode) rootNode.getEventIn("removeChildren");
// current_node è il nodo che dovrà essere aggiunto
// conterrà altri sotto-nodi
current_node = browser.createVrmlFromString("Transform {}");
// sensore di tocco da associare all'utente
touch = browser.createVrmlFromString("TouchSensor {}");
// tre livelli di Transform per introdurre le tre rotazioni
transf_x = browser.createVrmlFromString("Transform {}");
transf_y = browser.createVrmlFromString("Transform {}");
transf_z = browser.createVrmlFromString("Transform {}");
// tre rotazioni relative ai 3 nodi Transform precedenti
// consentono di ruotare l'oggetto lungo tre diversi
// assi
// NB: le rotazioni non funzionano con Cosmo Player 1.0
rot_x = (EventInSFRotation) transf_x[0].getEventIn("set_rotation");
rot_y = (EventInSFRotation) transf_y[0].getEventIn("set_rotation");
rot_z = (EventInSFRotation) transf_z[0].getEventIn("set_rotation");
children = (EventInMFNode) current_node[0].getEventIn("addChildren");
children.setValue(touch);
children.setValue(transf_x);
transfChildren_x = (EventInMFNode) transf_x[0].getEventIn("addChildren");
transfChildren_y = (EventInMFNode) transf_y[0].getEventIn("addChildren");
transfChildren_z = (EventInMFNode) transf_z[0].getEventIn("addChildren");
// Creazione del nuovo nodo Shape
nuovo_shape = browser.createVrmlFromString("Shape{}");
nuovo_app = browser.createVrmlFromString("Appearance{}");
nuovo_mat = browser.createVrmlFromString("Material{}");
if (tipo == 0)
nuovo_nodo = "Box{}"";
if (tipo == 1)
nuovo_nodo = "Cone{}"";
if (tipo == 2)
nuovo_nodo = "Cylinder{}"";
if (tipo == 3)
nuovo_nodo = "Sphere{}"";
if (tipo == 4)
nuovo_nodo = "Box{}"";
nuovo_geo = browser.createVrmlFromString(nuovo_nodo);
appearance = (EventInSFNode) nuovo_shape[0].getEventIn("appearance");
appearance.setValue(nuovo_app[0]);
material = (EventInSFNode) nuovo_app[0].getEventIn("material");
material.setValue(nuovo_mat[0]);
color = (EventInSFColor) nuovo_mat[0].getEventIn("set_diffuseColor");
col[0] = red;
col[1] = green;
col[2] = blue;
color.setValue(col);
geometry = (EventInSFNode) nuovo_shape[0].getEventIn("geometry");
geometry.setValue(nuovo_geo[0]);
transfChildren_z.setValue(nuovo_shape);
transfChildren_y.setValue(transf_z);
transfChildren_x.setValue(transf_y);
// traslazione e scala dell'oggetto
translation = (EventInSFVec3f) current_node[0].getEventIn("set_translation");
scale = (EventInSFVec3f) current_node[0].getEventIn("set_scale");
// evento di pressione sul TouchSensor
clicked = (EventOutSFBool) touch[0].getEventOut("isActive");
clicked.advise(this, new Integer(2));
// aggiungo di fatto il nodo alla Root
rootChildren.setValue(current_node);
In sostanza vengono effettuate le seguenti operazioni:
children [
Transform { # nodo identificato da transf_x
children [
Transform { # nodo identificato da transf_y
children [
Transform { # nodo identificato da transf_z
children [
Shape { .... }
TouchSensor {}
]
}
]
}
]
}
]
}
I diversi nodi Transform che avvolgono il nodo Shape aggiunto sono necessari per implementare le diverse rotazioni a cui sottoporre l'oggetto.
Chiudo qui con la spiegazione di questa demo. Sono conscio del fatto che probabilmente vi saranno rimasti molti dubbi (direi che è fisiologico). Come nel caso dell'esempio dell'umano del mese scorso, non è mio intendimento fornire delle spiegazioni troppo dettagliate degli esercizi proposti: sarebbe probabilmente inutile e comunque troppo noioso. Mi basta dare l'idea di cosa possa essere realizzato sfruttando la EAI... e magari fornire qualche spunto per la realizzazione di progetti più complessi.
Vi lascio ora alla demo così faticosamente costruita: per la cronaca, la demo è nata come adattamento di un lavoro che ho svolto tempo fa per il consorzio Corinto, collegato alla IBM. Si trattava di un tool di creazione interattiva di stanze arredate. In pratica è molto simile a quello che è raccontato in questo articolo, con la sola differenza che in quel caso si introducevano direttamente dei mobili invece che delle semplici primitive geometriche: nessun problema -> basta creare a run-time un nodo Inline con il mobile desiderato invece di creare un semplice nodo Shape.
A causa di un bug presente in Cosmo Player 1.0 le rotazioni sugli oggetti non funzionano. Con Cosmo Player 2.0 le rotazioni sono gestite correttamente.
Sorgente file Builder.java: Builder.java
Sorgente file Oggetto.java:
Oggetto.java
Dove andare ora?
Bella domanda! Abbiamo analizzato molti particolari e esempi riguardanti la EAI. Gli ultimi due esempi sono stati tuttaltro che banali. Temo che alla fine l'utilità di questo corso possa scemare tendendo ad andare troppo sul complicato. Per i prossimi mesi sarei intenzionato a trattare la realizzazione di un paio di applicazioni complesse, alcune che ho già realizzato (e quindi pronte), altre ancora in fase di studio. In particolare, per il mese prossimo intendevo affrontare un aspetto che mi è stato richiesto da più parti: come rendere persistenti le modifiche in un mondo vrml registrandole su file. Anche se si tratta di un argomento più java che vrml, penso di dedicarci un po' di attenzione per cercare una soluzione (ad oggi non so ancora come fare ad aggirare le barriere di Netscape e Explorer: se qualcuno ne sa di più mi lasci una mail).
Per il futuro penserei di parlarvi un po' di come realizzare un ambiente vrml in multi-utenza seguendo il modello implementativo di MultiDream, l'applicazione realizzata presso il gruppo VRML DREAMERS. Ovviamente si tratterà di un'analisi piuttosto superficiale, volta ad analizzare gli aspetti più interessanti e di base.
Prima di concludere,
vorrei chiedere all'ipotetico encomiabile lettore che mi ha seguito sino a
questo punto cosa ne pensa del corso. Mi piacerebbe sapere se ritiene interessante
l'esame di esempi complessi o se viceversa preferirebbe continuare con nozioni
di base; se l'analisi di questi esempi è sufficientemente chiara oppure
se risulta completamente oscura e priva di utilità pratica (perchè
hai letto sino a qui allora? ;))) ).
In conclusione, se
siete giunti a leggere sino a qui, mandatemi una email e fatemi sapere quanti
sono i super-eroi che ce l'hanno fatta ;). Email: ignazio@logicom.it
Notizie dai Vrml Dreamers
Vorrei ricordare
che stiamo organizzando una gara di mondi vrml (la seconda edizione) rivolta
alle realizzazioni vrml nazionali (e non... se ne arrivano). Partecipare è
semplice! Basta spedire un vostro mondo vrml all'indirizzo joust-drs@logicom.it
entro il 30 aprile 1998. Il mondo vrml deve essere VOSTRO, non deve cioè
contenere oggetti presi da librerie presenti su internet. Il regolamento lo
trovate presso il sito del gruppo vrml dreamers (http://www.lucia.it/vrml).
Le votazioni verranno effettuate via email sempre sul sito dei Dreamers a
partire dall'1 maggio 1998 sino a domenica 24 maggio.
RICORDO CHE NON E'
NECESSARIO REALIZZARE DELLE OPERE D'ARTE. La gara è organizzata al
solo scopo di divertirsi e per creare un punto di incontro tra quanti sviluppano
vrml in Italia. Un mondo in più, anche se fosse estremamente banale,
verrebbe comunque accolto con enorme piacere dall'organizzazione.
Vi aspettiamo, sia per partecipare che per votare!
NB: i risultati
delle votazioni verranno dati in anteprima durante una assemblea virtuale
in MultiDream! Sarà la PRIMA VERA assemblea vrml in Italia!!! vi aspettiamo
anche in quella occasione (mi sa che metteremo a dura prova le capacità
della nostra creatura ;) ).
Bye
\/irtual |\/|ad
Ignazio
Locatelli
|
||
|
||
MokaByte
ricerca nuovi collaboratori |
||
|