|
||||||
ROBOTICA
video
immagini
papers
progettati
costruiti
toolbox
vrml
simulatori
Prototyping |
Fino ad ora abbiamo visto
diversi aspetti della specifica 2.0 di Vrml e abbiamo analizzato la maggior
parte dei nodi. Ne mancano ancora alcuni, come per esempio i vari PlaneSensor,
SphereSensor...; altri sono stati analizzati solo in parte: mi riferisco in
particolare al nodo Material, di cui abbiamo analizzato solo pochissime componenti,
al nodo Transform e altri che presentano fields che non ho preso in considerazione
nelle passate lezioni.
Salvo eventuali future
lezioni, non intendo affrontare questi argomenti, sperando che a questo punto
abbiate gli stimoli giusti per andare a cercare direttamente nelle specifiche
quando incontrate qualche problema o avete qualche particolare effetto da
inserire nel vostro mondo. In ogni caso potete anche chiedere tramite email;
solitamente sono abbastanza celere nel rispondere.
Fatta questa piccola
prefazione, passiamo ora all'argomento della lezione. Con il comando PROTO
il programmatore VRML puo' crearsi nuovi nodi, diversi da quelli previsti
dalla specifica. Ci si potrebbe domandare il perche' di questa azione; in
particolare questo consente un maggiore riutilizzo del codice, cosa che peraltro
era possibile anche nel caso del comando USE. Vediamo di chiarire meglio
il concetto. Supponiamo di avere un sorgente VRML che definisce un oggetto
che ha la forma di un libro. Supponiamo che il colore associato al libro sia
rosso. Supponiamo ora che dobbiamo inserire nel nostro mondo almeno una decina
di questi libri, ma ognuno di essi con un colore diverso (blu, verde, giallo...).
La soluzione in questo
caso viene fornita dal comando PROTO. Sarebbe molto comodo il poter definire
un nuovo nodo che chiameremo Libro. Questo nodo avra' un solo campo che ne
specifichera' il colore. L'utilizzo del nodo sara' come quello di un nodo
qualunque:
Come si vede si compatta
di molto il codice VRML (replicare il sorgente e modificare la sola componente
di colore sarebbe inimmaginabile appena dobbiamo inserire due o tre di questi
libri... figuriamoci se dobbiamo simulare una biblioteca!!!).
Facciamo un ultimo esempio.
Supponiamo di avere un oggetto di forma umana. Presumibilmente sara' molto
complicato, soprattutto in considerazione del fatto che lo vogliamo animare.
E supponiamo di volere realizzare una staffetta 4x100 con una decina di squadre.
Dobbiamo insomma modellizzare 40 atleti! Il vero problema non e' tanto l'aspetto
fisico che vogliamo che vari... per esempio le diverse squadre portano divise
diverse. Ok... convinti tutti
della utilita' del comando PROTO? allora possiamo passare dal lato di creazione
del nuovo nodo.
Vediamo in cosa consiste
la definizione di un prototipo. Si comincia indicando la parola chiave PROTO
seguita dal nome da associare al nuovo nodo. Vediamo dunque la sintassi
di PROTO:
Ovviamente il tipo sara'
uno dei soliti tipi visti sino ad ora: SFBool, SFVec3f, SFRotation e cosi'
via. Fate attenzione che in
questo modo non avete creato nulla sullo schermo. Abbiamo semplicemente un
nuovo nodo. Quando lo richiameremo, il relativo effetto si ripercuotera' sul
mondo VRML.
Vediamo un semplice esempio
di utilizzo con il quale concludo questa lezione (rimandando poi al secondo
esempio nella prossima).
Supponiamo di volere
realizzare un piccolo quartiere con alcune (piccole) case.
Per mantenerci focalizzati
sugli aspetti nuovi della lezione, le case verranno mantenute molto semplici;
in particolare utilizzeremo un modello identico a quello realizzato in una
precedente lezione: vale a dire una box con una piramide sopra. Non volendo
avere case tutte dello stesso colore, non possiamo fare ricorso al comando
USE.
I campi che mi interessa
specificare sono i seguenti:
In questo modo terremo
il tutto molto semplice.
Vediamo dunque il file
VRML relativo.
Un paio di osservazioni
conclusive.
Si noti bene che posso
utilizzare un prototype solo dove potrebbe esserre impiegato il primo nodo
della definizione. In pratica il primo nodo contenuto nella definizione definisce
il tipo del prototype.
Nel nostro caso, House
ha come primo nodo un nodo Transform e quindi puo' essere liberamente utilizzato
in qualsiasi parte un nodo Transform potrebbe essere impiegato. Se il PROTO
definisce un nodo di tipo Material, potra' essere impiegato solo all'interno
del nodo Appearance.
Per ulteriori informazioni,
soprattutto sulla possibilita' di innestare PROTO all'interno di altri PROTO,
vi rimando alle specifiche.
Nella lezione successiva
viene analizzato un esempio un po' piu' complesso. Sicuramente il piu' complesso
visto sino a questo punto. L'attenzione sara' posta soprattutto sugli aspetti
di dinamicita' e animazione della scena.
Dopo avere affrontato
l'esempio vedremo di dare una rapida occhiata a EXTERNPROTO e quindi passeremo
all'interazione tra JAVA e VRML (dove ci sara' da divertirsi).
Ma c'e' una sostanziale differenza tra i due casi. Con il comando USE il nodo
(o gruppi di nodi) identificato viene riutilizzato tale e quale nel punto
in cui viene invocato. Con il comando PROTO posso invece definire un nuovo
nodo il quale avra' dei campi il cui valore sara' settato dall'utente...
Come fare con il comando USE? Con USE semplicemente si replica il nodo identificato
dal nome che segue USE. E quindi si replica anche il relativo colore!
Transform {
translation -10 0 0
children [
Libro {
colore 0 0 1 # qui ci metto un libro blu
}
]
}
Transform {
translation 10 0 0
children [
Libro {
colore 0 1 0 # qui ci metto un libro verde
}
]
}
Il fatto e' che ogni concorrente deve muoversi in modo diverso dagli altri.
Non tanto nella tecnica di corsa, quella possiamo assumerla uguale per tutti...
ma ci sara' qualcuno che corre piu' in fretta di un altro. La soluzione sara'
quella di creare dei nuovi campi che contengano le informazioni opportune
per far correre il concorrente in modo piu' o meno veloce rispetto agli altri.
L'esempio e' abbastanza complesso. Ne vedremo una semplificazione nella lezione
successiva, che sara' tutta dedicata all'esempio stesso.
Successivamente si indica la prototype declaration, la quale contiene i singoli
campi che fanno parte del nodo. Questi campi potranno essere field, eventIn,
eventOut o exposedField.
Segue la prototype definition che contiene un insieme di nodi che definiscono
che cosa il nuovo nodo fara'. All'interno di questa definizione serve un meccanismo
per riferirsi ai valori passati nei parametri. Questo viene realizzato tramite
la parola chiave IS.
Per esempio:
...
translation IS spostamento
...
dove 'spostamento' e' il nome del campo passato.
PROTO nome [
eventIn tipo nome
eventOut tipo nome
exposedField tipo nome valore di default
field tipo nome valore di default
] {
insieme di nodi
eventuali ROUTE
}
I nomi dei campi devono essere unici all'interno dello stesso PROTO.
#VRML V2.0 utf8
#semplice esempio di utilizzo del comando PROTO
PROTO House [
exposedField SFColor color_house 1 1 1
exposedField SFColo color_roof 1 0 0
] {
Transform {
translation 0 0 3
children [
Shape {
appearance Appearance {
material Material {
diffuseColor IS color_house
}
}
geometry Box { size 6 6 6 }
}
Transform {
translation 0 0 3
children [
Shape {
appearance Appearance {
material Material {
diffuseColor IS color_roof
}
}
geometry IndexedFaceSet {
coord Coordinate {
point [ -3 0 3, 3 0 3, 3 0 -3, -3 0 -3, 0 3 0 ]
}
coordIndex [
0,3,2,1,-1,
0,1,4,-1,
1,2,4,-1,
2,3,4,-1,
3,0,4,-1,
]
}
} # end of Shape
]
} # end of roof
} # end of shape
]
} # end of house
} # END OF PROTO
# adesso posso liberamente utilizzare il nuovo nodo.
#definisco un piano su cui mettere le varie case.
Shape {
appearance Appearance {
material Material { diffuseColor .5 .5 .5 }
}
geometry Box { size 100 .01 100 }
# avrei tranquillamente potuto usare un IndexedFaceSet
# per creare un piano.
}
#prima casa!
Transform {
translation -40 0 -40
children [
House {
color_house 0 1 0
color_roof 1 0 0
}
]
}
#seconda casa
Transform {
translation - 30 0 0
scale 1 1 2 # per ottenere case di dimensioni diverse
children [
House {
color_house 1 1 1
color_roof .5 0 0
}
]
}
Transform {
translation -40 0 -30
scale 1 2 2
children [
House {
color_house .5 .5 0
color_roof .8 .8 .8
}
]
}
Transform {
translation 0 0 -30
scale 3 0 0
children [
House {
color_house 1 0 0
color_roof .4 .4 .4
}
]
}
Transform {
translation 40 0 -30
scale 1.5 5 2
children [
House {
color_house 1 1 1
color_roof .8 0 0
}
]
}
Transform {
translation 30 0 0
scale 1 2 3
children [
House {
color_house 0 .5 0
color_roof .5 0 .1
}
]
}
#ultima casa!
Transform {
translation 0 0 -30
scale 3 .6 1
children [
House {
color_house .6 0 0
color_roof .4 .4 .4
}
]
}
Paesino