// mxmlc -output /Users/shin_ishimaru/Sites/Video3D/Video3D.swf -benchmark=true -default-size 240 240 -default-frame-rate=60 -default-background-color=0xFFFFFF Video3D.as

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.media.*;
    import flash.net.*;
    import flash.text.*;
    import flash.filters.*;

    import org.papervision3d.scenes.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;

    [SWF(backgroundColor=0xffffff)]

    public class Video3D extends Sprite
    {
        // _______________________________________________________________________
        //                                                                  vars3D
        private var container : Sprite;
        private var scene     : MovieScene3D;
        private var camera    : Camera3D;

        private var planeObj  : DisplayObject3D;
        private var planeSize : int = 300;      //Planeオブジェクト1辺の長さ
        private var segment   : int = 1;        //面の分割数
        private var material  : BitmapMaterial;
        private var bmpData   : BitmapData;
        private var connection: NetConnection;  //コネクション
        private var stream    : NetStream;      //ストリーム
        private var video     : Video;
        private var label     : TextField;

        private var valx      : Number = 0;
        private var valy      : Number = 0;
        private var count     : uint = 0;

        static public const
            TEXTURE_W:int = 240,    ///< テクスチャの幅
            TEXTURE_H:int = 240;    ///< テクスチャの高さ

        // _______________________________________________________________________
        //                                                             Constructor
        public function Video3D():void
        {
            stage.frameRate = 60;
            stage.quality   = "MEDIUM";
            stage.scaleMode = "noScale";
            stage.align = StageAlign.TOP_LEFT;
            this.addEventListener(Event.ENTER_FRAME, loop3D);
            this.stage.addEventListener(Event.RESIZE, onStageResize);

            label=new TextField();
            label.autoSize=TextFieldAutoSize.LEFT;
            addChild(label);

            init3D();

            //コネクションの生成
            connection=new NetConnection();

            //イベントリスナーの追加
            connection.addEventListener(
                NetStatusEvent.NET_STATUS,netStatusHandler);
            connection.addEventListener(
                SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);

            //ファイルとの接続を確立
            connection.connect(null);
        }
        //ネット状態イベントの処理
        private function netStatusHandler(evt:NetStatusEvent):void {
            switch (evt.info.code) {
                //成功
                case "NetConnection.Connect.Success":
                    //ストリームの生成
                    stream = new NetStream(connection);

                    //イベントリスナーの追加
                    stream.addEventListener(
                        NetStatusEvent.NET_STATUS,netStatusHandler);
                    stream.addEventListener(
                        AsyncErrorEvent.ASYNC_ERROR,asyncErrorHandler);

                    //動画の表示領域の生成
                    video = new Video();
                    video.attachNetStream(stream);

                    //動画ストリーミングの再生開始
                    stream.play("sample.flv");
                    label.text="FLV読み込み成功";
                    break;
                //ファイルが見つからない
                case "NetStream.Play.StreamNotFound":
                    label.text="ファイルが見つからない";
                    break;
                //繰り返し再生
                case "NetStream.Play.Stop":
                    stream.seek(0);
                    break;
            }
        }

        //非同期エラーイベントの処理
        private function asyncErrorHandler(evt:AsyncErrorEvent):void {
        }

        //セキュリティエラーイベントの処理
        private function securityErrorHandler(evt:SecurityErrorEvent):void {
            label.text="セキュリティエラー";
        }

        // _______________________________________________________________________
        //                                                                  Init3D
        private function init3D():void
        {
            //コンテナ生成
            this.container = new Sprite();
            addChild(this.container);
            this.container.x = this.stage.stageWidth  / 2;
            this.container.y = this.stage.stageHeight / 2;

            //シーン生成
            scene = new MovieScene3D( container );

            //カメラ設定
            camera = new Camera3D();
            camera.z = -planeSize;
            camera.focus = 500;
            camera.zoom = 1;

            //BitmapDataの作成。Bitmapに角丸矩形を描く
            bmpData = new BitmapData(TEXTURE_W,TEXTURE_H,false,0xff0000);

            //マテリアル設定
            material = new BitmapMaterial(bmpData);
            material.oneSide = false;

            //Planeオブジェクト生成
            //planeObj = scene.addChild( new Plane( material, planeSize, planeSize, segment, segment) );
            planeObj = scene.addChild( new Cube( material, planeSize, planeSize, planeSize, segment, segment, segment) );

        }

        // _______________________________________________________________________
        //                                                                    Loop
        private function loop3D( event:Event ):void
        {
            valx -= 0.2;
            valy -= 0.5;
            planeObj.rotationY = valx;
            planeObj.rotationX = 45;

            //ビデオをテクスチャに書き込む
            video.attachNetStream(null);
            bmpData.draw(video);
            video.attachNetStream(stream);

            //フィルタかける
            var filters:Array = new Array;
            filters.push(new DropShadowFilter(20, 45, 0x000000, 0.8, 5, 5, 1, BitmapFilterQuality.HIGH, false, false, false));
            //ブラー
            var blur:Number = 10*Math.sin( (++count/25) );
            if(blur > 0){
                filters.push(new BlurFilter(blur,blur,BitmapFilterQuality.HIGH));
            }
            planeObj.container.filters = filters;

            //レンダリング
            this.scene.renderCamera( camera );
        }

        // _______________________________________________________________________
        //                                                           onStageResize
        private function onStageResize(event:Event):void
        {
            this.container.x = this.stage.stageWidth  / 2;
            this.container.y = this.stage.stageHeight / 2;
        }

    }
}