In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

simple 3D 06 (PV3D version.)

http://wonderfl.net/c/tpsjをPV3Dで書き直してみました。
PV3Dをはじめ、各種3Dライブラリの凄さを再確認。
Get Adobe Flash player
by sakef 31 Jul 2010
    Embed
/**
 * Copyright sakef ( http://wonderfl.net/user/sakef )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/20Y9
 */

/*
    http://wonderfl.net/c/tpsjをPV3Dで書き直してみました。
    PV3Dをはじめ、各種3Dライブラリの凄さを再確認。
*/
package
{
    import com.bit101.components.Label;
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    import flash.system.Security;
    import net.hires.debug.Stats;
    import org.papervision3d.materials.BitmapMaterial;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.view.BasicView;
    
    [SWF(width="465", height="465", backgroundColor="0xffffff")]
    public class simple3d_06_pv3d extends BasicView
    {
        // サイズ・中心等
        private static const SIZE:Number=90;
        private static const RADIUS:int = 300;
        private static const CAMERA_RADIUS:int=600;
        private static const CENTER_X:int=465 >> 1;
        private static const CENTER_Y:int=465 >> 1;
        
        // 画像検索に使うキーワード
        private static const KEYWORD:String = "sea";
        
        // カメラ用
        private var isMouseDown:Boolean;
        private var oldX:Number;
        private var oldY:Number;
        private var targetRot:Number;
        private var targetPitch:Number;
        private var rot:Number;
        private var pitch:Number;
        
        // コンテナとPlaneの数
        private var container:Array;
        private var n_planes:int;
        
        // 画像用
        private var count:int;
        private var label:Label;
        
        public function simple3d_06_pv3d()
        {
            super(0,0,true,true);
            
            // ステージ設定・マウス関係停止
            stage.scaleMode=StageScaleMode.NO_SCALE;
            stage.align=StageAlign.TOP_LEFT;
            stage.quality=StageQuality.HIGH;
            stage.frameRate=30;
            mouseChildren=false;
            mouseEnabled=false;
            
            // Stats追加
            addChild(new Stats());
            
            // 変数の初期化
            container = [];
            oldX=oldY=rot=pitch=n_planes=count=0;
            targetPitch=90;
            targetRot=180;
            isMouseDown=false;
            
            // カメラの初期化
            camera.x = 0;
            camera.y = 0;
            camera.z = CAMERA_RADIUS;
        
            // Planeを球体に並べる
            var radian:Number = Math.PI/180;
            var H:int=(RADIUS * Math.PI) / SIZE;
            var theta1:Number=90;
            for(var i:int=0; i < H; i++)
            {
                var theta2:Number=0;
                var pn:int=Math.floor((2 * RADIUS * Math.PI * Math.cos(theta1 * radian)) / SIZE);
                for(var j:int=0; j < pn; j++)
                {
                    var plane:Plane = new Plane(null, SIZE, SIZE);
                    plane.rotationX=-theta1;
                    plane.rotationY=theta2;
                    plane.x=RADIUS * Math.cos(theta1 * radian) * Math.sin(theta2 * radian);
                    plane.y=RADIUS * Math.sin(theta1 * radian);
                    plane.z=RADIUS * Math.cos(theta1 * radian) * Math.cos(theta2 * radian);
                    theta2+=360 / pn;
                    container[n_planes] = plane;
                    scene.addChild(plane);
                    n_planes ++;
                }
                theta1-=180 / H;
            }
            
            // ロード状況用ラベルの初期化
            label = new Label(this, CENTER_X-80, CENTER_Y-50);
            label.scaleX = label.scaleY = 2;
            label.text="Loading images from flickr.\n" + count.toString() + "\t/ " + n_planes.toString(); 
            
            // ポリシーファイルの読み込み
            Security.loadPolicyFile("http://api.flickr.com/crossdomain.xml");
            Security.loadPolicyFile("http://farm1.static.flickr.com/crossdomain.xml");
            Security.loadPolicyFile("http://farm2.static.flickr.com/crossdomain.xml");
            Security.loadPolicyFile("http://farm3.static.flickr.com/crossdomain.xml");
            Security.loadPolicyFile("http://farm4.static.flickr.com/crossdomain.xml");
            
            // Flickrから画像のロード
            var api_loader:URLLoader=new URLLoader;
            api_loader.addEventListener(Event.COMPLETE, onCompleteAccessAPI);
            api_loader.load(new URLRequest("http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=25c5f4bc0087edf4d6efdc567daf0a64&tags="+KEYWORD + "&per_page=" + n_planes));
        }
        
        // FlickrAPIへのアクセスが成功したら実行する関数
        private function onCompleteAccessAPI(e:Event):void
        {
            var api_loader:URLLoader=e.target as URLLoader;
            api_loader.removeEventListener(Event.COMPLETE, onCompleteAccessAPI);
            
            // XMLのパースと画像のURLの作成・ロード
            var xml:XML=XML(api_loader.data);
            if (xml.@stat == "ok")
            {
                for each(var photo:XML in xml.photos.photo)
                {
                    var url:String="http://farm" + photo.@farm + ".static.flickr.com/" + photo.@server + "/" + photo.@id + "_" + photo.@secret + ".jpg";
                    var img_loader:Loader=new Loader();
                    img_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompletePhotoLoad);
                    img_loader.load(new URLRequest(url), new LoaderContext(true));
                }
            }
        }
        
        // 画像のロードが終わったら実行する関数
        private function onCompletePhotoLoad(e:Event):void
        {
            var img_loader:Loader=(e.target as LoaderInfo).loader;
            img_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onCompletePhotoLoad);
            
            // ロードした画像をPlaneに反映
            var plane:Plane = container[count] as Plane;
            var mat:BitmapMaterial = new BitmapMaterial((img_loader.content as Bitmap).bitmapData, true);
            mat.doubleSided = true;
            plane.material = mat;
            count ++;
            label.text="Loading images from flickr.\n" + count.toString() + "\t/ " + n_planes.toString(); 
            
            // 画像が全部ロードし終わったらレンダリング開始
            if(count == n_planes)
            {
                label.visible = false;
                addEventListener(Event.ENTER_FRAME, onFrame);
                stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
                stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            }
        }
        
        // 計算更新用関数
        private function onFrame(e:Event):void
        {
            // カメラの移動
            if (isMouseDown)
            {
                targetRot+=(mouseX - oldX) * 0.2;
                targetPitch+=(mouseY - oldY) * 0.2;
                targetPitch=(targetPitch > -90) ? (targetPitch) : (-90);
                targetPitch=(targetPitch < 90) ? (targetPitch) : (90);
                
                oldX=mouseX;
                oldY=mouseY;
            }
            rot+=(targetRot - rot) * 0.1;
            pitch+=(targetPitch - pitch) * 0.1;
            pitch=(pitch > -90) ? (pitch) : (-90);
            pitch=(pitch < 90) ? (pitch) : (90);
            camera.x=CAMERA_RADIUS * Math.sin(rot * Math.PI / 180);
            camera.y=CAMERA_RADIUS * Math.sin(pitch * Math.PI / 180);
            camera.z=CAMERA_RADIUS * Math.cos(rot * Math.PI / 180);
            
            // レンダリング
            singleRender();
        }
        
        // マウスダウン時の関数
        private function onMouseDown(e:MouseEvent):void
        {
            isMouseDown=true;
            oldX=mouseX;
            oldY=mouseY;
        }
        
        // マウスアップ時の関数
        private function onMouseUp(e:MouseEvent):void
        {
            isMouseDown=false;
        }
    }
}