— boreal-kiss.com

[FlashPlayer10]drawRectanglesでパノラマ画像をテクスチャリング

円環状の多面体(長方形が複数繋がったようなやつ。各長方形は三角形二つで構成)に沿ってパノラマ画像を貼付け。胆はテクスチャ貼付け用のUVT座標の設定と、円環の内側が見えるようcullingしたこと。z-sortはなんにもしてない。あと、今回新しく追加されたVector3DクラスをPointクラスの3Dバージョン(x,y,z)ではないかと推測して使っているので正しい使い方ではないかも。

[追記2008/05/19]
Vector3Dの説明やプリミティブ図形の描画方法を説明している記事発見。かなり参考になる。

[FLASH10]パノラマ
[FLASH10]パノラマ (要Flash Plaeyer 10)

package {
    /*
    * Requires Flex SDK 3.0.1 or later to be compiled
    */
    import __AS3__.vec.Vector;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.display.TriangleCulling;
    import flash.events.Event;
    import flash.geom.Vector3D;
    
    [SWF(width="700",height="400",backgroundColor="0x0",frameRate="24")]

    public class Astro11 extends Sprite{
        [Embed(source="img/panoramic.jpg")]
        private var TestImage:Class;
        
        private var img:Bitmap;
        private var container:Sprite;
        
        public function Astro11(){
            //Canvas
            container = new Sprite();
            container.x = stage.stageWidth/2;
            container.y = stage.stageHeight/2;
            addChild(container);
            
            img = new TestImage();
            addEventListener(Event.ENTER_FRAME,rotate);
        }
        
        private function rotate(e:Event):void{
            const DUMP:Number = 2.5e-3;
            var dx:Number = (mouseX - stage.stageWidth/2);
            drawScene(dx*DUMP);
        }
        
        private function drawScene(angle:Number):void{
            container.graphics.clear();
            
            //Total number of rectangle faces along a torus, 
            //i.e., 2xTOTAL triangles.
            const TOTAL:int = 30;
            
            //Radius of the torus
            const R:Number = 200;
            
            //Focal length
            const F:Number = 200;
            
            //Angular offset of the image 
            //for hiding the image's "non-gapless edge"
            const OFFSET:Number = -Math.PI/2;
            angle += OFFSET;
            
            //Size of a rectangle that two triangles make
            var w:Number = 2*Math.PI*R/TOTAL;
            var h:Number = img.height;
            
            //Arguments for drawRectangles
            var vertices:Vector.<Number> = new Vector.<Number>();
            var indices:Vector.<int> = new Vector.<int>();
            var uvtData:Vector.<Number> = new Vector.<Number>();
            
            for (var i:int=0; i<TOTAL; i++){
                var dt:Number = 2*Math.PI/TOTAL;
                 
                indices.push(2*i,2*(i+1),2*i+1, 2*i+1,2*(i+1),2*(i+1)+1);
                
                if (i==0){
                    //Define the position of each vertex in 3D space
                    var v0:Vector3D = new Vector3D(R*Math.cos(angle+i*dt),
                                                -h/2,R*Math.sin(angle+i*dt));
                    var v1:Vector3D = new Vector3D(R*Math.cos(angle+i*dt),
                                                h/2,R*Math.sin(angle+i*dt));
                    var v2:Vector3D = new Vector3D(R*Math.cos(angle+(i+1)*dt),
                                                -h/2,R*Math.sin(angle+(i+1)*dt));
                    var v3:Vector3D = new Vector3D(R*Math.cos(angle+(i+1)*dt),
                                                h/2,R*Math.sin(angle+(i+1)*dt));
                
                    //Scaling factor
                    var t0:Number = F/(F + v0.z);
                    var t1:Number = F/(F + v1.z);
                    var t2:Number = F/(F + v2.z);
                    var t3:Number = F/(F + v3.z);
                
                    vertices.push(v0.x*t0,v0.y*t0, v1.x*t1,v1.y*t1, 
                                    v2.x*t2,v2.y*t2, v3.x*t3,v3.y*t3);
                    uvtData.push(i/TOTAL,i/TOTAL,t0, i/TOTAL,1,t1, 
                                    (i+1)/TOTAL,0,t2, (i+1)/TOTAL,1,t3);
                }
                else{
                    v2 = new Vector3D(R*Math.cos(angle+(i+1)*dt),
                                                -h/2,R*Math.sin(angle+(i+1)*dt));
                    v3 = new Vector3D(R*Math.cos(angle+(i+1)*dt),
                                                h/2,R*Math.sin(angle+(i+1)*dt));
                    
                    t2 = F/(F + v2.z);
                    t3 = F/(F + v3.z);
                    
                    vertices.push(v2.x*t2,v2.y*t2, v3.x*t3,v3.y*t3);
                    uvtData.push((i+1)/TOTAL,0,t2, (i+1)/TOTAL,1,t3);
                }
            }
            
            //Frontface culling
            container.graphics.beginBitmapFill(img.bitmapData);
            container.graphics.drawTriangles(vertices,indices,uvtData,
                                            TriangleCulling.POSITIVE);
            container.graphics.endFill();
        }
    }
}
2 comments
  1. muta says: 2008年5月19日11:17 PM

    トラックバックありがとうございます。うちのブログにはそんなもの滅多にこないので嬉しい限りです。出たばかりの FlashPlayer 10 ですが、一緒に弄び倒しましょう。

  2. admin says: 2008年5月20日3:07 AM

    mutaさん >>
    ご自分で解析されたんですかね。新鮮な情報だったので参考にさせてもらいます。

Submit comment