Utföra komplexa 3D-omformningar

Flash Player 10 och senare, Adobe AIR 1.5 och senare

Med klassen Matrix3D kan du omforma 3D-punkter inom en koordinatrymd eller mappa 3D-punkter från en koordinatrymd till en annan.

Du behöver inte förstå matrismatematiken för att kunna använda klassen Matrix3D. De flesta vanliga omformningsåtgärder kan hanteras med klassens metoder. Du behöver inte bekymra dig om att uttryckligen ställa in eller beräkna värdena för respektive element i matrisen.

När du har ställt in z -egenskapen för ett visningsobjekt på ett numeriskt värde, kan du hämta objektets omformningsmatris med hjälp av Matrix3D-egenskapen för visningsobjektets Transform-objekt:

var leafMatrix:Matrix3D = this.transform.matrix3D;

Du kan använda metoderna för Matrix3D-objektet om du vill utföra översättning, rotation, skalning och perspektivprojektion på visningsobjektet.

Använd klassen Vector3D med dess x -, y - och z -egenskaper när du hanterar 3D-punkter. Den kan också representera en spatial vektor inom fysiken, som har en riktning och storlek. Med metoderna för klassen Vector3D kan du utföra vanliga beräkningar med spatiala vektorer, till exempel addition, punktprodukt och summaproduktberäkningar.

Obs! Klassen Vector3D är inte besläktad med ActionScript-klassen Vector. Klassen Vector3D innehåller egenskaper och metoder för att definiera och manipulera 3D-punkter, medan klassen Vector stöder arrayer med typbestämda objekt.

Skapa Matrix3D-objekt

Du kan skapa och hämta Matrix3D -objekt på tre sätt:

  • Använda Matrix3D() -konstruktormetoden för att instansiera en ny matris. Matrix3D() -konstruktorn använder ett Vector -objekt som innehåller 16 numeriska värden och placerar vart och ett av värdena i en cell i matrisen. Till exempel:

    var rotateMatrix:Matrix3D = new Matrix3D(1,0,0,1, 0,1,0,1, 0,0,1,1, 0,0,0,1);
  • Ange värdet för z -egenskapen för ett visningsobjekt. Hämta sedan omformningsmatrisen från det objektets transform.matrix3D -egenskap.

  • Hämta Matrix3D-objektet som styr visningen av 3D-objekten på scenen genom att anropa metoden perspectiveProjection.toMatrix3D() för rotvisningsobjektet.

Använda flera 3D-omformningar

Du kan tillämpa flera 3D-omformningar samtidigt med hjälp av ett Matrix3D-objekt. Om du till exempel vill rotera, skala och sedan flytta en kub, tillämpar du tre separata omformningar på varje punkt i kuben. Det är emellertid mer effektivt att beräkna flera omformningar i ett Matrix3D-objekt i förväg och sedan utföra en matrisomformning på varje punkt.

Obs! Ordningen som matrisomformningarna utförs i har betydelse. Matrisberäkningar är inte kommutativa. Om du till exempel tillämpar en rotation följt av en översättning får du ett annat resultat än om du tillämpar samma översättning följt av samma rotation.

I följande exempel visas två olika sätt att utföra flera 3D-omformningar.

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; 
        } 
    } 
}

I metoden doTransforms() använder det första kodblocket DisplayObject-egenskaperna för att ändra rotation, skalning och position för en rektangulär form. Det andra kodblocket använder metoderna för klassen Matrix3D för att utföra samma omformningar.

Den största fördelen med att använda Matrix3D -metoderna är att alla beräkningar utförs först i matrisen. Sedan tillämpas de på visningsobjektet endast en gång, när egenskapen transform.matrix3D har angetts. Om du ställer in DisplayObject-egenskaperna blir källkoden lite enklare att läsa. Varje gång som en rotations- eller skalningsegenskap ställs in, sker emellertid fler beräkningar som ändrar flera av visningsobjektets egenskaper.

Om koden ska tillämpa samma komplexa omformningar på visningsobjekten fler än en gång, kan du spara Matrix3D-objektet som en variabel och sedan använda den om igen.

Ändra visningsordning med hjälp av Matrix3D-objekt

Så som tidigare nämnts bestämmer visningsobjektens lagerordning i visningslistan vilken ordning lagren visas i, oavsett deras relativa z-axlar. Om animeringen omformar egenskaperna för visningsobjekten till en annan ordning än den i visningslistan, kanske betraktaren ser visningsobjekten i en lagerordning som inte motsvarar z-axelns lagerordning. Ett objekt som ska visas längre bort från betraktaren kanske därför visas framför ett objekt som är närmare betraktaren.

För att vara säker på att lagerordningen för 3D-visningsobjekten motsvarar objektens relativa djup, ska du göra så här:

  1. Använd metoden getRelativeMatrix3D() för Transform-objektet för att hämta den relativa z-axeln till de underordnade 3D-visningsobjekten.

  2. Ta bort objekten från visningslistan med metoden removeChild() .

  3. Sortera visningsobjekten utifrån deras relativa z-axelvärden.

  4. Lägg tillbaka de underordnade objekten i omvänd ordning i visningslistan med metoden addChild() .

Den här ordningen säkerställer att objekten visas enligt sina relativa z-axlar.

Följande kod framtvingar rätt visning av de sex ytorna i en 3D-ask. Den ändrar ordning på askens ytor efter en rotation:

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); 
    } 
}

Programfilerna för det här exemplet finns på www.adobe.com/go/learn_programmingAS3samples_flash_se . Programfilerna finns i mappen Samples/ReorderByZ.