Gli oggetti Camera3D
e Object3D
hanno una funzione, getPosition
, che restituisce la posizione sotto forma di vettore. Sottraendo la posizione della camera dalla posizione dell'oggetto, siamo in grado di ricavare il vettore dalla camera all'oggetto: la lunghezza di tale vettore ovviamente è la distanza tra i due.
Listato 60. Funzione per calcolare la sfocatura
function setBlur( ){
var cubePos:Vector;
var skin:MixedSkin;
var object:Object3D;
var filterList:Array;
var blur:Number;
var camPos:Vector = cam.getPosition();
for ( i = 0; i < objects.length; i++ ){
object = objects[i];
// Calcoliamo distanza e sfocatura
cubePos = object.getPosition();
distance = VectorMath.getNorm( VectorMath.sub( cubePos, camPos ));
blur = Math.abs(distance - 600)/200;
// Ricaviamo i filtri dell'oggetto
skin = MixedSkin (object.getSkin());
filterList = skin.filters;
// Impostiamo i nuovi valori di sfocatura e aggiorniamo il filtro
filterList[0].blurX = filterList[0].blurY = blur;
skin.filters = filterList;
}
}
Per prima cosa ricaviamo la posizione della camera, poi ricaviamo la posizione di ogni cubo. A questo punto calcoliamo la distanza utilizzando la funzione sub()
della classe VectorMath
: questa funzione sottrae il secondo vettore (camPos
) dal primo (cubePos
), mentre la funzione norm()
restituisce la lunghezza del vettore risultante.
A questo punto abbiamo la distanza, che utilizziamo per stabilire l'ammontare della sfocatura. Poichè non vogliamo nessuna sfocatura per l'oggetto con una distanza dalla telecamera pari a 600, sottraiamo tale valore alla distanza.
Dopo di che, rileviamo la skin (sfruttando la funzione getSkin()
) e ricaviamo i filtri ad essa applicati; possiamo a questo punto impostare i nuovi valori per il filtro e aggiornare l'oggetto applicandogli la nuova skin, contenente la sfocatura.
Nota: in Sandy 1.1 vi è un bug nella funzione getPosition
dell'oggetto Object3D, quindi è necessario aprire il file Object3D.as e modificare la funzione in questo modo:
// Da sandy.core.Object3D versione 1.2
public function getPosition( Void ):Vector {
var v:Vertex = aPoints[0];
return new Vector( v.tx - v.x, v.ty - v.y, v.tz - v.z );
}
Se invece siamo già in possesso della versione 1.2, non è necessaria alcuna correzione nei file della libreria.
Il risultato finale sarà quello illustrato di seguito. Utilizziamo le frecce direzionali per muoverci nella scena.
Utilizzo del BlurFilter per creare un effetto di profondità di campo
Per muovere la telecamera, abbiamo associato al listener onRenderEvent
la seguente funzione:
Listato 61. Funzione per muovere la telecamera
function cameraMove(){
if (Key.isDown (Key.UP)) {
cam.moveForward(20);
setBlur( );
}
if (Key.isDown (Key.DOWN)) {
cam.moveForward(-20);
setBlur( );
}
if (Key.isDown (Key.LEFT)) {
cam.pan(-3);
setBlur( );
}
if (Key.isDown (Key.RIGHT)) {
cam.pan(3);
setBlur( );
}
// Impostiamo la sfocatura iniziale
if (firstFrame){
firstFrame=false;
setBlur();
}
}
Grazie a questi comandi, quando viene premuta una freccia direzionale, il filmato agisce di conseguenza (muovendo la telecamera in avanti, indietro, a sinistra o a destra) quindi chiama la funzione setBlur
, che come abbiamo visto si occupa di calcolare la sfocatura per ogni oggetto presente sulla scena.
Nota: per impostare i valori iniziali, abbiamo richiamato la funzione setBlur
una volta sola sul primo fotogramma, utilizzando come controllo un booleano (firstFrame) impostato su true all'inizio del filmato, altrimenti non avremmo ottenuto alcuna sfocatura poichè la funzione sarebbe stata richiamata prima del caricamento della scena.
Siamo giunti così alla fine di questa analisi delle luci e filtri in Sandy. Ovviamente è possibile fare molto di più coi filtri, per cui sbizzarriamo la nostra fantasia con gli altri filtri messi a disposizione da Flash, come ad esempio il GlowFilter
, magari combinandoli tra loro per creare degli interessanti effetti speciali!
"© Petit Publications 2006" - diritti riservati