我们首先熟悉一个函数的使用drawTriangles,drawTriangles字面理解,就是画三角形,当然adobe不会因为你需要画三角形才给你提供这个方法吧,其真正的作用是通过快速批量的画三角形来实现位图的扭曲。我们所有的图形都可以用三角片来表示,不管是平面和三维图形,通过三角片,可以模拟出任何图形,如下图:
drawTriangles是我们开发全景浏览器的基础,drawTriangles的定义如下:
public function drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = "none"):void
-
vertices:Vector.<Number>
由数字构成的矢量,其中的每一对数字将被视为一个坐标位置(一个 x, y 对)。vertices
参数是必需的。
-
indices:Vector.<int>
(default =null
)
一个由整数或索引构成的矢量,其中每三个索引定义一个三角形。如果 indexes
参数为 null,则每三个顶点(vertices
矢量中的 6 对 x,y)定义一个三角形。否则,每个索引将引用一个顶点,即 vertices
矢量中的一对数字。例如,indexes[1]
引用 (vertices[2]
, vertices[3]
)。indexes
参数是可选的,但 indexes 通常会减少提交的数据量和计算的数据量。
由用于应用纹理映射的标准坐标构成的矢量。每个坐标引用用于填充的位图上的一个点。每个顶点必须具有一个 UV 或一个 UVT 坐标。对于 UV 坐标,(0,0) 是位图的左上角,(1,1) 是位图的右下角。
如果此矢量的长度是 vertices
矢量长度的两倍,则使用标准坐标而不进行透视校正。
如果此矢量的长度是 vertices
矢量长度的三倍,则将第三个坐标解释为“t”(即在视角空间中从视点到纹理的距离)。这有助于呈现引擎在三维中映射纹理时正确应用透视。
如果 uvtData
参数为 null,则将应用普通填充规则(和任何填充类型)。
-
culling:String
(default = "none
")
指定是否呈现面向指定方向的三角形。此参数可防止呈现在当前视图中看不见的三角形。此参数可设置为由 TriangleCulling 类定义的任何值。
1. vertices的使用
我们看看drawTriangles如何使用,看以下代码:
public function MiPanoTest()
{
var ver:Vector.<Number>=new Vector.<Number>();
ver.push(200,0);
ver.push(0,200);//记录坐标x,y坐标点
ver.push(400,200);
#效果1 this.graphics.beginFill(0x00ccff);
#效果2 this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData)
this.graphics.drawTriangles(ver);
this.graphics.endFill();
}
其显示效果如下:
以上只是drawTriangles的小试牛刀,我们看看如何将图片放入三角片中,上面的案例,我们只指定了三个顶点,所以图形会以默认方式呈现,下面我们将顶点的数量增加到9个,切每个点的距离是50,且平均排列,代码如下:
public class MiPanoTest extends Sprite
{
[Embed(source="assets/img.jpg")]
public var texture:Class;
public function MiPanoTest()
{
var row:int=3;
var cell:int=3;
var step:int=50;
var vertexs:Vector.<Number>=new Vector.<Number>();
//定义了一个50区间的9格方格
for(var i:int=0;i<row;i++){
for(var j:int=0;j<cell;j++){
vertexs.push(i*step,j*step);
}
}
//下一步,我们计算三角片的组成
this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData)
this.graphics.drawTriangles(vertexs);
this.graphics.endFill();
}
}
我们看到的结果是一片空白,什么都没有绘制,是什么原因呢?
2. indices的使用
原因是在前面的案例,我们只有三个顶点,所以drawTriangles通过三个顶点就可以构件一个面,而本案例有9个顶点,系统根本不知道那些点能组合成三角片,所以会出现一个三角片都没有,无法绘制出图形,那么这个就是第二个参数indices的,告诉系统如何组织三角片,我们上面添加了9个顶点,系统会按照两个一组,进行编号,然后把这些顶点划分三角片,如下图所示:
我们可以知道indices是记录顶点的索引位置那么,组合的三角形可以定义如下:
(0,1,3)
(1,3,4)
(1,2,4)
(2,4,5)
(3,4,6)
(4,6,7)
(4,5,7)
(5,7,8)
注意其排列循序,组成一个正方形网格的三角片0,1,3和1,3,4,结果上面的划分,我们定义代码如下:
public class MiPanoTest extends Sprite
{
[Embed(source="assets/img.jpg")]
public var texture:Class;
public function MiPanoTest()
{
var row:int=3;
var cell:int=3;
var step:int=100;
var vertexs:Vector.<Number>=new Vector.<Number>();
var indices:Vector.<int>=new Vector.<int>();
//定义了一个50区间的9格方格
for(var i:int=0;i<row;i++){
for(var j:int=0;j<cell;j++){
vertexs.push(i*step,j*step);
}
}
indices.push(0,1,3)
indices.push(1,3,4)
indices.push(1,2,4)
indices.push(2,4,5)
indices.push(3,4,6)
indices.push(4,6,7)
indices.push(4,5,7)
indices.push(5,7,8)
//下一步,我们计算三角片的组成
this.graphics.lineStyle(1,0x000000,1);
this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData)
this.graphics.drawTriangles(vertexs,indices);
this.graphics.endFill();
}
}
其显示效果如下:
我们赋值三角片的划分规则以后,图形终于显示出来了,图形是出来了,但是这个和正常的图片绘制有什么区别,区别就是我们改变一下坐标顶点的位置试试,我们将上面的图形编程一个梯形样式,代码如下:
public class MiPanoTest extends Sprite
{
[Embed(source="assets/img.jpg")]
public var texture:Class;
public function MiPanoTest()
{
var row:int=3;
var cell:int=3;
var step:int=100;
var vertexs:Vector.<Number>=new Vector.<Number>();
var indices:Vector.<int>=new Vector.<int>();
//定义了一个50区间的9格方格
for(var i:int=0;i<row;i++){
for(var j:int=0;j<cell;j++){
var offset:Number=0;
if(j==0){
offset=20*(row-i);
}else if(j==1){
offset=0
}else{
offset=-20*(row-i);
}
vertexs.push(j*step+offset,i*step);
}
}
indices.push(0,1,3)
indices.push(1,3,4)
indices.push(1,2,4)
indices.push(2,4,5)
indices.push(3,4,6)
indices.push(4,6,7)
indices.push(4,5,7)
indices.push(5,7,8)
//下一步,我们计算三角片的组成
this.graphics.lineStyle(1,0x000000,1);
this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData)
this.graphics.drawTriangles(vertexs,indices);
this.graphics.endFill();
}
}
我们看一下显示效果如下:
我们看到,虽然三角形的位置发生了变化,但是图形还是原来的图形,只是没有在三角形内部的部分,没有显示,这里,我们就要说明第三个参数uvtData
的含义,他记录的是每个顶点所占的贴图的比例,从0~1,如图:
我们要把一个完整的图形显示在当前的这个梯形内部,则我们要设置每个点的UV比例,由于每个顶点都有UV两个方向(T暂时放着)uvtData数组的长度应该是vertices的两倍
,所以,对以上的案例代码稍作修改如下:
public class MiPanoTest extends Sprite
{
[Embed(source="assets/img.jpg")]
public var texture:Class;
public function MiPanoTest()
{
var row:int=3;
var cell:int=3;
var step:int=100;
var vertexs:Vector.<Number>=new Vector.<Number>();
var indices:Vector.<int>=new Vector.<int>();
var uvtData:Vector.<Number>=new Vector.<Number>();
//定义了一个50区间的9格方格
for(var i:int=0;i<row;i++){
for(var j:int=0;j<cell;j++){
var offset:Number=0;
if(j==0){
offset=20*(row-i);
}else if(j==1){
offset=0
}else{
offset=-20*(row-i);
}
vertexs.push(j*step+offset,i*step);
}
}
indices.push(0,1,3)
indices.push(1,3,4)
indices.push(1,2,4)
indices.push(2,4,5)
indices.push(3,4,6)
indices.push(4,6,7)
indices.push(4,5,7)
indices.push(5,7,8)
uvtData.push(0,0,0.5,0,1,0,0,0.5,0.5,0.5,1,0.5,0,1,0.5,1,1,1);
//下一步,我们计算三角片的组成
this.graphics.lineStyle(1,0x000000,1);
this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData)
this.graphics.drawTriangles(vertexs,indices,uvtData);
this.graphics.endFill();
}
}
显示效果如下:
我们把一个完整的图形在多个三角网格中显示出来了。