forked from: Alternativa3D TextureEnvironmentMaterial (環境マップ)のテスト

by mycodingqt forked from Alternativa3D TextureEnvironmentMaterial (環境マップ)のテスト (diff: 1)
♥0 | Line 848 | Modified 2011-09-13 19:12:12 | MIT License
play

ActionScript3 source code

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

// forked from narutohyper's Alternativa3D TextureEnvironmentMaterial (環境マップ)のテスト
package {
    /**
     * Alternativa3D 環境マップのテスト
     * 画面ドラッグで回転します、
     *
     * Alternativa3D platformのフォーラムで公開されていた、環境マップマテリアルの習作です。
     * あくまでAlternativa3Dの環境マップテストです。
     * 他意はございません。
     *
     * 画像は最初に3枚読み込みますが、もし表示されなかったらリロードしてください
     *
     * LOADで画像はめ込めますけどね・・・
     * 
     * @narutohyper
     */    
    import alternativ5.engine3d.materials.FillMaterial;
    import alternativ5.engine3d.materials.TextureMaterial;
    import alternativ5.engine3d.core.Object3D;
    import alternativ5.engine3d.core.Mesh;
    import alternativ5.engine3d.core.Vertex
    import alternativ5.engine3d.core.Surface
    import alternativ5.engine3d.events.MouseEvent3D
    import alternativ5.engine3d.loaders.*; 
    import alternativ5.types.Point3D;
    import alternativ5.types.Texture;
    import alternativ5.utils.*

    import flash.display.*;
    import flash.net.URLRequest; 
    import flash.events.Event;
    import flash.events.MouseEvent;

    import flash.system.LoaderContext; 
    import flash.geom.Point;
    import flash.geom.Matrix;
    import flash.system.Security;
    import flash.text.*;    
    import org.libspark.thread.EnterFrameThreadExecutor;
    import org.libspark.thread.Thread; 
    

    [SWF(width = 465, height = 465, frameRate = 60,backgroundColor=0x000000)]

    public class SimpleDemo extends Sprite {
        public static const CROSSDOMAIN:String = "http://marubayashi.net/crossdomain.xml";
        public var mc1:MovieClip;
        public var mc2:MovieClip;

        private var bmd1:BitmapData;
        private var bmd2:BitmapData;
        private var bmd3:BitmapData;
        private var mcm1:TextureMaterial
        private var mcm2:TextureMaterial
        private var mcm3:TextureEnvironmentMaterial
        private var newMesh:Mesh;


        public function SimpleDemo():void {
            var dbg:TextField=new TextField()
            dbg.autoSize=TextFieldAutoSize.LEFT
            dbg.selectable=false;
            dbg.mouseEnabled=false;
            var format:TextFormat=new TextFormat();
            format.color=0x666666
            format.size=12;
            format.font='_ゴシック';
            dbg.defaultTextFormat=format
            dbg.x=100;
            addChild(dbg)


            var img1:Loader=new Loader();
            var img2:Loader=new Loader();
            var img3:Loader=new Loader();
            Security.loadPolicyFile(CROSSDOMAIN);
            var context:LoaderContext = new LoaderContext(true);
            img1.load(new URLRequest('http://marubayashi.net/archive/sample/images/environment/a.jpg'), context); 
            img1.contentLoaderInfo.addEventListener(Event.COMPLETE, img1Complete);

            function img1Complete (e:Event):void {
                img1.contentLoaderInfo.removeEventListener(Event.COMPLETE, img1Complete);
                bmd1=new BitmapData(800,800,false,0x000000)
                bmd1.perlinNoise(40, 40, 1, 1, true, true, 8, true, null);
                bmd1.draw(img1.content,new Matrix(1,0,0,1,300,300),null,BlendMode.SCREEN)
                img2.load(new URLRequest('http://marubayashi.net/archive/sample/images/environment/b.jpg'), context); 
                img2.contentLoaderInfo.addEventListener(Event.COMPLETE, img2Complete);
                
            }

            function img2Complete (e:Event):void {
                img2.contentLoaderInfo.removeEventListener(Event.COMPLETE, img2Complete);
                bmd2=new BitmapData(200,200,false,0)
                bmd2.draw(img2.content)
                img3.load(new URLRequest('http://marubayashi.net/archive/sample/images/environment/c.jpg'), context); 
                img3.contentLoaderInfo.addEventListener(Event.COMPLETE, img3Complete);
                
            }

            function img3Complete (e:Event):void {
                img3.contentLoaderInfo.removeEventListener(Event.COMPLETE, img3Complete);
                bmd3=new BitmapData(200,200,false,0)
                bmd3.draw(img3.content)
            }

            this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            function onEnterFrame(e:Event):void {
                loadCheck()
            }
            
            function loadCheck():void {

                if (bmd1,bmd2,bmd3) {
                    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
                    removeChild(dbg)
                    init()
                } else {
                    dbg.text='now loading ';
                    dbg.appendText((img1.contentLoaderInfo.bytesTotal>1000)?Math.round(img1.contentLoaderInfo.bytesLoaded/img1.contentLoaderInfo.bytesTotal*100)+'% ':'-?-');
                    dbg.appendText((img2.contentLoaderInfo.bytesTotal>1000)?Math.round(img2.contentLoaderInfo.bytesLoaded/img2.contentLoaderInfo.bytesTotal*100)+'% ':'-?-');
                    dbg.appendText((img3.contentLoaderInfo.bytesTotal>1000)?Math.round(img3.contentLoaderInfo.bytesLoaded/img3.contentLoaderInfo.bytesTotal*100)+'% ':'-?-');
                        
                }
            }

        }



        private function init():void {

            // テンプレートを作成します
            var template:BasicTemplate = new BasicTemplate();
            addChild(template);
            template.camera.coords=new Point3D(0,0,-1000)

            // マテリアルを作成します

            var material1:FillMaterial=new FillMaterial(0xEEEEEE,1,BlendMode.NORMAL,1,0x0000000);
            var material2:FillMaterial=new FillMaterial(0x666666,1,BlendMode.NORMAL,1,0x0000000);



            mcm1=new TextureMaterial(new Texture(bmd1),1,false,true)
            mcm2=new TextureMaterial(new Texture(bmd2),1,false,true)
            mcm3=new TextureEnvironmentMaterial(new Texture(bmd3), new Texture(bmd1),0.2,1.0,true,true)


            newMesh=new Mesh();

            newMesh.createVertex( 290.00,  375.00, -25.00, 0);
            newMesh.createVertex( 270.00,  384.00, -25.00, 1);
            newMesh.createVertex(-270.00,  384.00, -25.00, 2);
            newMesh.createVertex(-290.00,  375.00, -25.00, 3);
            newMesh.createVertex(-300.00,  354.00, -25.00, 4);
            newMesh.createVertex(-300.00, -354.00, -25.00, 5);
            newMesh.createVertex(-290.00, -375.00, -25.00, 6);
            newMesh.createVertex(-270.00, -384.00, -25.00, 7);
            newMesh.createVertex( 270.00, -384.00, -25.00, 8);
            newMesh.createVertex( 290.00, -375.00, -25.00, 9);
            newMesh.createVertex( 300.00, -354.00, -25.00,10);
            newMesh.createVertex( 300.00,  354.00, -25.00,11);

            newMesh.createVertex( 270.00,  354.00, -25.00,12);
            newMesh.createVertex(-270.00,  354.00, -25.00,13);
            newMesh.createVertex(-270.00, -354.00, -25.00,14);
            newMesh.createVertex( 270.00, -354.00, -25.00,15);

            newMesh.createVertex( 290.00,  375.00,  5.00,16);
            newMesh.createVertex( 270.00,  384.00,  5.00,17);
            newMesh.createVertex(-270.00,  384.00,  5.00,18);
            newMesh.createVertex(-290.00,  375.00,  5.00,19);
            newMesh.createVertex(-300.00,  354.00,  5.00,20);
            newMesh.createVertex(-300.00, -354.00,  5.00,21);
            newMesh.createVertex(-290.00, -375.00,  5.00,22);
            newMesh.createVertex(-270.00, -384.00,  5.00,23);
            newMesh.createVertex( 270.00, -384.00,  5.00,24);
            newMesh.createVertex( 290.00, -375.00,  5.00,25);
            newMesh.createVertex( 300.00, -354.00,  5.00,26);
            newMesh.createVertex( 300.00,  354.00,  5.00,27);

            newMesh.createVertex( 270.00,  354.00, 25.00,28);
            newMesh.createVertex(-270.00,  354.00, 25.00,29);
            newMesh.createVertex(-270.00, -354.00, 25.00,30);
            newMesh.createVertex( 270.00, -354.00, 25.00,31);

            newMesh.createVertex( 191.00,  260.00, 59.50,32);
            newMesh.createVertex(-191.00,  260.00, 59.50,33);
            newMesh.createVertex(-191.00, -260.00, 59.50,34);
            newMesh.createVertex( 191.00, -260.00, 59.50,35);

            newMesh.createVertex(  93.00,  140.00, 73.99,36);
            newMesh.createVertex( -93.00,  140.00, 73.99,37);
            newMesh.createVertex( -93.00, -140.00, 73.99,38);
            newMesh.createVertex(  93.00, -140.00, 73.99,39);



            var textureW:Number=600;
            var textureH:Number=768;

            var facesArray:Array=[]

            //正面
            facesArray=[];
            setFaceAndUv([ 1, 0, 3, 2],textureW,textureH,'front_0','xy',true);
            setFaceAndUv([ 0,11, 4, 3],textureW,textureH,'front_1','xy',true);
            setFaceAndUv([11,10, 5, 4],textureW,textureH,'front_2','xy',true);
            setFaceAndUv([10, 9, 6, 5],textureW,textureH,'front_3','xy',true);
            setFaceAndUv([ 9, 8, 7, 6],textureW,textureH,'front_4','xy',true);
            newMesh.createSurface(facesArray,'front')


            //裏
            facesArray=[];
            setFaceAndUv([37,38,39,36],textureW,textureH,'back_0');
            setFaceAndUv([33,37,36,32],textureW,textureH,'back_1');
            setFaceAndUv([36,39,35,32],textureW,textureH,'back_2');
            setFaceAndUv([38,34,35,39],textureW,textureH,'back_3');
            setFaceAndUv([33,34,38,37],textureW,textureH,'back_4');

            setFaceAndUv([29,33,32,28],textureW,textureH,'back_5');
            setFaceAndUv([32,35,31,28],textureW,textureH,'back_6');
            setFaceAndUv([34,30,31,35],textureW,textureH,'back_7');
            setFaceAndUv([29,30,34,33],textureW,textureH,'back_8');

            setFaceAndUv([18,29,28,17],textureW,textureH,'back_9');
            setFaceAndUv([28,31,26,27],textureW,textureH,'back_10');
            setFaceAndUv([30,23,24,31],textureW,textureH,'back_11');
            setFaceAndUv([20,21,30,29],textureW,textureH,'back_12');
            setFaceAndUv([16,17,28],textureW,textureH,'back_13');
            setFaceAndUv([16,28,27],textureW,textureH,'back_14');
            setFaceAndUv([18,19,29],textureW,textureH,'back_15');
            setFaceAndUv([19,20,29],textureW,textureH,'back_16');
            setFaceAndUv([30,21,22],textureW,textureH,'back_17');
            setFaceAndUv([30,22,23],textureW,textureH,'back_18');
            setFaceAndUv([31,24,25],textureW,textureH,'back_19');
            setFaceAndUv([31,25,26],textureW,textureH,'back_20');

            newMesh.createSurface(facesArray,'back')


            //Side
            facesArray=[];
            setFaceAndUv([0,1,17,16],textureW,textureH,'side_0','xz');
            setFaceAndUv([1,2,18,17],textureW,textureH,'side_1','xz');
            setFaceAndUv([2,3,19,18],textureW,textureH,'side_2','xz');

            setFaceAndUv([3,4,20,19],textureW,textureH,'side_3','yz');
            setFaceAndUv([4,5,21,20],textureW,textureH,'side_4','yz');
            setFaceAndUv([5,6,22,21],textureW,textureH,'side_5','yz');

            setFaceAndUv([6,7,23,22],textureW,textureH,'side_6','yz');
            setFaceAndUv([7,8,24,23],textureW,textureH,'side_7','yz');
            setFaceAndUv([8,9,25,24],textureW,textureH,'side_8','yz');

            setFaceAndUv([9,10,26,25],textureW,textureH,'side_9','yz');
            setFaceAndUv([26,10,11,27],textureW,textureH,'side_10','yz');
            setFaceAndUv([27,11,0,16],textureW,textureH,'side_11','yz');

            newMesh.createSurface(facesArray,'side')

            function setFaceAndUv(v:Array,w:Number,h:Number,id:Object,mode:String='xy',reverse:Boolean=false):void {
                facesArray.push(id)

                newMesh.createFace(v,id);
                var pt:Array=[];
                for (var i:uint=0;i<v.length;i++) {
                    if (mode=='xz') {
                        pt.push(new Point((newMesh.vertices[v[i]].x+w/2)/w,(newMesh.vertices[v[i]].z+h/2)/h))
                    } else if (mode=='yz') {
                        pt.push(new Point((newMesh.vertices[v[i]].y+w/2)/w,(newMesh.vertices[v[i]].z+h/2)/h))
                    } else {
                        pt.push(new Point((newMesh.vertices[v[i]].x+w/2)/w,(newMesh.vertices[v[i]].y+h/2)/h))
                    }
                }
                if (reverse) {
                    newMesh.setUVsToFace(pt[3],pt[2],pt[1],id)
                } else {
                    newMesh.setUVsToFace(pt[0],pt[1],pt[2],id)
                }
            }


            newMesh.setMaterialToSurface(mcm3,'front');
            newMesh.setMaterialToSurface(mcm2,'back');
            newMesh.setMaterialToSurface(new FillMaterial(0xE0E0E0),'side');

            newMesh.rotationY = 180 * Math.PI / 180;
            newMesh.rotationZ = 180 * Math.PI / 180;

            template.scene.root.addChild(newMesh);


            var me:Sprite=this;
            var dragFlag:Boolean=false
            var mouseSX:Number;
            var mouseSY:Number;
            var nowRotationX:Number;
            var nowRotationY:Number;
            
            me.stage.addEventListener(MouseEvent.MOUSE_DOWN,onDown)

            function onDown(e:MouseEvent):void {
                me.stage.removeEventListener(MouseEvent.MOUSE_DOWN,onDown);
                me.stage.addEventListener(MouseEvent.MOUSE_UP,onUp);
                mouseSX=me.mouseX
                mouseSY=me.mouseY
                nowRotationX=newMesh.rotationX
                nowRotationY=newMesh.rotationY
                    
                dragFlag=true
            }

            function onUp(e:MouseEvent):void {
                me.stage.addEventListener(MouseEvent.MOUSE_DOWN,onDown);
                me.stage.removeEventListener(MouseEvent.MOUSE_UP,onUp);
                dragFlag=false
    
            }


            Thread.initialize(new EnterFrameThreadExecutor());
            new MainThread(this).start();


            template.onPreRender = function():void {
                if (dragFlag) {
                    newMesh.rotationY=nowRotationY+(mouseSX-mouseX)/-2 * Math.PI / 180;
                    newMesh.rotationX=nowRotationX+(mouseSY-mouseY)/2 * Math.PI / 180;
                }
            
            }
        }


        public function drawImage(bmd:BitmapData):void {
            bmd3.draw(bmd)
            mcm3=new TextureEnvironmentMaterial(new Texture(bmd3), new Texture(bmd1),0.2,1.0,true,true)
            newMesh.setMaterialToSurface(mcm3,'front');
        }



    }
}






import org.libspark.thread.Thread;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.SimpleButton;
import flash.utils.ByteArray; 
import flash.net.FileReference;
import flash.net.FileReferenceList;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.display.*;
import flash.text.*;
import flash.system.Security;

class MainThread extends Thread {
    public static const CROSSDOMAIN:String = "http://assets.wonderfl.net/crossdomain.xml";
    private var _base:SimpleDemo;
    private var _loadButton:Button;
    private var _saveButton:Button;
    private var _original:Loader;
    private var _guide:Guide;

    private var bmd:BitmapData


    public function MainThread(base:SimpleDemo) {
        this._base = base;

        this._loadButton = this._base.addChild(new Button('LOAD', 60)) as Button;
        this._loadButton.x = this._loadButton.y = 1;
        this._saveButton = this._base.addChild(new Button('SAVE', 60)) as Button;
        this._saveButton.x = 1;
        this._saveButton.y = this._loadButton.height + 2;

        this._guide = this._base.addChild(new Guide()) as Guide;
        this._guide.x = this._guide.y = (465 - 360) >> 1;

        this.bmd=new BitmapData(200,160,false,0x308CCB)

    }

    protected override function run():void {
        this._event();
    }

    



    private function _event():void {
        event(this._loadButton, MouseEvent.CLICK, this._loadImage);
        event(this._saveButton, MouseEvent.CLICK, this._saveImage);
        Security.loadPolicyFile(CROSSDOMAIN);
    }

    // load image
    private function _loadImage(e:MouseEvent):void {
        trace(Button(e.target).label)
        var file:FileReference = new FileReference();
        event(file, Event.SELECT, this._loadFileSelected);
        event(file, Event.CANCEL, this._loadFileCancel);
        file.browse();
    }

    private function _loadFileSelected(e:Event):void {
        var file:FileReference = FileReference(e.target);
        event(file, Event.COMPLETE, this._fileLoaded);
        file.load();
    }
    
    private function _fileLoaded(e:Event):void {
        if (this._original) {
            //this._original.parent.removeChild(this._original);
            this._original.unload();
        }
        this._original = new Loader();
        this._original.loadBytes(FileReference(e.target).data);
        event(this._original.contentLoaderInfo, Event.COMPLETE, this._imageLoaded);
    }

    private function _loadFileCancel(e:Event):void {
        this._event();
    }

    
    private function _imageLoaded(e:Event):void {
        var a:Number = 159 / this._original.width;
        var b:Number = 164 / this._original.height;
        var mtr:Matrix=new Matrix(a,0,0,b,21,17)

        this.bmd=new BitmapData(200,200,true,0x00000000)
        this.bmd.draw(this._original.content,mtr)
        this._base.drawImage(bmd)

        this._event();
    }
    

    // save image 
    private function _saveImage(e:Event):void { 
        var raw:BitmapData = new BitmapData(360, 360, true, 0x0); 
        this._guide.visible = false;
        raw.draw(this._base, new Matrix(1, 0, 0, 1, -this._guide.x, -this._guide.y), null, null, null, true);
        this._guide.visible = true;
        var png:ByteArray = PNGEnc.encode(raw); 
        raw.dispose(); 
        var file:FileReference = new FileReference(); 
        event(file, Event.SELECT, this._saveFileSelected); 
        event(file, Event.CANCEL, this._saveFileSelected);
        file.save(png, 'noflash.png'); 
    }

    private function _saveFileSelected(e:Event):void { 
        this._event();
    } 

}

class Guide extends Shape {
    
    public function Guide() {
        var g:Graphics = this.graphics;
        g.lineStyle(1, 0xFF0000, 0.3, true);
        g.drawRect(0, 0, 360, 360);
    }
}



class Button extends SimpleButton {
    public var label:String

    public function Button(_label:String, width:int = 0):void {
        label=_label
        var up:Sprite = _buildImage(label, 0x0, width);
        var over:Sprite = _buildImage(label, 0x333333, width);
        var down:Sprite = _buildImage(label, 0x333333, width);
        down.y = 1;
        super(up, over, down, up);
    }
    
    private static function _buildImage(label:String, color:int, width:int = 0):Sprite {
        var text:TextField = new TextField();
        text.defaultTextFormat = new TextFormat('Verdana', 10, 0xffffff, true, null, null, null, null, TextFormatAlign.CENTER);
        text.autoSize = TextFieldAutoSize.LEFT
        text.selectable = false;
        text.text = label;
        text.x = (width - text.width) >> 1;
        text.y = 5;
        var base:Shape = new Shape();
        var g:Graphics = base.graphics;
        g.beginFill(color);
        g.drawRect(0, 0, width, text.height + 10);
        g.endFill();
        var sp:Sprite = new Sprite();
        sp.addChild(base);
        sp.addChild(text);
        return sp;
    }
}









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;


/**
 * BasicTemplate for Alternativa3D
 * Alternativa3Dを扱いやすくするためのテンプレートです
 * @author Yasu
 */
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 {
        atPostRender();
        _onPostRender();
        scene.calculate();
        atPreRender();
        _onPreRender();
    }
    
    /**
     * @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;
        }
    }
}







import alternativ5.engine3d.alternativa3d;
import alternativ5.engine3d.core.Camera3D;
import alternativ5.engine3d.core.PolyPrimitive;
import alternativ5.engine3d.display.Skin;
import alternativ5.engine3d.materials.DrawPoint;
import alternativ5.engine3d.materials.Material;
import alternativ5.engine3d.materials.TextureMaterial;
import alternativ5.engine3d.materials.TextureMaterialPrecision;
import alternativ5.types.Matrix3D;
import alternativ5.types.Point3D;
import alternativ5.types.Texture;
import alternativ5.types.alternativatypes;
import alternativ5.utils.MathUtils;

import flash.display.BlendMode;
import flash.display.Graphics;
import flash.display.Shape;
import flash.geom.Matrix;

use namespace alternativatypes;
use namespace alternativa3d;

class TextureEnvironmentMaterial extends TextureMaterial {

    private static const reflectionMatrix:Matrix = new Matrix();
    private static var shapes:Array = new Array();

    private var _reflection:Texture;
    private var _reflectionBlendMode:String;
    private var _reflectiveness:Number;

    private var gfx:Graphics;

    public function TextureEnvironmentMaterial(texture:Texture = null, reflection:Texture = null, reflectiveness:Number = 1.0, alpha:Number = 1.0, repeat:Boolean = false, smooth:Boolean = false, blendMode:String = BlendMode.NORMAL, precision:Number = TextureMaterialPrecision.MEDIUM, reflectionBlendMode:String = BlendMode.NORMAL) {
        super(texture, alpha, repeat, smooth, blendMode, -1, 0, precision);
         _reflection = reflection;
         _reflectiveness = reflectiveness;
         _reflectionBlendMode = reflectionBlendMode;
    }

    override alternativa3d function canDraw(primitive:PolyPrimitive):Boolean {
        return _reflection != null || _texture != null;
    }

    override alternativa3d function clear(skin:Skin):void {
        skin.gfx.clear();
        var count:int = skin.numChildren;
        for (var i:int = 0; i < count; i++) {
            var shape:Shape = skin.removeChildAt(0) as Shape;
            shape.graphics.clear();
            shapes.push(shape);
        }
    }

    /**
     * @private
     * @inheritDoc
     */
    override alternativa3d function draw(camera:Camera3D, skin:Skin, length:uint, points:Array):void {
        if (_reflectiveness < 1) {
            super.draw(camera, skin, length, points);
        }
        if (_reflectiveness > 0) {
            var gfx:Graphics;
            if (_reflectiveness < 1) {
                var shape:Shape = shapes.pop();
                if (shape == null) {
                    shape = new Shape();
                }
                skin.addChild(shape);
                gfx = shape.graphics;
                shape.alpha = _reflectiveness;
                shape.blendMode = _reflectionBlendMode;
            } else {
                skin.alpha = _reflectiveness;
                skin.blendMode = _blendMode;
                gfx = skin.gfx;
            }

            var cameraMatrix:Matrix3D = camera.cameraMatrix;

            var normal:Point3D = skin.primitive.face.globalNormal;
            var normalInCamX:Number = normal.x*cameraMatrix.a + normal.y*cameraMatrix.b + normal.z*cameraMatrix.c;
            var normalInCamY:Number = normal.x*cameraMatrix.e + normal.y*cameraMatrix.f + normal.z*cameraMatrix.g;
            var normalInCamZ:Number = normal.x*cameraMatrix.i + normal.y*cameraMatrix.j + normal.z*cameraMatrix.k;

            var focalLength:Number = camera.focalLength;

            var apoint:DrawPoint = points[0];
            var bpoint:DrawPoint = points[1];
            var cpoint:DrawPoint = points[2];
            var ax:Number = apoint.x*focalLength/apoint.z;
            var ay:Number = apoint.y*focalLength/apoint.z;
            var bx:Number = bpoint.x*focalLength/bpoint.z;
            var by:Number = bpoint.y*focalLength/bpoint.z;
            var cx:Number;
            var cy:Number;

            var vx:Number;
            var vy:Number;
            var vz:Number;
            var rx:Number;
            var ry:Number;
            var rz:Number;
            var nx:Number;
            var ny:Number;
            var nz:Number;
            var dot:Number;
            var len:Number;
            var aN:Boolean;
            var bN:Boolean;
            var cN:Boolean;

            vx = apoint.x;
            vy = apoint.y;
            vz = apoint.z;

            dot = vx*normalInCamX + vy*normalInCamY + vz*normalInCamZ;
            rx = vx - 2*dot*normalInCamX;
            ry = vy - 2*dot*normalInCamY;
            rz = vz - 2*dot*normalInCamZ;
            len = Math.sqrt(rx*rx + ry*ry + rz*rz);
            nx = rx*0.5;
            ny = ry*0.5;
            nz = (rz - len)*0.5;
            len = Math.sqrt(nx*nx + ny*ny + nz*nz);
            nx /= len;
            ny /= len;

            aN = (nz > 0);

            var au:Number = 0.5 + nx*0.5;
            var av:Number = 0.5 - ny*0.5;

            vx = bpoint.x;
            vy = bpoint.y;
            vz = bpoint.z;

            dot = vx*normalInCamX + vy*normalInCamY + vz*normalInCamZ;
            rx = vx - 2*dot*normalInCamX;
            ry = vy - 2*dot*normalInCamY;
            rz = vz - 2*dot*normalInCamZ;
            len = Math.sqrt(rx*rx + ry*ry + rz*rz);
            nx = rx*0.5;
            ny = ry*0.5;
            nz = (rz - len)*0.5;
            len = Math.sqrt(nx*nx + ny*ny + nz*nz);
            nx /= len;
            ny /= len;

            bN = (nz > 0);

            var bu:Number = 0.5 + nx*0.5;
            var bv:Number = 0.5 - ny*0.5;


            for (var i:int = 1; i < length; i++) {
                cpoint = points[i];
                cx = cpoint.x*focalLength/cpoint.z;
                cy = cpoint.y*focalLength/cpoint.z;

                vx = cpoint.x;
                vy = cpoint.y;
                vz = cpoint.z;

                dot = vx*normalInCamX + vy*normalInCamY + vz*normalInCamZ;
                rx = vx - 2*dot*normalInCamX;
                ry = vy - 2*dot*normalInCamY;
                rz = vz - 2*dot*normalInCamZ;
                len = Math.sqrt(rx*rx + ry*ry + rz*rz);
                nx = rx*0.5;
                ny = ry*0.5;
                nz = (rz - len)*0.5;
                len = Math.sqrt(nx*nx + ny*ny + nz*nz);
                nx /= len;
                ny /= len;

                cN = (nz > 0);

                var cu:Number = 0.5 + nx*0.5;
                var cv:Number = 0.5 - ny*0.5;

                var abx:Number = bx - ax;
                var aby:Number = by - ay;
                var acx:Number = cx - ax;
                var acy:Number = cy - ay;
                var abu:Number = bu - au;
                var abv:Number = bv - av;
                var acu:Number = cu - au;
                var acv:Number = cv - av;
                var det:Number = abu*acv - abv*acu;
                var w:Number = _reflection._width;
                var h:Number = _reflection._height;

                reflectionMatrix.a = (acv*abx - abv*acx)/det;
                reflectionMatrix.b = (acv*aby - abv*acy)/det;
                reflectionMatrix.c = (acu*abx - abu*acx)/det;
                reflectionMatrix.d = (acu*aby - abu*acy)/det;
                reflectionMatrix.tx = (av - 1)*reflectionMatrix.c - au*reflectionMatrix.a + ax;
                reflectionMatrix.ty = (av - 1)*reflectionMatrix.d - au*reflectionMatrix.b + ay;

                reflectionMatrix.a /= w;
                reflectionMatrix.b /= w;
                reflectionMatrix.c /= h;
                reflectionMatrix.d /= h;

                gfx.beginBitmapFill(_reflection._bitmapData, reflectionMatrix, true, true);
                gfx.moveTo(ax, ay);
                gfx.lineTo(bx, by);
                gfx.lineTo(cx, cy);
                
                bx = cx;
                by = cy;
                bu = cu;
                bv = cv;
            }
        }
    }

    private function lookAtMatrix(dx:Number, dy:Number, dz:Number):Matrix3D {
        return Matrix3D.rotationMatrix(Math.atan2(dz, Math.sqrt(dx * dx + dy * dy) - MathUtils.DEG90), 0, -Math.atan2(dx, dy));
    }

    /**
     * @private
     */
    private function drawTriangle(ax:Number, ay:Number, au:Number, av:Number, bx:Number, by:Number, bu:Number, bv:Number, cx:Number, cy:Number, cu:Number, cv:Number):void {
        var abx:Number = bx - ax;
        var aby:Number = by - ay;
        var acx:Number = cx - ax;
        var acy:Number = cy - ay;
        var abu:Number = bu - au;
        var abv:Number = bv - av;
        var acu:Number = cu - au;
        var acv:Number = cv - av;
        var det:Number = abu*acv - abv*acu;
        var w:Number = _reflection._width;
        var h:Number = _reflection._height;

        reflectionMatrix.a = (acv*abx - abv*acx)/det;
        reflectionMatrix.b = (acv*aby - abv*acy)/det;
        reflectionMatrix.c = (acu*abx - abu*acx)/det;
        reflectionMatrix.d = (acu*aby - abu*acy)/det;
        reflectionMatrix.tx = (av - 1)*reflectionMatrix.c - au*reflectionMatrix.a + ax;
        reflectionMatrix.ty = (av - 1)*reflectionMatrix.d - au*reflectionMatrix.b + ay;

        reflectionMatrix.a /= w;
        reflectionMatrix.b /= w;
        reflectionMatrix.c /= h;
        reflectionMatrix.d /= h;

        gfx.beginBitmapFill(_reflection._bitmapData, reflectionMatrix, true, true);
        gfx.moveTo(ax, ay);
        gfx.lineTo(bx, by);
        gfx.lineTo(cx, cy);
    }

    /**
     * @inheritDoc
     */        
    override public function clone():Material {
        var res:TextureEnvironmentMaterial = new TextureEnvironmentMaterial(_texture, _reflection, _reflectiveness, _alpha, _repeat, _smooth, _blendMode, _precision); 
        return res;
    }

}


// http://www.5etdemi.com/blog/archives/2006/12/as3-png-encoder-faster-better/ 

class PNGEnc { 
         
        public static function encode(img:BitmapData, type:uint = 0):ByteArray { 
                 
                // Create output byte array 
                var png:ByteArray = new ByteArray(); 
                // Write PNG signature 
                png.writeUnsignedInt(0x89504e47); 
                png.writeUnsignedInt(0x0D0A1A0A); 
                // Build IHDR chunk 
                var IHDR:ByteArray = new ByteArray(); 
                IHDR.writeInt(img.width); 
                IHDR.writeInt(img.height); 
                if(img.transparent || type == 0) 
                { 
                        IHDR.writeUnsignedInt(0x08060000); // 32bit RGBA 
                } 
                else 
                { 
                        IHDR.writeUnsignedInt(0x08020000); //24bit RGB 
                } 
                IHDR.writeByte(0); 
                writeChunk(png,0x49484452,IHDR); 
                // Build IDAT chunk 
                var IDAT:ByteArray= new ByteArray(); 
                 
                switch(type) 
                { 
                        case 0: 
                                writeRaw(img, IDAT); 
                                break; 
                        case 1: 
                                writeSub(img, IDAT); 
                                break; 
                } 
                 
                IDAT.compress(); 
                writeChunk(png,0x49444154,IDAT); 
                // Build IEND chunk 
                writeChunk(png,0x49454E44,null); 
                // return PNG 
                 
                 
                 
                return png; 
        } 
         
        private static function writeRaw(img:BitmapData, IDAT:ByteArray):void 
        { 
                var h:int = img.height; 
                var w:int = img.width; 
                var transparent:Boolean = img.transparent; 
                 
                for(var i:int=0;i < h;i++) { 
                        // no filter 
                        if ( !transparent ) { 
                                var subImage:ByteArray = img.getPixels( 
                                        new Rectangle(0, i, w, 1)); 
                                //Here we overwrite the alpha value of the first pixel 
                                //to be the filter 0 flag 
                                subImage[0] = 0; 
                                IDAT.writeBytes(subImage); 
                                //And we add a byte at the end to wrap the alpha values 
                                IDAT.writeByte(0xff); 
                        } else { 
                                IDAT.writeByte(0); 
                                var p:uint; 
                                for(var j:int=0;j < w;j++) { 
                                        p = img.getPixel32(j,i); 
                                        IDAT.writeUnsignedInt( 
                                                uint(((p&0xFFFFFF) << 8)| 
                                                (p>>>24))); 
                                } 
                        } 
                } 
        } 
         
        private static function writeSub(img:BitmapData, IDAT:ByteArray):void 
        { 
                var r1:uint; 
                var g1:uint; 
                var b1:uint; 
                var a1:uint; 
                 
                var r2:uint; 
                var g2:uint; 
                var b2:uint; 
                var a2:uint; 
                 
                var r3:uint; 
                var g3:uint; 
                var b3:uint; 
                var a3:uint; 
                 
                var p:uint; 
                var h:int = img.height; 
                var w:int = img.width; 
                 
                for(var i:int=0;i < h;i++) { 
                        // no filter 
                        IDAT.writeByte(1); 
                        if ( !img.transparent ) { 
                                r1 = 0; 
                                g1 = 0; 
                                b1 = 0; 
                                a1 = 0xff; 
                                for(var j:int=0;j < w;j++) { 
                                        p = img.getPixel(j,i); 
                                         
                                        r2 = p >> 16 & 0xff; 
                                        g2 = p >> 8  & 0xff; 
                                        b2 = p & 0xff; 
                                         
                                        r3 = (r2 - r1 + 256) & 0xff; 
                                        g3 = (g2 - g1 + 256) & 0xff; 
                                        b3 = (b2 - b1 + 256) & 0xff; 
                                         
                                        IDAT.writeByte(r3); 
                                        IDAT.writeByte(g3); 
                                        IDAT.writeByte(b3); 
                                         
                                        r1 = r2; 
                                        g1 = g2; 
                                        b1 = b2; 
                                        a1 = 0; 
                                } 
                        } else { 
                                r1 = 0; 
                                g1 = 0; 
                                b1 = 0; 
                                a1 = 0; 
                                for(j=0;j < w;j++) { 
                                        p = img.getPixel32(j,i); 
                                         
                                        a2 = p >> 24 & 0xff; 
                                        r2 = p >> 16 & 0xff; 
                                        g2 = p >> 8  & 0xff; 
                                        b2 = p & 0xff; 
                                         
                                        r3 = (r2 - r1 + 256) & 0xff; 
                                        g3 = (g2 - g1 + 256) & 0xff; 
                                        b3 = (b2 - b1 + 256) & 0xff; 
                                        a3 = (a2 - a1 + 256) & 0xff; 
                                         
                                        IDAT.writeByte(r3); 
                                        IDAT.writeByte(g3); 
                                        IDAT.writeByte(b3); 
                                        IDAT.writeByte(a3); 
                                         
                                        r1 = r2; 
                                        g1 = g2; 
                                        b1 = b2; 
                                        a1 = a2; 
                                } 
                        } 
                } 
        } 

        private static var crcTable:Array; 
        private static var crcTableComputed:Boolean = false; 

        private static function writeChunk(png:ByteArray,  
                        type:uint, data:ByteArray):void { 
                var c:uint; 
                if (!crcTableComputed) { 
                        crcTableComputed = true; 
                        crcTable = []; 
                        for (var n:uint = 0; n < 256; n++) { 
                                c = n; 
                                for (var k:uint = 0; k < 8; k++) { 
                                        if (c & 1) { 
                                                c = uint(uint(0xedb88320) ^  
                                                        uint(c >>> 1)); 
                                        } else { 
                                                c = uint(c >>> 1); 
                                        } 
                                } 
                                crcTable[n] = c; 
                        } 
                } 
                var len:uint = 0; 
                if (data != null) { 
                        len = data.length; 
                } 
                png.writeUnsignedInt(len); 
                var p:uint = png.position; 
                png.writeUnsignedInt(type); 
                if ( data != null ) { 
                        png.writeBytes(data); 
                } 
                var e:uint = png.position; 
                png.position = p; 
                c = 0xffffffff; 
                for (var i:int = 0; i < (e-p); i++) { 
                        c = uint(crcTable[ 
                                (c ^ png.readUnsignedByte()) &    
                                0xff] ^ (c >>> 8)); 
                } 
                c = uint(c^uint(0xffffffff)); 
                png.position = e; 
                png.writeUnsignedInt(c); 
        } 
}