Flash3D 全景开发一

Posted 挨踢老干部的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flash3D 全景开发一相关的知识,希望对你有一定的参考价值。

我们首先熟悉一个函数的使用drawTriangles,drawTriangles字面理解,就是画三角形,当然adobe不会因为你需要画三角形才给你提供这个方法吧,其真正的作用是通过快速批量的画三角形来实现位图的扭曲。我们所有的图形都可以用三角片来表示,不管是平面和三维图形,通过三角片,可以模拟出任何图形,如下图:

timg

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

其显示效果如下:

imageimage

以上只是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个顶点,系统会按照两个一组,进行编号,然后把这些顶点划分三角片,如下图所示:

imageimage

我们可以知道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(); 
     }
 }

其显示效果如下:

image

我们赋值三角片的划分规则以后,图形终于显示出来了,图形是出来了,但是这个和正常的图片绘制有什么区别,区别就是我们改变一下坐标顶点的位置试试,我们将上面的图形编程一个梯形样式,代码如下:

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=100var 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(); 
         }
     }

我们看一下显示效果如下:

image

我们看到,虽然三角形的位置发生了变化,但是图形还是原来的图形,只是没有在三角形内部的部分,没有显示,这里,我们就要说明第三个参数uvtData的含义,他记录的是每个顶点所占的贴图的比例,从0~1,如图:

imageimage

我们要把一个完整的图形显示在当前的这个梯形内部,则我们要设置每个点的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(); 
     }
 }

显示效果如下:

image

我们把一个完整的图形在多个三角网格中显示出来了。

以上是关于Flash3D 全景开发一的主要内容,如果未能解决你的问题,请参考以下文章

程序员都痛恨开会?多开 1 个会,我少写 1000 行代码......

震撼!全网第一张源码分析全景图揭秘Nginx

牛逼!全网第一张源码分析全景图揭秘Nginx

flash3D学习1

全景智慧城市-VR全景商业化里的一颗新星

VR全景是继互联网后的第二王朝吗?