|
||||||
ROBOTICA
video
immagini
papers
progettati
costruiti
toolbox
vrml
simulatori
Interpolatori e prima semplice animazione |
Chiariamo ora l’ultimo concetto
che ci serve per realizzare una animazione. Abbiamo a disposizione un comando
(ROUTE) per passare il contenuto di un nodo ad un altro nodo e abbiamo un nodo
TimeSensor che scandisce il tempo. Quello che ci servirebbe a questo punto sarebbe
un nodo che presenti valori diversi a seconda del trascorrere del tempo, in
modo tale che questi valori possano poi essere spediti al nodo da animare. Nel
nostro caso la sequenza di valori va spedita al campo translation del nodo Transform
che contiene il cubo che vogliamo animare. Il meccanismo che ancora ci manca
viene reso disponibile da vrml con gli interpolatori.
Un nodo interpolatore
riceve in ingresso un parametro dipendente dal tempo e manda in uscita un
valore dipendente a sua volta dal tempo.
Vediamo un semplice esempio
per chiarirci le idee.
Affinchè l’interpolatore
possa funzionare occorre aver definito un nodo TimeSensor.
Inoltre dobbiamo collegare
il trascorrere del tempo con l’interpolatore in questione. Dobbiamo quindi
usare un comando ROUTE.
ROUTE tempo.fraction_changed
TO posizione.set_fraction
Da dove sbucano i campi
fraction_changed e set_fraction ? Basta fare riferimento alle specifiche dei
nodi e si vedrà che questi campi sono propri di questi nodi e che hanno un
tipo di interfaccia appropriato per l’operazione effettuata.
Analizziamo in dettaglio
quello che abbiamo appena scritto. Abbiamo definito un nodo interpolatore,
il cui funzionamento sarà spiegato tra breve. Inoltre abbiamo creato un orologio
che segna il trascorrere del tempo. Abbiamo infine collegato il campo fraction_changed
del nodo ‘tempo’ al campo set_fraction del nodo ‘posizione’. Non abbiamo dichiarato
esplicitamente questi due campi nei nodi, ma essi esistono dal momento in
cui il nodo viene creato.
Fraction_changed contiene
la frazione di tempo trascorsa rispetto ad un ciclo (in questo caso di 10
secondi). Quindi il campo fraction_changed conterrà un valore compreso tra
0 e 1, con 0 rappresentante l’inizio del ciclo e 1 la fine.
Questo campo emesso dal
nodo ‘tempo’, va a settare un campo all’interno del nodo interpolatore. Questo
campo, che dipende appunto dal tempo, viene usato per calcolare la nuova posizione.
Questa viene calcolata interpolando tra i due valori contenuti nel campo keyValue
corrispondenti ai due estremi dell’intervallo di frazioni nel campo key in
cui fraction_changed va a cadere.
Per cui si vede che al
tempo iniziale, dove fraction_changed è uguale a 0, l’interpolatore emetterà
la posizione 1 0 0. Per una frazione di tempo pari a 0.5 (e quindi dopo 5
secondi) la posizione sarà 2 0 0. Per frazioni intermedie l’interpolatore
calcolerà posizioni intermedie tra 1 0 0 e 2 0 0. Settando di volta in volta
il campo translation del nodo Transform con il valore calcolato dall’interpolatore
abbiamo l’animazione.
Dunque manca un ultimissimo
tocco. Legare l’uscita del nodo interpolatore con il campo translation. Basta
aggiungere :
ROUTE posizione.value_changed
TO cubo.set_translation
Et voilà. L’animazione
è completata.
Riportiamo qui il sorgente
completo.
E con questo la nostra
prima animazione è completata. Prima di terminare questo paragrafo osserviamo
però (e l’ideale sarebbe appunto provare sulla macchina l’esempio) che il
cubo si sposta dalla posizione -1 0 0 a 1 0 0 ; quando però deve ricominciare
la sequenza si ha che il cubo riparte da -1 0 0, creando un fastidioso salto.
L’ideale sarebbe far rimbalzare il cubo da sinistra a destra e viceversa.
Per fare questo possiamo
modificare leggermente l’interpolatore nel modo seguente.
In questo modo il cubo
si sposta da sinistra a destra e viceversa in 5 secondi e poi riprende. Se
vogliamo mantenere la velocità dell’esempio precedente basta impostare cycleinterval
a 10 secondi.
Si noti come l’ultimo
valore del campo keyValue va a matchare il primo. Questo è indispensabile
per avere continuità nel moto, in quanto 1 e 0 sono in pratica lo stesso istante.
Da ultimo se riconsideriamo
la prima versione, si noti che non era necessario introdurre 3 valori nel
campo key e keyValue. Infatti la posizione intermedia 0 0 0 per una frazione
pari a 0.5 sarebbe stata calcolata automaticamente dall’interpolatore stesso.
Se viceversa voglio impostare
diverse velocità o cammini più complessi allora devo aumentare i punti su
cui basare l’interpolazione.
Con questa spiegazione
possiamo considerare quasi conclusa la parte di animazione con mezzi forniti
direttamente da vrml. Nella prossima sezione vedremo un altro esempio e altri
tipi di interpolatori.
Procederemo poi a considerare
la possibilità di creare animazioni e comportamenti più complessi usando scripts
java. Solo pochi cenni saranno rivolti all’uso di scripts CGI e all’interfacciamento
con java.
Già con i mezzi a disposizione
in questo momento si possono creare mondi decisamente interessanti. Ovviamente
le animazioni saranno molto più complesse di quella rappresentata qui come
esempio, ma a livello concettuale non ci sarà niente di nuovo ; semplicemente
si avranno percorsi più articolati e complicati.
DEF posizione PositionInterpolator {
key [ 0 .5 1 ]
keyValue [ 1 0 0, 2 0 0, 5 0 0 ]
}
DEF tempo TimeSensor {
cycleInterval 10
enabled TRUE
loop TRUE
startTime 1
}
#VRML V2.0 utf8
#semplice animazione. Versione 1
DEF cubo Transform {
translation -1 0 0
children [
Shape {
appearance Appearance {
material Material { diffuseColor 1 0 0 }
}
geometry Box { size 1 1 1 }
}
]
}
DEF tempo TimeSensor {
cycleInterval 5
enabled TRUE
loop TRUE
startTime 1
}
DEF posizione PositionInterpolator {
key [0 .5 1]
keyValue [-1 0 0, 0 0 0, 1 0 0]
}
ROUTE tempo.fraction_changed TO posizione.set_fraction
ROUTE posizione.value_changed TO cubo.set_translation
cubo animato
DEF posizione PositionInterpolator {
key [0 .5 1]
keyValue [-1 0 0, 1 0 0, -1 0 0]
}