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

forked from: forked from: [BetweenAS3] Papervision Matrix3D Tween

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

// forked from yonatan's forked from: [BetweenAS3] Papervision Matrix3D Tween
// forked from yonatan's [BetweenAS3] Papervision Matrix3D Tween
// forked from nitoyon's [BetweenAS3] Random Text Tween
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.utils.*;
    import org.libspark.betweenas3.easing.*;
    import org.libspark.betweenas3.*;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.PaperPlane;
    import org.papervision3d.view.BasicView;
    import frocessing.color.ColorHSV;

    [SWF (backgroundColor="0xffffff")]

    public class FlashTest extends BasicView {
        public function FlashTest() {
            _camera.zoom = 30;

            var light:PointLight3D;
            light = new PointLight3D(false);
            light.y = 1000;

            var planes:Array = [];
            for(var i:uint=0; i < 64; i++) {
                var hsv:ColorHSV = new ColorHSV(i*4, 0.9, 0.8);
                var mat:FlatShadeMaterial = new FlatShadeMaterial(light, hsv.value32);
                mat.doubleSided = true;
                var p:PaperPlane = new PaperPlane(mat);
                scene.addChild(p);
                planes.push(p);
            }

            function doTweens():void {
                var sx:Number = Math.random()*3;
                var sy:Number = Math.random()*3;
                var sz:Number = Math.random()*2;
                var yaw:Number = Math.random()*1000;
                var pitch:Number = Math.random()*1200;
                var dist:Number = Math.random()*500 + 250;
                var lookAt0:Boolean = Math.random() < 0.5;

                for(var i:uint=0; i < planes.length; i++) {
                    var n:Number = i/planes.length - 0.5;

                    var dst:DisplayObject3D = new DisplayObject3D;
                    dst.yaw(yaw-yaw*n);
                    dst.pitch(pitch-pitch*n);
                    dst.moveForward(dist);
                    dst.scaleX = sx;
                    dst.scaleY = sy;
                    dst.scaleZ = sz;
                    if(lookAt0) {
                        dst.lookAt(DisplayObject3D.ZERO);
                    }
                    dst.copyTransform(dst);

                    var tween:PVMatrixTween = new PVMatrixTween();
                    tween.target = planes[i];
                    tween.easing = Sine.easeOut;
                    tween.matrix = dst.transform;
                    tween.time = 1;
                    BetweenAS3.delay(tween, Math.abs(i-32)*20/1000).play();
                }
            }

            setInterval(doTweens, 1750);
            addEventListener("enterFrame", function(e:*):void {
                    light.x = _camera.x = Math.sin(getTimer()/3000) * 1000;
                    light.z = _camera.z = Math.cos(getTimer()/3000) * 1000;
                });

            startRendering();
        }
    }
}

import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.core.easing.IEasing;
import org.libspark.betweenas3.core.ticker.ITicker;
import org.libspark.betweenas3.core.tweens.AbstractTween;
import org.libspark.betweenas3.core.tweens.IITween;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.core.math.Quaternion;
import org.papervision3d.objects.DisplayObject3D;

class PVMatrixTween extends AbstractTween
{
    /**
    * static ITicker cache.
    */
    private static var _ticker:ITicker;

    /**
    * initial Matrix3D storage.
    */
    private var _start:Matrix3D;

    /**
    * DisplayObject3D.
    */
    public function get target():DisplayObject3D { return _target; }
    public function set target(value:DisplayObject3D):void {
        value.copyTransform(value); // hack -- make sure the do3d's transform is up to date.
        _start = Matrix3D.clone(value.transform);
        _target = value;
    }
    private var _target:DisplayObject3D;

    /**
    * Tween easing.
    */
    public function get easing():IEasing { return _easing; }
    public function set easing(value:IEasing):void { _easing = value; }
    private var _easing:IEasing;

    /**
    * Destination transform matrix.
    */
    public function get matrix():Matrix3D { return _matrix; }
    public function set matrix(value:Matrix3D):void { _matrix = value; }
    private var _matrix:Matrix3D;

    /**
    * Set or get duration.
    */
    public function get time():Number { return _duration; }
    public function set time(value:Number):void { _duration = value; }

    /**
    * Constructor.
    *
    * @param duration sleep duration.
    * @param ticker   ticker object.
    * @param position initial position.
    */
    public function PVMatrixTween(ticker:ITicker = null, position:Number = 0) {
        if (!_ticker) {
            // create tmp tween to get the BetweenAS3's static ticker.
            var tmpTween:IITween = BetweenAS3.parallel() as IITween;
            _ticker = tmpTween.ticker;
        }

        super(ticker || _ticker, position);
    }

    /**
    * 更新処理を行う。
    */
    protected override function internalUpdate(time:Number):void
    {
        // check
        if (!_target) { throw new Error("target is not set"); }
        if (!_easing) { throw new Error("easing is not set"); }
        if (!_matrix) { throw new Error("matrix is not set"); }

        // get the factor (0.0~1.0)
        var factor:Number = 0.0;
        if (time > 0.0) {
            if (time < _duration) {
                factor = _easing.calculate(time, 0.0, 1.0, _duration);
            }
            else {
                factor = 1.0;
            }
        }

        // update the matrix
        _target.copyTransform(interpolateMatrix3D(_start, _matrix, factor));
    }

    /**
    * 3D utils 
    */

    private function interpolateMatrix3D(thisMat:Matrix3D,toMat:Matrix3D,percent:Number):Matrix3D{
        // decomposition:
        
        // we need to give Quaternion.createFromMatrix rotation-only matrices (with normalized axii), 
        // otherwise we choke on scaling matrices
        
        var thisQuat:Quaternion = Quaternion.createFromMatrix( getRotationMatrix( thisMat ) );
        var toQuat:Quaternion = Quaternion.createFromMatrix( getRotationMatrix( toMat ) );
        
        var thisScale:Number3D = getScaleFromMatrix3D( thisMat );
        var toScale:Number3D = getScaleFromMatrix3D( toMat );
        
        var thisTranslation:Number3D = new Number3D( thisMat.n14, thisMat.n24, thisMat.n34 );
        var toTranslation:Number3D = new Number3D( toMat.n14, toMat.n24, toMat.n34 );
        
        // interpolation:
        
        var scale_x:Number = thisScale.x*(1-percent) + toScale.x*percent;
        var scale_y:Number = thisScale.y*(1-percent) + toScale.y*percent;
        var scale_z:Number = thisScale.z*(1-percent) + toScale.z*percent;
        
        var tx:Number = thisTranslation.x*(1-percent) + toTranslation.x*percent;
        var ty:Number = thisTranslation.y*(1-percent) + toTranslation.y*percent;
        var tz:Number = thisTranslation.z*(1-percent) + toTranslation.z*percent;

        var q:Quaternion = Quaternion.slerp( thisQuat, toQuat, percent );

        // recomposition:

        var x:Number = q.x;
        var y:Number = q.y;
        var z:Number = q.z;
        var w:Number = q.w;
        
        var ret:Matrix3D = new Matrix3D;

        // apparently mxmlc optimizes away the duplicate multiplications, 
        // so there's no need to do it manually
        ret.n11 = (1-2*y*y-2*z*z)*scale_x;
        ret.n21 = (2*x*y+2*w*z)*scale_x;
        ret.n31 = (2*x*z-2*w*y)*scale_x;
        ret.n41 = 0;
        ret.n12 = (2*x*y-2*w*z)*scale_y;
        ret.n22 = (1-2*x*x-2*z*z)*scale_y;
        ret.n32 = (2*y*z+2*w*x)*scale_y;
        ret.n42 = 0;
        ret.n13 = (2*x*z+2*w*y)*scale_z;
        ret.n23 = (2*y*z-2*w*x)*scale_z;
        ret.n33 = (1-2*x*x-2*y*y)*scale_z;
        ret.n43 = 0;
        ret.n14 = tx;
        ret.n24 = ty;
        ret.n34 = tz;
        ret.n44 = 1;
        
        return ret;
    }
    
    // scale values can't be negative!
    private function getScaleFromMatrix3D( m:Matrix3D ):Number3D {
        var x:Number = Math.sqrt( m.n11*m.n11 + m.n21*m.n21 + m.n31*m.n31 );
        var y:Number = Math.sqrt( m.n12*m.n12 + m.n22*m.n22 + m.n32*m.n32 );
        var z:Number = Math.sqrt( m.n13*m.n13 + m.n23*m.n23 + m.n33*m.n33 );
        return( new Number3D( x, y, z ) );
    }

    // returns a rotation-only matrix (no scale/translate)
    private function getRotationMatrix( m:Matrix3D ):Matrix3D {
        var scale:Number3D = getScaleFromMatrix3D( m );
        return( new Matrix3D ( [
                    m.n11 / scale.x, m.n12 / scale.y, m.n13 / scale.z, 0,
                    m.n21 / scale.x, m.n22 / scale.y, m.n23 / scale.z, 0,
                    m.n31 / scale.x, m.n32 / scale.y, m.n33 / scale.z, 0,
                    0, 0, 0, 1 
                ] ) );
    }
}