テクスチャの操作を開始した後、
drawTriangles()
の uvtData パラメーターを使用することができます。このパラメーターにより、ビットマップを塗るために UV マッピングを設定することができます。
UV マッピングは、オブジェクトのテクスチャを作成するためのメソッドです。U 水平(x)値および V 垂直(y)値という 2 つの値に依存します。ピクセル値に基づくのではなく、パーセンテージに基づきます。0 U および 0 V はイメージの左上であり、1 U および 1 V は右下です。
ビットマップイメージ上の UV 0 および 1 の位置
三角形のベクターには、イメージ上のそれぞれの場所に関連付けるために UV 座標を与えることができます。
ビットマップイメージの三角形領域の UV 座標
UV 値は、三角形のポイントとの整合性を保ちます。
三角形の頂点が移動し、ビットマップが歪められて、個別のポイントの UV 値が同じに保たれます。
ActionScript 3D 変換が、ビットマップに関連付けられている三角形に適用されると、ビットマップイメージが UV 値に基づいて三角形に適用されます。そのため、マトリックス計算を使用する代わりに、UV 値を設定または調整して 3 次元効果を作成します。
Graphics.drawTriangles()
メソッドは、3 次元変換のオプションの情報部分である T 値を受け入れることもあります。uvtData の T 値は 3D 遠近法を表します。より具体的には、関連付けられた頂点の縮尺率を表します。UVT マッピングでは、UV マッピングに遠近法補正が追加されます。例えば、オブジェクトが「原点」の 50 % のサイズで表示されるように視点から離れた 3D 空間に配置される場合、そのオブジェクトの T 値は 0.5 になります。三角形が 3D 空間のオブジェクトを表すように描画される場合、z 軸に沿ったその位置によって T 値が決定されます。T 値を決定する等式は次のとおりです。
T = focalLength/(focalLength + z);
この等式では、focalLength は、ビューに提供される遠近法の量を示す焦点の長さまたは計算された「スクリーン」位置を表します。
焦点の長さと z 値
-
A.
-
視点
-
B.
-
スクリーン
-
C.
-
3D オブジェクト
-
D.
-
focalLength 値
-
E.
-
z 値
T の値を使用して、基本的なシェイプを拡大/縮小し、遠くにあるように見せます。通常これは、3D ポイントを 2D ポイントに変換するために使用する値です。UVT データの場合は、遠近法で三角形の内部の頂点の間のビットマップを拡大/縮小するためにも使用されます。
UVT 値を定義する場合、T 値は頂点に対して定義されている UV 値に直接従います。T を含める場合、
uvtData
パラメーターの 3 つの値(U、V および T)がすべて、
vertices
パラメーターの 2 つの値(x および y)に一致します。UV 値単体では、uvtData.length == vertices.length となります。T 値を含めると、uvtData.length = 1.5*vertices.length となります。
次の例では、UVT データを使用して 3D 空間で回転された平面を表示します。この例では、ocean.jpg というイメージおよび「ヘルパー」クラス ImageLoader を使用して ocean.jpg イメージがロードされるので、BitmapData オブジェクトに割り当てることができます。
次に、ImageLoader クラスソースを示します(このコードは 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);
}
}
}
また、トライアングル、UV マッピングおよび T 値を使用して、消失点に向かって縮小し、回転するように見えるイメージを作成する ActionScript を次に示します。このコードを、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);
}
}
}
この例をテストするには、この 2 つのクラスファイルを「ocean.jpg」という名前のイメージと同じディレクトリに保存します。元のビットマップがどのように変換されて、3D 空間内で遠くに消失し、回転するように見えるかを参照することができます。