flash on 2011-12-8

by roconico
Alternativa3D MovieClipMaterial
papervision3dでできてもAlternativa3Dではどうすれば?シリーズ、第4弾

Ver5.6で追加されたMovieClipMaterialを使用すれば、Alternativa3Dでも簡単にアニメするMaterialを貼り付けられます。
がんばればFLVだって流せます
 たぶんTextureMaterialを継承してるので内部で、ひたすらbitmapDataにcopyPixel or drawしてるだけでしょうね。
ちなみにAlternativa3Dの公式サイトにあるデモでは、Spriteをひたすらdrawしてましたねw
@narutohyper

Alternativa3D を簡単に扱うためのベーシックテンプレート
@author Yasu (clockmaker)
♥0 | Line 155 | Modified 2011-12-09 12:53:41 | MIT License
play

ActionScript3 source code

/**
 * Copyright roconico ( http://wonderfl.net/user/roconico )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/20lF
 */

package {

    import alternativ5.engine3d.materials.MovieClipMaterial
    import alternativ5.engine3d.primitives.Box;
    import alternativ5.types.Point3D;
    
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.display.GradientType
    import flash.events.Event;
    import flash.geom.Matrix


    [SWF(width = 465, height = 465, frameRate = 60)]
    /**
     * Alternativa3D MovieClipMaterial
     * papervision3dでできてもAlternativa3Dではどうすれば?シリーズ、第4弾
     * 
     * Ver5.6で追加されたMovieClipMaterialを使用すれば、Alternativa3Dでも簡単にアニメするMaterialを貼り付けられます。
     * がんばればFLVだって流せます
     * たぶんTextureMaterialを継承してるので内部で、ひたすらbitmapDataにcopyPixel or drawしてるだけでしょうね。
     * ちなみにAlternativa3Dの公式サイトにあるデモでは、Spriteをひたすらdrawしてましたねw
     * @narutohyper
    */
    
    /**
     * Alternativa3D を簡単に扱うためのベーシックテンプレート
     * @author Yasu (clockmaker)
     */
    public class SimpleDemo extends Sprite {

        public function SimpleDemo():void {

            // テンプレートを作成します
            var template:BasicTemplate = new BasicTemplate();
            addChild(template);



            //-----------------------------------------------
            //MovieClipの作成
            //-----------------------------------------------
                //MovieClipを作成します。
                var mc:MovieClip=new MovieClip();

                var colors:Array=new Array(0x000099,0x000000)
                var alphas:Array=new Array(1,1)
                var ratios:Array=new Array(0,255)
                var matrix:Matrix=new Matrix()
                matrix.createGradientBox(500,500,Math.PI/2,0,0)
                mc.graphics.beginGradientFill(GradientType.RADIAL,colors, alphas, ratios, matrix)

                mc.graphics.drawRect(0,0,500,500)

                var circle:Sprite=new Sprite();
                circle.graphics.beginFill(0xFFFFFFF)
                circle.graphics.drawCircle(0,0,20)

                mc.addChild(circle);
                circle.y=250
                circle.addEventListener(Event.ENTER_FRAME,onCircleEnterFrame)

                var pitchX:Number=5
                var pitchY:Number=5
                function onCircleEnterFrame(e:Event):void {
                    var c:*=e.currentTarget;
                    c.x+=pitchX
                    c.y+=pitchY

                    if (circle.x+(c.width/2)>500) {
                        pitchX*=-1
                        c.x=500-(c.width/2)
                    } else if (c.x-(c.width/2)<0) {
                        pitchX*=-1
                        c.x=0+(c.width/2)
                    }

                    if (c.y+(c.width/2)>500) {
                        pitchY*=-1
                        c.y=500-(c.height/2)
                    } else if (c.y-(c.height/2)<0) {
                        pitchY*=-1
                        c.y=0+(circle.height/2)
                    }
                }

            //-----------------------------------------------
            //Boxの作成
            //-----------------------------------------------


                // マテリアルを作成します 
                var material:MovieClipMaterial = new MovieClipMaterial(mc,500,500); 

                // プリミティブを作成します 
                var box:Box = new Box(500, 500, 500); 
                box.cloneMaterialToAllSurfaces(material); 

                // 3Dシーンのルートに追加します 
                template.scene.root.addChild(box); 

            


            var angle:uint=0


            // Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
            // レンダリング前に実行したい処理を記述します。
            template.onPreRender = function():void {

                // 立方体を回転させます (角度はラジアン)
                box.rotationY += 1 * Math.PI / 180;



            
                // マウスがステージの高さ何%の位置にあるか算出
                var rateY:Number = mouseY / stage.stageHeight;
                
                // カメラの高さの座標を調整
                // イージングの公式 対象の値 += (目標値 - 現在の値) * 減速率
                template.camera.y += ( - 1000 * rateY - template.camera.y) * 0.1;
                
                // カメラの座標を中央に向かせる
                template.cameraContoller.lookAt(new Point3D());
            }
        }
    }
}



/**
 * BasicTemplate for Alternativa3D
 * Alternativa3Dを扱いやすくするためのテンプレートです
 * @author Yasu
 */
import alternativ5.engine3d.controllers.CameraController;
import alternativ5.engine3d.core.Camera3D;
import alternativ5.engine3d.core.Object3D;
import alternativ5.engine3d.core.Scene3D;
import alternativ5.engine3d.display.View;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
class BasicTemplate extends Sprite{
    /**
     * シーンインスタンスです。
     */
    public var scene:Scene3D;
    /**
     * ビューインスタンスです。
     */
    public var view:View;
    /**
     * カメラインスタンスです。
     */
    public var camera:Camera3D;
    /**
     * カメラコントローラーです。
     */
    public var cameraContoller:CameraController;
    
    private var _viewWidth:int;
    private var _viewHeight:int;
    private var _scaleToStage:Boolean;

    /**
     * 新しい BasicTemplate インスタンスを作成します。
     * @param    viewWidth
     * @param    viewHeight
     * @param    scaleToStage
     */
    public function BasicTemplate(viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true) {
        _viewWidth = viewWidth;
        _viewHeight = viewHeight;
        _scaleToStage = scaleToStage;
        
        // Creating scene
        scene = new Scene3D();
        scene.splitAnalysis = false; // not analysis for performance
        scene.root = new Object3D();
        
        // Adding camera
        camera = new Camera3D();
        camera.z = -1000;
        scene.root.addChild(camera);
        
        // camera contoller
        cameraContoller = new CameraController(this);
        cameraContoller.camera = camera;
        
        // set view
        view = new View();
        view.camera = camera;
        addChild(view);
        
        // stage
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }
    
    /**
     * 初期化されたときに実行されるイベントです。
     * 初期化時に実行したい処理をオーバーライドして記述します。
     */
    protected function atInit():void {}
    
    /**
     * 初期化されたときに実行されるイベントです。
     * 初期化時に実行したい処理を記述します。
     */
    private var _onInit:Function = function():void { };
    public function get onInit():Function { return _onInit; }
    public function set onInit(value:Function):void {
        _onInit = value;
    }
    
    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング前に実行したい処理をオーバーライドして記述します。
     */
    protected function atPreRender():void {}
    
    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング前に実行したい処理を記述します。
     */
    private var _onPreRender:Function = function():void{};
    public function get onPreRender():Function { return _onPreRender; }
    public function set onPreRender(value:Function):void {
        _onPreRender = value;
    }
    
    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング後に実行したい処理をオーバーライドして記述します。
     */
    protected function atPostRender():void {
    }
    
    /**
     * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
     * レンダリング後に実行したい処理を記述します。
     */
    protected var _onPostRender:Function = function():void{};
    public function get onPostRender():Function { return _onPostRender; }
    public function set onPostRender(value:Function):void {
        _onPostRender = value;
    }
    
    /**
     * レンダリングを開始します。
     */
    public function startRendering():void {
        addEventListener(Event.ENTER_FRAME, onRenderTick);
    }
    /**
     * レンダリングを停止します。
     */
    public function stopRendering():void {
        removeEventListener(Event.ENTER_FRAME, onRenderTick);
    }
    
    /**
     * シングルレンダリング(レンダリングを一回だけ)を実行します。
     */
    public function singleRender():void {
        onRenderTick();
    }
    
    /**
     * @private
     */
    private function init(e:Event = null):void {
        stage.scaleMode = StageScaleMode.NO_SCALE;
        stage.align = StageAlign.TOP_LEFT;
        stage.quality = StageQuality.HIGH;

        // resize
        stage.addEventListener(Event.RESIZE, onResize);
        onResize(null);
        
        // render
        startRendering();
        
        atInit();
        _onInit();
        
    }
    
    /**
     * @private
     */
    private function onRenderTick(e:Event = null):void {
        atPreRender();
        _onPreRender();
        scene.calculate();
        atPostRender();
        _onPostRender();
    }
    
    /**
     * @private
     */
    private function onResize(event:Event = null):void {
        if (_scaleToStage) {
            view.width = stage.stageWidth;
            view.height = stage.stageHeight;
        }else {
            view.width = _viewWidth;
            view.height = _viewHeight;
        }
    }
}