Trasformazioni 3D complesse

Flash Player 10 e versioni successive, Adobe AIR 1.5 e versioni successive

La classe Matrix3D consente di trasformare i punti 3D all'interno di uno spazio di coordinate o di mapparli da uno spazio coordinate a un altro.

Non è richiesto che conosciate la matematica delle matrici per utilizzare la classe Matrix3D. La maggior parte delle operazioni di trasformazione più comuni può essere gestita mediante i metodi di questa classe. Pertanto, non dovete preoccuparvi di impostare esplicitamente o calcolare i valori di ciascun elemento nella matrice.

Una volta impostata la proprietà z di un oggetto di visualizzazione su un valore numerico, potete recuperare la matrice di trasformazione dell'oggetto mediante la proprietà Matrix3D dell'oggetto Transform dell'oggetto di visualizzazione:

var leafMatrix:Matrix3D = this.transform.matrix3D;

Potete utilizzare i metodi dell'oggetto Matrix3D per applicare conversioni, rotazioni, modifiche in scala e proiezioni prospettiche all'oggetto di visualizzazione.

Utilizzate la classe Vector3D con le relative proprietà x, y e z per gestire i punti 3D. Può anche rappresentare un vettore spaziale in fisica, il quale ha una direzione e una magnitudo. I metodi della classe Vector3D vi consentono di eseguire calcoli comuni con i vettori spaziali, quali l'addizione, il prodotto scalare e il prodotto vettoriale.

Nota: la classe Vector3D non è correlata alla classe Vector di ActionScript. La classe Vector3D contiene proprietà e metodi per definire e modificare i punti 3D, mentre la classe Vector supporta gli array degli oggetti con tipo.

Creazione di oggetti Matrix3D

Sono disponibili tre metodi principali per creare o recuperare gli oggetti Matrix3D:

  • Utilizzate il metodo della funzione di costruzione Matrix3D() per creare l'istanza di una nuova matrice. La funzione di costruzione Matrix3D() colloca ognuno dei 16 valori numerici di un oggetto Vector in una cella della matrice. Ad esempio:

    var rotateMatrix:Matrix3D = new Matrix3D(1,0,0,1, 0,1,0,1, 0,0,1,1, 0,0,0,1);
  • Impostate il valore della proprietà z di un oggetto di visualizzazione. Quindi, recuperate la matrice di trasformazione dalla proprietà transform.matrix3D di tale oggetto.

  • Recuperate l'oggetto Matrix3D che controlla la visualizzazione degli oggetti 3D sullo stage, eseguendo la chiamata al metodo perspectiveProjection.toMatrix3D() sull'oggetto di visualizzazione principale.

Applicazione di trasformazioni 3D multiple

Potete applicare numerose trasformazioni 3D contemporaneamente mediante un oggetto Matrix3D. Ad esempio, se desiderate ruotare, modificare in scala e successivamente spostare un cubo, potete applicare tre trasformazioni separate a ogni punto del cubo. Tuttavia, è molto più efficiente precalcolare più trasformazioni in un unico oggetto Matrix3D e successivamente eseguire una trasformazione di matrice su ogni punto.

Nota: l'ordine con cui vengono applicate le trasformazioni di matrice è importante. I calcoli di matrice non sono commutativi. Ad esempio, se applicate una rotazione seguita da una conversione ottenete un risultato diverso dall'applicare prima la stessa conversione seguita dalla stessa rotazione.

L'esempio seguente mostra due modi per effettuare trasformazioni 3D multiple.

package { 
    import flash.display.Sprite;     
    import flash.display.Shape; 
    import flash.display.Graphics; 
    import flash.geom.*; 
 
public class Matrix3DTransformsExample extends Sprite 
    { 
        private var rect1:Shape; 
        private var rect2:Shape; 
         
public function Matrix3DTransformsExample():void 
        { 
            var pp:PerspectiveProjection = this.transform.perspectiveProjection; 
            pp.projectionCenter = new Point(275,200); 
            this.transform.perspectiveProjection = pp; 
             
            rect1 = new Shape(); 
            rect1.x = -70; 
            rect1.y = -40; 
            rect1.z = 0; 
            rect1.graphics.beginFill(0xFF8800); 
            rect1.graphics.drawRect(0,0,50,80); 
            rect1.graphics.endFill(); 
            addChild(rect1); 
 
            rect2 = new Shape(); 
            rect2.x = 20; 
            rect2.y = -40; 
            rect2.z = 0; 
            rect2.graphics.beginFill(0xFF0088); 
            rect2.graphics.drawRect(0,0,50,80); 
            rect2.graphics.endFill(); 
            addChild(rect2); 
             
            doTransforms(); 
        } 
 
        private function doTransforms():void 
        { 
            rect1.rotationX = 15; 
            rect1.scaleX = 1.2; 
            rect1.x += 100; 
            rect1.y += 50; 
            rect1.rotationZ = 10; 
 
            var matrix:Matrix3D = rect2.transform.matrix3D; 
            matrix.appendRotation(15, Vector3D.X_AXIS); 
            matrix.appendScale(1.2, 1, 1); 
            matrix.appendTranslation(100, 50, 0); 
            matrix.appendRotation(10, Vector3D.Z_AXIS); 
            rect2.transform.matrix3D = matrix; 
        } 
    } 
}

Nel metodo doTransforms(), il primo blocco di codice utilizza le proprietà di DisplayObject per modificare la rotazione, la modifica in scala e la posizione della forma rettangolare. Il secondo blocco di codice utilizza i metodi della classe Matrix3D per effettuare le stesse trasformazioni.

Il vantaggio principale dell'utilizzo dei metodi di Matrix3D consiste nel fatto che tutti i calcoli vengono prima effettuati nella matrice e successivamente vengono applicati all'oggetto di visualizzazione una sola volta, quando la relativa proprietà transform.matrix3D viene impostata. Se impostate le proprietà di DisplayObject, il codice sorgente sarà più semplice da leggere. Tuttavia, ogni volta che viene impostata una rotazione o una modifica in scala, genera calcoli multipli e modifica più proprietà di un oggetto di visualizzazione.

Se prevedete che il codice utilizzato applichi le stesse trasformazioni complesse agli oggetti di visualizzazione più di una volta contemporaneamente, salvate l'oggetto Matrix3D sotto forma di variabile e riapplicatelo tutte le volte che è necessario.

Uso degli oggetti Matrix3D per riordinare la visualizzazione

Come indicato in precedenza, l'ordine dei livelli degli oggetti di visualizzazione nell'elenco di visualizzazione determina l'ordine dei livelli di visualizzazione, a prescindere dai relativi assi z. Se l'animazione trasforma le proprietà degli oggetti di visualizzazione in un ordine diverso da quello dell'elenco di visualizzazione, chi guarda potrebbe visualizzare un ordine dei livelli degli oggetti di visualizzazione che non corrisponde all'ordine dei livelli degli assi z. Pertanto, un oggetto che dovrebbe apparire più lontano da chi guarda potrebbe essere visualizzato in primo piano rispetto a un oggetto che è più vicino.

Per garantire che i livelli degli oggetti di visualizzazione 3D corrispondano alle profondità relative degli oggetti, utilizzate un approccio simile al seguente:

  1. utilizzate il metodo getRelativeMatrix3D() dell'oggetto Transform per ottenere gli assi z relativi degli oggetti di visualizzazione 3D secondari;

  2. utilizzate il metodo removeChild() per rimuovere gli oggetti dall'elenco di visualizzazione;

  3. ordinate gli oggetti di visualizzazione in base ai valori dei relativi assi z;

  4. utilizzate il metodo addChild() per aggiungere nuovamente gli elementi secondari all'elenco di visualizzazione, ma in ordine inverso.

Questo riordinamento garantisce che gli oggetti vengano visualizzati conformemente ai relativi assi z.

Il codice seguente applica la visualizzazione corretta delle sei facce di una scatola 3D. Riordina le facce della scatola dopo che a essa sono state applicate delle rotazioni:

public var faces:Array; . . . 
 
public function ReorderChildren() 
{     
    for(var ind:uint = 0; ind < 6; ind++) 
    { 
        faces[ind].z = faces[ind].child.transform.getRelativeMatrix3D(root).position.z; 
        this.removeChild(faces[ind].child); 
    } 
    faces.sortOn("z", Array.NUMERIC | Array.DESCENDING); 
    for (ind = 0; ind < 6; ind++) 
    { 
        this.addChild(faces[ind].child); 
    } 
}

Per ottenere i file dell'applicazione per questo esempio, visitate la pagina www.adobe.com/go/learn_programmingAS3samples_flash_it. I file dell'applicazione si trovano nella cartella Samples/ReorderByZ.