Als u begint te werken met structuren, wilt u waarschijnlijk gebruikmaken van de parameter uvtData van
drawTriangles()
. Met deze parameter kunt u UV-toewijzing instellen voor bitmapvullingen.
UV-toewijzing is een methode voor het geven van structuur aan objecten. De methode is gebaseerd op twee waarden: een horizontale (x) U-waarde en een verticale (y) V-waarde. De waarden zijn niet gebaseerd op pixelwaarden, maar op percentages. 0 U en 0 V is helemaal linksboven in een afbeelding en 1 U en 1 V is helemaal rechtsonder:
De locaties UV 0 en 1 op een bitmapafbeelding
U kunt vectoren van een driehoek UV-coördinaten geven om deze zelf te koppelen aan de respectieve locaties op een afbeelding:
De UV-coördinaten van een driehoekig gebied van een bitmapafbeelding
De UV-waarden blijven consistent met de punten van de driehoek:
De hoekpunten van de driehoek worden verplaatst en de bitmap wordt vervormd om te zorgen dat de UV-waarden voor een individueel punt gelijk blijven
Aangezien 3D-transformaties in ActionScript worden toegepast op de driehoek die is gekoppeld aan de bitmap, wordt de bitmapafbeelding op basis van de UV-waarden toegepast op de driehoek. Dus in plaats van matrixberekeningen te gebruiken, kunt u de UV-waarden instellen of aanpassen om een driedimensionaal effect te creëren.
De methode
Graphics.drawTriangles()
accepteert ook optionele informatie voor driedimensionale transformaties: de T-waarde. De T-waarde in uvtData vertegenwoordigt het 3D-perspectief, of specifieker gezegd, de schaalfactor van het toegewezen hoekpunt (vertex). UVT-toewijzing voegt perspectiefcorrectie toe aan UV-toewijzing. Als een object bijvoorbeeld in de 3D-ruimte op afstand van het gezichtspunt is geplaatst zodat het 50% van de “oorspronkelijke” grootte lijkt te zijn, is de T-waarde van dat object 0.5. Aangezien driehoeken worden getekend om objecten in de 3D-ruimte te vertegenwoordigen, bepalen de locaties langs de z-as hun T-waarden. De T-waarde wordt bepaald met de volgende vergelijking:
T = focalLength/(focalLength + z);
In de vergelijking staat focalLength voor een brandpuntsafstand of een berekende locatie op het scherm die bepaalt hoeveel perspectief wordt toegevoegd aan de weergave.
De focuslengte en z-waarde
-
A.
-
gezichtspunt
-
B.
-
scherm
-
C.
-
3D-object
-
D.
-
waarde van focalLength
-
E.
-
z-waarde
Met behulp van de waarde van T worden basisvormen geschaald zodat ze verder weg lijken. Het is in het algemeen de waarde die wordt gebruikt om 3D-punten om te zetten in 2D-punten. Bij UVT-gegevens wordt de T-waarde ook gebruikt om een bitmap te schalen tussen de punten in een driehoek met perspectief.
Wanneer u UVT-waarden definieert, volgt de T-waarde direct de UV-waarden die zijn gedefinieerd voor een hoekpunt. Door de toevoeging van T komen alle drie waarden in de parameter
uvtData
(U, V en T) overeen met alle twee waarden in de parameter
vertices
(x en y). Met alleen UV-waarden geldt uvtData.length == vertices.length. Met de opname van een T-waarde geldt uvtData.length = 1,5*vertices.length.
In het volgende voorbeeld wordt een vlak getoond dat in de 3D-ruimte wordt geroteerd met behulp van UVT-gegevens. Het voorbeeld gebruikt de afbeelding ocean.jpg en de “helperklasse” ImageLoader, die de afbeelding ocean.jpg laadt zodat deze kan worden toegewezen aan het BitmapData-object.
Hier is de bron van de klasse ImageLoader. Sla deze code op in een bestand met de naam ImageLoader.as:
package {
import flash.display.*
import flash.events.*;
import flash.net.URLRequest;
public class ImageLoader extends Sprite {
public var url:String;
public var bitmap:Bitmap;
public function ImageLoader(loc:String = null) {
if (loc != null){
url = loc;
loadImage();
}
}
public function loadImage():void{
if (url != null){
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
var req:URLRequest = new URLRequest(url);
loader.load(req);
}
}
private function onComplete(event:Event):void {
var loader:Loader = Loader(event.target.loader);
var info:LoaderInfo = LoaderInfo(loader.contentLoaderInfo);
this.bitmap = info.content as Bitmap;
this.dispatchEvent(new Event(Event.COMPLETE));
}
private function onIoError(event:IOErrorEvent):void {
trace("onIoError: " + event);
}
}
}
En hier is het ActionScript waarin driehoeken, UV-toewijzing en T-waarden worden gebruikt om de afbeelding kleiner te laten worden in de richting van een verdwijnpunt en te laten roteren. Sla deze code op in een bestand met de naam Spinning3dOcean.as:
package {
import flash.display.*
import flash.events.*;
import flash.utils.getTimer;
public class Spinning3dOcean extends Sprite {
// plane vertex coordinates (and t values)
var x1:Number = -100, y1:Number = -100, z1:Number = 0, t1:Number = 0;
var x2:Number = 100, y2:Number = -100, z2:Number = 0, t2:Number = 0;
var x3:Number = 100, y3:Number = 100, z3:Number = 0, t3:Number = 0;
var x4:Number = -100, y4:Number = 100, z4:Number = 0, t4:Number = 0;
var focalLength:Number = 200;
// 2 triangles for 1 plane, indices will always be the same
var indices:Vector.<int>;
var container:Sprite;
var bitmapData:BitmapData; // texture
var imageLoader:ImageLoader;
public function Spinning3dOcean():void {
indices = new Vector.<int>();
indices.push(0,1,3, 1,2,3);
container = new Sprite(); // container to draw triangles in
container.x = 200;
container.y = 200;
addChild(container);
imageLoader = new ImageLoader("ocean.jpg");
imageLoader.addEventListener(Event.COMPLETE, onImageLoaded);
}
function onImageLoaded(event:Event):void {
bitmapData = imageLoader.bitmap.bitmapData;
// animate every frame
addEventListener(Event.ENTER_FRAME, rotatePlane);
}
function rotatePlane(event:Event):void {
// rotate vertices over time
var ticker = getTimer()/400;
z2 = z3 = -(z1 = z4 = 100*Math.sin(ticker));
x2 = x3 = -(x1 = x4 = 100*Math.cos(ticker));
// calculate t values
t1 = focalLength/(focalLength + z1);
t2 = focalLength/(focalLength + z2);
t3 = focalLength/(focalLength + z3);
t4 = focalLength/(focalLength + z4);
// determine triangle vertices based on t values
var vertices:Vector.<Number> = new Vector.<Number>();
vertices.push(x1*t1,y1*t1, x2*t2,y2*t2, x3*t3,y3*t3, x4*t4,y4*t4);
// set T values allowing perspective to change
// as each vertex moves around in z space
var uvtData:Vector.<Number> = new Vector.<Number>();
uvtData.push(0,0,t1, 1,0,t2, 1,1,t3, 0,1,t4);
// draw
container.graphics.clear();
container.graphics.beginBitmapFill(bitmapData);
container.graphics.drawTriangles(vertices, indices, uvtData);
}
}
}
U kunt dit voorbeeld testen door deze twee klassenbestanden op te slaan in dezelfde map als de afbeelding "ocean.jpg". U kunt zien hoe de oorspronkelijke bitmap wordt getransformeerd zodat het lijkt of de bitmap verdwijnt in de verte en roteert in de 3D-ruimte.