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

MIKUMIKU BLUR DEMO

東京てら子7 『夏休みの自由研究発表』の発表その2
* http://atnd.org/events/6936
* PV3Dで(モーション)ブラーをかけられるかを試したものです
* みんな大好き初音ミクのモデルデータをブラーってみました。
* ぶっちゃけ重いです
* ネギ振り/髪揺れつき
* ただの残像ではないので、ネギ振り/髪揺れにはブラーがかかっていません
* あくまで、カメラの動きにのみブラーがかかっています
Get Adobe Flash player
by fumix 29 Aug 2010
/**
 * Copyright fumix ( http://wonderfl.net/user/fumix )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/lYTe
 */

/*
 * 東京てら子7 『夏休みの自由研究発表』の発表その2
 * http://atnd.org/events/6936
 * PV3Dで(モーション)ブラーをかけられるかを試したものです
 * みんな大好き初音ミクのモデルデータをブラーってみました。
 * ぶっちゃけ重いです
 * ネギ振り/髪揺れつき
 * ただの残像ではないので、ネギ振り/髪揺れにはブラーがかかっていません
 * あくまで、カメラの動きにのみブラーがかかっています
 */
package {
    import org.libspark.betweenas3.easing.Sine;
    import flash.filters.BlurFilter;
    import org.libspark.betweenas3.easing.Cubic;
    import org.libspark.betweenas3.core.easing.CubicEaseInOut;
    import flash.geom.Point;
    import flash.display.SpreadMethod;
    import flash.geom.Matrix;
    import flash.display.GradientType;
    import flash.display.Shape;
    import org.papervision3d.render.QuadrantRenderEngine;
    import org.libspark.betweenas3.tweens.ITweenGroup;
    import org.libspark.betweenas3.tweens.ITween;
    import org.libspark.betweenas3.core.tweens.groups.SerialTween;
    import org.libspark.betweenas3.BetweenAS3;
    import org.papervision3d.events.FileLoadEvent;
    import org.papervision3d.objects.DisplayObject3D;

    import net.hires.debug.Stats;

    import com.bit101.components.HUISlider;
    import com.bit101.components.Label;

    import flash.display.Bitmap;
    import flash.geom.ColorTransform;
    import flash.display.BitmapData;
    import org.papervision3d.core.math.Number3D;

    import flash.events.MouseEvent;
    import flash.display.DisplayObject;
    import flash.display.StageQuality;
    import flash.events.Event;
    
    import org.papervision3d.objects.parsers.DAE;
    import org.papervision3d.view.BasicView;
    [SWF(backgroundColor="#FFFFFF", frameRate="15", width="465", height="465")]
    public class LoadCollada extends BasicView
    {
        private var model:DAE;
        private var _negi:DisplayObject3D;
        private var _arm:DisplayObject3D;
        private var _far : DisplayObject3D;

        private var _view : BitmapData;
        private var _colorTransBlur : ColorTransform;

        private var _stats : Stats;
        private var _colorTrans : ColorTransform;
        private var _kami : DisplayObject3D;

        public function LoadCollada() {
            // flash init
            stage.quality = StageQuality.MEDIUM;

            //BG設置    
            var bg : Shape = new Shape();
            addChildAt(bg, 0);
            var gradType:String = GradientType.LINEAR;
            var gradColors:Array = [ 0xFFFFFF , 0xE8E8E8 ];
            var gradAlphas:Array = [ 1, 1 ];
            var gradRadios:Array = [ 0, 255 ];
            var gradMrx:Matrix = new Matrix( );
            gradMrx.createGradientBox( stage.stageWidth,  stage.stageHeight , Math.PI/2, 0,0);
            var gradSpread:String = SpreadMethod.PAD;
            bg.graphics.beginGradientFill( gradType , gradColors ,  gradAlphas , gradRadios , gradMrx ,gradSpread);
            bg.graphics.drawRect( 0 , 0, stage.stageWidth, stage.stageHeight ); 

            //view設置
            _view = new BitmapData(stage.stageWidth,  stage.stageHeight);
            addChild(new Bitmap(_view));

            //ラベル設置
            var la : Label = new Label(this, 8, 4, "MIKUMIKU BLUR DEMO");
            la.scaleX = la.scaleY = 2;
            var la2:Label = new Label(this, 10, 30, "PLASE DRAG STAGE");
            
            //stats設置
            _stats = new Stats();
            _stats.x = stage.stageWidth - 78;
            _stats.y = 8;
            addChild(_stats);

            //ColorTransform設定
            _colorTransBlur = new ColorTransform();
            _colorTrans = new ColorTransform(1, 1, 1, 0.0);
            
            // DAEクラスのインスタンスmodelを作成
            model = new DAE();
            // daeファイルを読み込む。これだけでOK。めっちゃ簡単。
            // negimiku.daeファイルは、miku.pngを読むように設定されているのでマテリアルとかもいらない。
            model.load("http://www.planet-ape.net/pv3d/negimiku2.dae");
            model.addEventListener( FileLoadEvent.LOAD_COMPLETE, compCollada );
            // サイズ調整 (今回はモデルが1つなのでこれで平気そうにみえる。ホントはmodelを大きくしたい)
            model.scale = 45;
            model.y = -100;
            camera.y = 400;
            // シーンにaddChild
            scene.addChild(model);

            //viewportをリムーブ
            removeChild(viewport);
        }

        /**
         * colladaファイルの読み込み完了
         * @param event
         */
        private function compCollada(event : FileLoadEvent) : void {
            var dae_rootNode:DisplayObject3D = model.getChildByName("COLLADA_Scene");
            //ネギと腕を取りだす
            _negi = dae_rootNode.getChildByName('negi');
            _arm = dae_rootNode.getChildByName('R_arm');
            _far = dae_rootNode.getChildByName('miku_far');
            _kami = dae_rootNode.getChildByName('miku_kami');
            //ネギを腕にaddChildし直し(位置の調整も)
            dae_rootNode.removeChildByName('negi');
            _negi.x = -1.5;
            _negi.y = -6.5;
            _negi.z = 1.0;
            _arm.addChild(_negi);

            //髪アニメ
            var kamiAnim1:ITween = BetweenAS3.tween(_kami, {rotationX:10},{rotationX:-5},0.5, Sine.easeInOut);
            var kamiAnim2:ITween = BetweenAS3.tween(_kami, {rotationX:-5},{rotationX:10},0.5, Sine.easeInOut);
            var kamiSerial:ITween = BetweenAS3.serial(kamiAnim1,kamiAnim2);
            kamiSerial.stopOnComplete = false;
            kamiSerial.play();
            
            // render and loop
            addEventListener(Event.ENTER_FRAME, loop);
            
            // mouse interactive
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }

        private function loop(event : Event) : void {
            // Mouse Interactive
            easePitchOld = easePitch;
            easeYawOld = easeYaw;
            easePitch += (cameraPitch - easePitch) * 0.4;
            easeYaw += (cameraYaw - easeYaw) * 0.4;
            
            easePitchDiff = (easePitch - easePitchOld) / 6;
            easeYawDiff = (easeYaw - easeYawOld) / 6;            

            _view.lock();
            _view.colorTransform(_view.rect, _colorTrans);
            for(var j : int = 1;j <= 6;j++) {
                camera.x = 1200 * Math.sin((easeYawOld + easeYawDiff * j) * Number3D.toRADIANS);
                camera.z = 1200 * Math.cos((easeYawOld + easeYawDiff * j) * Number3D.toRADIANS);
                camera.y = 40 * (easePitchOld + easePitchDiff*j);

                singleRender();

                _colorTransBlur.alphaOffset = -255*(6 - j) / 6;
                _view.draw(viewport, null, _colorTransBlur);                    
            }

            _view.unlock();
        }

        // ----------------------------------------------
        // Mouse Interactive
        // ----------------------------------------------

        private var isOribiting : Boolean;
        private var cameraPitch : Number = 10;
        private var cameraYaw : Number = 90;
        private var previousMouseX : Number;
        private var previousMouseY : Number;
        private var easePitch : Number = 270;
        private var easeYaw : Number = 90;
        private var easePitchOld : Number = 270;
        private var easeYawOld : Number = 90;
        private var easePitchDiff : Number;
        private var easeYawDiff : Number;
        
        private function onMouseDown(event : MouseEvent) : void {
            isOribiting = true;
            previousMouseX = event.stageX;
            previousMouseY = event.stageY;
            singleRender();
        }

        private function onMouseUp(event : MouseEvent) : void {
            isOribiting = false;

            //ネギ振りアニメ
            var anim:ITween;
            
            var negiAnim:ITween = BetweenAS3.tween(_negi, {rotationX:35},{rotationX:0},0.3);
            var negiSerial:ITween = BetweenAS3.serial(negiAnim,BetweenAS3.reverse(negiAnim));
            var armAnim:ITween = BetweenAS3.tween(_arm, {rotationX:45},{rotationX:0},0.3,Cubic.easeInOut);
            var armAnim2:ITween = BetweenAS3.tween(_arm, {rotationX:360},{rotationX:0},0.4,Cubic.easeInOut);
            var armSerial:ITween = BetweenAS3.serial(armAnim,BetweenAS3.reverse(armAnim));
            if(Math.random()>0.2){
                anim = BetweenAS3.parallel(negiSerial, armSerial);
            }else{
                anim = BetweenAS3.parallel(armAnim2);                
            }
            anim.play();

        }

        private function onMouseMove(event : MouseEvent) : void {
            var differenceX:Number = event.stageX - previousMouseX;
            var differenceY:Number = event.stageY - previousMouseY;
 
            if(isOribiting) {
                cameraPitch += differenceY * 0.3;
                cameraYaw += differenceX * 0.3;
                
                cameraPitch = Math.max(5, Math.min(cameraPitch, 360));
 
                previousMouseX = event.stageX;
                previousMouseY = event.stageY;
            }
        }
    }
}