[转]使用CS4的新增类实现全景图效果

http://uh.9ria.com/space-12147-do-blog-id-5759.html

全景图原理其实很简单,就是将做好的球面贴图贴在一个圆的内部,然后将摄像机放在圆的中间观看,由于视差而产生的现象。因此,只要使用3D引擎的话,制作一个全景系统是很简单的(创建球体,贴上贴图,然后放置摄像机到原点就可以)

但是仅仅是一个全景显示就去搬pv3D这样一个大家伙过来有些小题大做。FLASH3D其实都是将位图打碎成三角形,然后对每个三角形做矩阵变换,并通过绘制三角形到元件的方式实现的。明白这一点就可以自己做。CS4之后提供了原生的3D转换和批量绘制三角形的drawTriangles方法以及许多关于3D矢量的数学公式,大大简化了这个过程(但drawTriangles的使用方法确实难以掌握)

http://code.google.com/p/ghostcat/source/browse/trunk/ghostcatfp10/src/ghostcat/display/g3d/GBitmapSphere.as

这个类实际上是一个绘制球体的类,传入位图贴图,半径,面数之后,修改其matrix3d属性并执行render方法后,就会绘制出一个3D的球体。我们要制作全景效果,只要将它的culling属性设为显示内部TriangleCulling.NEGATIVE,然后将圆的半径设置得足够大,看起来就像是在球体内部了。

值得一提的是,这样制作的全景系统将只有1.8K。而且因为省掉了排序等等多余的操作,效率会有一定提高。

之后会再说说全景中热点的实现方法。







package ghostcat.display.g3d
{
        import flash.display.BitmapData;
        import flash.display.Sprite;
        import flash.display.TriangleCulling;
        import flash.geom.Matrix3D;
        import flash.geom.Point;
        import flash.geom.Vector3D;

        /**
         * 位图贴图球体
         *  
         * @author flashyiyi
         * 
         */
        public class GBitmapSphere extends Sprite
        {
                /**
                 * 贴图
                 */
                public var material:BitmapData;
                
                private var vertsVec:Vector.<Vector.<Vector3D>>;
                
                /**
                 * 转换矩阵 
                 */
                public var matrix3D:Matrix3D;
                /**
                 * 半径
                 */
                public var radius:Number;
                
                /**
                 * 显示内部/外部
                 */
                public var culling:String;
                
                /**
                 * 贴图平滑
                 */
                public var smooth:Boolean;
                
                private var nMesh:Number;
                private var vertices:Vector.<Number>;
                private var indices:Vector.<int>;
                private var uvtData:Vector.<Number>;
                
                public function GBitmapSphere(material:BitmapData,radius:Number = 100, nMesh:int = 30)
                {
                        this.material = material;
                        this.radius = radius;
                        this.nMesh = nMesh;
                        this.matrix3D = new Matrix3D();
                        this.culling = TriangleCulling.POSITIVE;
                        
                        setVertsVec();
                        render();
                }
                
                /**
                 * 创建多边形
                 * 
                 */
                protected function setVertsVec():void
                {
                        var i:int;
                        var j:int;
                        var istep:Number;
                        var jstep:Number;
                        
                        istep=2*Math.PI/nMesh;
                        jstep=Math.PI/nMesh;
                        
                        this.vertsVec=new Vector.<Vector.<Vector3D>>();
                        
                        for(i=0;i<=nMesh;i++)
                        {
                                var vector:Vector.<Vector3D> = new Vector.<Vector3D>();
                                for(j=0;j<=nMesh;j++)
                                {
                                        vector[j]=new Vector3D(radius*Math.sin(istep*i)*Math.sin(jstep*j),-radius*Math.cos(jstep*j),-radius*Math.cos(istep*i)*Math.sin(jstep*j));
                                }
                        
                                vertsVec[i] = vector;
                        }
                        
                        indices = new Vector.<int>();
                        uvtData = new Vector.<Number>();
                        
                        var curVertsNum:int=0;
                        for(i=0;i<nMesh;i++)
                        {
                                for(j=0;j<nMesh;j++)
                                {
                                        indices.push(curVertsNum,curVertsNum+1,curVertsNum+3,curVertsNum+1,curVertsNum+2,curVertsNum+3);
                                        uvtData.push(i/nMesh,j/nMesh,(i+1)/nMesh,j/nMesh,(i+1)/nMesh,(j+1)/nMesh,i/nMesh,(j+1)/nMesh);
                                        curVertsNum += 4;
                                }
                        }
                }
                
                /**
                 * 旋转矩阵并渲染 
                 * @param rotx
                 * @param roty
                 * @param rotz
                 * 
                 */
                public function rotate(rotx:Number,roty:Number,rotz:Number):void
                {
                        matrix3D.appendRotation(rotx,Vector3D.X_AXIS);
                        matrix3D.appendRotation(roty,Vector3D.Y_AXIS);
                        matrix3D.appendRotation(rotz,Vector3D.Z_AXIS);
                }
                
                /**
                 * 重置旋转
                 * 
                 */
                public function reset():void
                {
                        matrix3D = new Matrix3D();
                }
                
                /**
                 * 根据矩阵渲染图像 
                 * 
                 */
                public function render():void
                {
                        vertices = new Vector.<Number>();
                        for(var i:int = 0;i<nMesh;i++)
                        {
                                for(var j:int = 0;j<nMesh;j++)
                                {
                                        var curv0:Vector3D = matrix3D.deltaTransformVector(vertsVec[i][j]);
                                        var curv1:Vector3D = matrix3D.deltaTransformVector(vertsVec[i+1][j]);
                                        var curv2:Vector3D = matrix3D.deltaTransformVector(vertsVec[i+1][j+1]);
                                        var curv3:Vector3D = matrix3D.deltaTransformVector(vertsVec[i][j+1]);
                                        
                                        vertices.push(curv0.x,curv0.y,curv1.x,curv1.y,curv2.x,curv2.y,curv3.x,curv3.y);
                                }
                        }
                        
                        graphics.clear();
                        
                        if (material)
                                graphics.beginBitmapFill(material,null,false,smooth);
                        
                        graphics.drawTriangles(vertices,indices,uvtData,culling);
                        graphics.endFill();
                }
        }
}

你可能感兴趣的:(Google,Blog,Flash,J#)