3B modeller, üçgenlerin bir alanda toplanmasıyla temsil edildiği için ActionScript'te
Graphics.drawTriangles()
yöntemini kullanarak bitmap dönüşümleri yapabilirsiniz. (Ancak, Flash Player ve AIR uygulaması derinlik arabelleğini desteklemez, bu nedenle görüntüleme nesneleri doğası gereği yassı veya 2B olmaya devam eder. Bu,
Flash Player ve AIR çalışma zamanında 3B görüntüleme nesnelerini anlama
bölümünde bu açıklanmaktadır.)
Graphics.drawTriangles()
yöntemi, bir üçgen yolu çizmek için koordinatlar kümesini aldığından,
Graphics.drawPath()
yöntemine benzer.
Graphics.drawPath()
öğesini kullanmaya alışmak için, bkz.
Yol Çizme
.
Graphics.drawTriangles()
yöntemi, üçgen yolu için nokta konumlarını belirtmek üzere bir Vector.<Number> öğesi kullanır:
drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = "none"):void
drawTriangles()
öğesinin birinci parametresi 8
vertices
parametresi), zorunlu olan tek parametredir. Bu parametre, üçgenlerinizin çizildiği koordinatları tanımlayan sayıların bir vektörüdür. Her üç koordinat kümesi (altı sayı) bir üçgen yolunu temsil eder. Her üçgen üç koordinat çifti (üç tane x/y değerleri kümesi) gerektirdiğinden,
indices
parametresi olmadan, vektör uzunluğu her zaman altının bir faktörü olmalıdır. Örneğin:
graphics.beginFill(0xFF8000);
graphics.drawTriangles(
Vector.<Number>([
10,10, 100,10, 10,100,
110,10, 110,100, 20,100]));
Bu üçgenlerin hiçbiri bir nokta paylaşmaz ancak paylaşsalardı, birden çok üçgen için
vertices
vektöründe değerleri yeniden kullanmak üzere ikinci
drawTriangles()
parametresi olan
indices
kullanılabilirdi.
indices
parametresini kullanırken,
indices
değerlerinin doğrudan
vertices
dizi öğeleriyle ilgili olan dizinler değil, nokta dizinleri olmasına dikkat edin. Başka bir deyişle,
indices
tarafından tanımlandığı şekilde
vertices
vektöründeki bir dizin gerçekte 2'ye bölünen gerçek dizindir.
vertices
vektörünün üçüncü noktası için, söz konusu noktanın birinci sayısal değeri 4 vektör dizininde başlasa da, örneğin
indices
değeri olarak 2'yi kullanın.
Örneğin,
indices
parametresini kullanarak çapraz kenarı paylaşacak şekilde iki üçgeni birleştirin:
graphics.beginFill(0xFF8000);
graphics.drawTriangles(
Vector.<Number>([10,10, 100,10, 10,100, 100,100]),
Vector.<int>([0,1,2, 1,3,2]));
Şimdi iki üçgen kullanılarak bir kare çizilmiş olsa da,
vertices
vektöründe yalnızca dört noktanın belirtilmiş olduğuna dikkat edin.
indices
öğesi kullanılarak, iki üçgen tarafından paylaşılan iki nokta, her üçgen için yeniden kullanılır. Bu da, genel kesişme noktaları sayısını 6'dan (12 sayı) 4'e (8 sayı) düşürür:
vertices parametresi kullanılarak iki üçgenle çizilmiş bir kare
Bu teknik, çoğu noktanın birden çok üçgen tarafından paylaşıldığı daha büyük üçgen kafesleri için kullanışlıdır.
Üçgenlere tüm dolgular uygulanabilir. Dolgular, diğer şekillere olduğu gibi sonuçta elde edilen üçgene de uygulanır.
Bitmap'leri dönüştürme
Bitmap dönüştürmeleri, üç boyutlu bir nesne üzerinde perspektif veya "doku" görünümü sağlar. Özel olarak, görüntünün ufuk noktasına yaklaştıkça daralıyor gibi görünmesi için ufuk noktasına doğru bir bitmap'i deforme edebilirsiniz. Veya, üç boyutlu bir nesneye için yüzey oluşturmak üzere iki boyutlu bitmap kullanarak o üç boyutlu nesne üzerinde doku veya "sargı" görünümü sağlayabilirsiniz.
Bir ufuk noktası ve bitmap ile sarılmış üç boyutlu bir nesne kullanan iki boyutlu yüzey.
UV eşleme
Dokularla çalışmaya başladıktan sonra
drawTriangles()
öğesinin uvtData parametresinden yararlanmak istersiniz. Bu parametre, bitmap dolgular için UV eşleme ayarlamanıza olanak sağlar.
UV eşleme, nesneleri dokulaştırma yöntemidir. Bu iki değeri esas alır: U yatay (x) değeri ve V dikey (y) değeri. Bunlar piksel değerlerini değil, yüzdeleri esas alır. 0 U ve 0 V, görüntünün sol üst kısmı iken, 1 U ve 1 V de görüntünün sağ alt kısmıdır:
Bitmap görüntüde UV 0 ve 1 konumları
Üçgen vektörlerinin bir görüntüdeki ilgili konumlarla ilişkilendirilmesi için söz konusu üçgen vektörlerine UV koordinatları verilebilir:
Bitmap görüntünün üçgen alanının UV koordinatları
UV değerleri, üçgenin noktalarıyla tutarlı kalır:
Üçgenin kesişme noktaları hareket eder ve bitmap, tek bir noktanın UV değerlerini aynı tutmak için deforme olur
ActionScript 3B dönüştürmeler, bitmap'le ilişkilendirilmiş üçgene uygulanırken, bitmap görüntü, UV değerlerini esas alan üçgene uygulanır. Bu nedenle, matris hesaplamalarını kullanmak yerine, üç boyutlu efektler oluşturmak için UV değerlerini ayarlayın.
Graphics.drawTriangles()
yöntemi ayrıca üç boyutlu dönüştürmeler için isteğe bağlı bir bilgiyi de kabul eder: T değeri. uvtData öğesindeki T değeri, 3B perspektifi veya daha net olmak gerekirse, ilişkilendirilmiş tepenin ölçek faktörünü temsil eder. UVT eşleme, UV eşlemeye perspektif düzeltmesi ekler. Örneğin, bir nesne, 3B alanda "orijinal" boyutunun %50'si kadar görünecek şekilde görüş açısından uzağa konumlandırılırsa, o nesnenin T değeri 0,5 olur. 3B alanda nesneleri temsil etmek için üçgenler çizildiğinden, bunların z ekseni boyunca konumları T değerlerini belirler. T değerini belirleyen eşitlik şöyledir:
T = focalLength/(focalLength + z);
Bu eşitlikte, focalLength bir odak uzaklığını veya görünümde sağlanan perspektif miktarını dikte eden hesaplanmış "ekran" konumunu temsil eder.
Odak uzaklığı ve z değeri
-
A.
-
görüş açısı
-
B.
-
ekran
-
C.
-
3B nesne
-
D.
-
focalLength değeri
-
E.
-
z değeri
Temel şekilleri daha uzak mesafede görünecek şekilde ölçeklemek için T değeri kullanılır. Bu genellikle 3B noktaları 2B noktalara dönüştürmek için kullanılan değerdir. UVT verileri olması durumunda, perspektif içeren bir üçgen içindeki noktalar arasında bitmap'i ölçeklemek için de bu kullanılır.
UVT değerlerini tanımladığınızda, T değeri doğrudan tepe için tanımlanan UV değerlerini izler. T'nin eklenmesiyle,
uvtData
parametresindeki her üç değer (U, V ve T),
vertices
parametresindeki her iki değerle (x ve y) eşleştirilir. UV değerleri tek olduğunda, uvtData.length == vertices.length. T değeri eklendiğinde, uvtData.length = 1.5*vertices.length.
Şu örnek, UVT verileri kullanılarak 3B alanda döndürülen bir düzlemi gösterir. Bu örnek, BitmapData nesnesine atanabilmesi için ocean.jpg görüntüsünü yüklemek üzere ocean.jpg adında bir görüntüyü ve ImageLoader adında bir “yardımcı” sınıfı kullanır.
Burada ImageLoader sınıf kaynağı verilmiştir (bu kodu ImageLoader.as adındaki bir dosyaya kaydedin):
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);
}
}
}
Burada da görüntünün bir ufuk noktasına doğru daralıyor ve dönüyor gibi görünmesini sağlamak için üçgenleri, UV eşlemeyi ve T değerlerini kullanan ActionScript verilmiştir. Bu kodu Spinning3dOcean.as adındaki bir dosyaya kaydedin:
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);
}
}
}
Bu örneği test etmek için, bu iki sınıf dosyasını “ocean.jpg” adındaki bir görüntüyle aynı dizine kaydedin. Orijinal bitmap'in, 3B alanda gittikçe kayboluyor ve dönüyor gibi görünmesi için nasıl dönüştürüldüğünü görebilirsiniz.
Yüzey kaldırma
Yüzey kaldırma, geçerli görüş açısından gizlendikleri için oluşturucunun, üç boyutlu bir nesnenin hangi yüzeylerini oluşturmaması gerektiğini belirleyen işlemdir. 3B alanda, üç boyutlu nesnenin "arkasındaki" yüzey, görüş açısından gizlenir:
3B nesnenin arkası, görüş açısından gizlenir.
-
A.
-
görüş açısı
-
B.
-
3B nesne
-
C.
-
üç boyutlu nesnenin arkası
Doğası gereği tüm üçgenler, boyutu, şekli veya konumuna bakılmaksızın her zaman oluşturulur. Yüzey kaldırma, Flash Player veya AIR uygulamasının 3B nesnenizi doğru şekilde oluşturmasını sağlar. Ayrıca daire oluşturma işlemini azaltmak için bazen oluşturucu tarafından bazı üçgenlerin atlanmasını istersiniz. Alanda dönen bir küpü göz önünde bulundurun. Görüş açısı içinde olmayan kenarlar, küpün diğer tarafındaki diğer yöne baktığından, asla o küpün üç kenarından fazlasını görmezsiniz. Bu kenarlar görünmeyeceğinden, oluşturucunun bunları çizmemesi gerekir. Yüzey kaldırma olmadan, Flash Player veya AIR uygulaması hem ön hem de arka kenarları oluşturur.
Küpte ise geçerli görüş açısından görünmeyen kenarlar vardır
Bu nedenle,
Graphics.drawTriangles()
yöntemi, yüzey kaldırma değeri oluşturmak için dördüncü bir parametre içerir:
public function drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = "none"):void
culling parametresi,
TriangleCulling
numaralandırma sınıfındaki bir değerdir:
TriangleCulling.NONE
,
TriangleCulling.POSITIVE
ve
TriangleCulling.NEGATIVE
. Bu değerler, nesnenin yüzeyini tanımlayan üçgen yolunun yönüne bağlıdır. Yüzey kaldırmanın belirlenmesine yönelik ActionScript API'si, 3B şeklin tüm dışarı bakan üçgenlerinin aynı yol yönünde çizildiğini varsayar. Üçgenin bir yüzü ters döndüğünde, yol yönü de değişir. Bu noktada, üçgenin yüzeyi kaldırılabilir. (Oluşturma işleminden çıkarılır.)
Böylece,
POSITIVE
öğesinin bir
TriangleCulling
değeri, pozitif yol yönüne (saat yönüne) sahip üçgenleri kaldırır.
NEGATIVE
öğesinin
TriangleCulling
değeri, negatif (saat yönünün tersi) yol yönüne sahip üçgenleri kaldırır. Küp olması durumunda, öne bakan yüzeyler pozitif yol yönüne sahip olurken, arkaya bakan yüzeyler negatif yol yönüne sahip olur:
Yol yönünü göstermek için "sarılmamış" bir küp. "Sarılmadığında", arka taraftaki yol yönü ters çevrilir.
Yüzey kaldırmanın nasıl çalıştığını görmek için,
UV eşleme
bölümündeki önceki örnekle başlayın,
drawTriangles()
yönteminin culling parametresini
TriangleCulling.NEGATIVE
olarak ayarlayın:
container.graphics.drawTriangles(vertices, indices, uvtData, TriangleCulling.NEGATIVE);
Görüntünün "arka" tarafının nesne döndükçe oluşturulmadığını göreceksiniz.
|
|
|