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

forked from: Ribbon?

行列でやってみた
// forked from HaraMakoto's Ribbon?
// 行列でやってみた

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.WireframeMaterial;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.render.QuadrantRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.objects.primitives.Plane;
    [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="40")]
    
    public class RibbonRotate extends Sprite
    {
             /**
        * 3Dベース系の定義
        */ 
        private var scene:Scene3D;
        private var viewport:Viewport3D; //3Dアイテムを入れる箱
        private var renderer:BasicRenderEngine; //レンダラー
        public var camera:Camera3D; //カメラオブジェクト
        private var container:DisplayObject3D;
        private var camTarget:DisplayObject3D; //カメラターゲット
        /**
        * 3Dオブジェクトの定義
        */
        private var pEx:PlaneExt; //頭
        private var p2Ex:PlaneExt; //しっぽの頭
        private var pExArray:Array = new Array(); //PlaneChilds入れる配列

        public function RibbonRotate()
        {
            if (stage) _addStage();
            else addEventListener(Event.ADDED_TO_STAGE, _addStage);
        }
        private function _addStage(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, _addStage);
            paperDisplaySetting();
            setSphere();
            setPlanes();
            addEventListener( Event.ENTER_FRAME, _onEnterFrame ); //毎フレーム処理
        }

        private function setPlanes():void
        {
            //マテリアル
            var CM:ColorMaterial = new ColorMaterial(0xFCFCFC,1);
            CM.doubleSided = true;
            CM.oneSide = false;

            //頭
            pEx = new PlaneExt(CM,5,10);
            container.addChild( pEx );

            //しっぽの頭
            p2Ex = new PlaneExt(CM,5,10);
            p2Ex.setTargetPL( pEx );
            container.addChild( p2Ex );
            pExArray.push( p2Ex );

            //しっぽ
            for( var i:int=1;i<60; i++ )
            {
                var ppEx:PlaneExt = new PlaneExt(CM,5,10);
                ppEx.setTargetPL( pExArray[i-1] );
                container.addChild( ppEx );
                pExArray.push( ppEx );
            }
        }

        /**
        * 3Dフィールド設定
        */
        private function paperDisplaySetting():void
        {
            //ビューポート設定
            viewport = new Viewport3D(640,480,true); 
            addChild( viewport );
            //カメラ設定
            camera = new Camera3D();
            camera.z = -300;
            camera.focus = 500;
            camera.zoom = 1;
            //カメラターゲット設定
            camTarget = new DisplayObject3D();
            camera.target = camTarget;
            camTarget.x = camTarget.y = camTarget.z = 0;
            //シーン設定
            scene = new Scene3D;
            //ベース設定
            container = new DisplayObject3D();
            container.x = container.y = container.z = 0;
            scene.addChild( container );
            //レンダー設定
            renderer = new BasicRenderEngine();
        }

        /**
        * 球体配置
        */
        private function setSphere():void
        {
            var _bigSphere:Sphere = new Sphere( new WireframeMaterial(0x666666, 10),20 );
            _bigSphere.useOwnContainer = true;
            container.addChild( _bigSphere );
        }

        /**
        * 毎フレーム処理
        */
        private function _onEnterFrame( e:Event ):void
        {
            RenderingScene();
        }

        /**
        * レンダリング
        */
        private function RenderingScene():void
        {
            if( mouseX > 0 && mouseX < stage.stageWidth && mouseY > 0 && mouseY < stage.stageHeight )
            {
                var vx:Number = 0;
                vx += 0.1 * ( viewport.containerSprite.mouseX * 0.1 - vx );
                container.rotationY += vx;
                container.rotationX += 0.5 * ( viewport.containerSprite.mouseY * 0.4 - container.rotationX );
            }
            pEx._onEnterFrame(null);

            var arrNum:Number = pExArray.length;
            for( var i:int=0; i < arrNum; i++ )
            {
                pExArray[i]._onEnterFrame_child(null);
            }

            //レンダリング
            renderer.renderScene(scene,camera,viewport);
        }
    }
}


import flash.events.Event;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.core.math.Quaternion;
import org.papervision3d.core.proto.MaterialObject3D;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.objects.primitives.Sphere;

class PlaneExt extends Plane
{
    public var vx:Number=0;
    public var vy:Number=0;
    public var vz:Number=0;
    public var rx:Number;
    public var ry:Number;

    public var fx:Number=0;
    public var fy:Number=0;
    public var fz:Number=0;

    private var xLimit:Number = 100;
    private var yLimit:Number = 100;
    private var zLimit:Number = 100;

    public var ox:Number = 0;
    public var oy:Number = 0;
    public var oz:Number = 0;
    public var ovx:Number = 0;
    public var ovy:Number = 0;
    public var ovz:Number = 0;
    private var toRadian:Number = Math.PI/180;

    private var targetPlane:PlaneExt;

    public function PlaneExt( material:MaterialObject3D=null, width:Number=0, height:Number=0, segmentsW:Number=0, segmentsH:Number=0 )
    {
        super( material, width, height, segmentsW, segmentsH);
        rx = 360 * Math.random();
        ry = 360 * Math.random();

        //Planeの原点を移動
        for each(var obj_vartices:Vertex3D in this.geometry.vertices)
        {
            obj_vartices.y -= 5;
        }

    }
    public function setTargetPL(pl:PlaneExt):void
    {
        targetPlane = pl;
    }
    public function _onEnterFrame(e:Event):void
    {
        ox = fx;
        oy = fy;
        oz = fz;
        ovx = vx;
        ovy = vy;
        ovz = vz;

        rx += 10;

        vx = 8 * Math.cos(rx * toRadian);
        vy = 8 * Math.sin(rx * toRadian);
        vz = 8 * Math.cos(ry * toRadian);

        fx += vx;
        fy += vy;
        fz += vz;

        if(fx > xLimit){rx = rx + 90;}
        if(fx < -xLimit){rx = rx + 90;}

        if(fy > yLimit){rx = rx + 90;}
        if(fy < -yLimit){rx = rx + 90;}

        if(fz > zLimit){ry = ry + 90;}
        if(fz < -zLimit){ry = ry + 90;}

        setAttitude();

        this.x = fx;
        this.y = fy;
        this.z = fz;
    }

    public function _onEnterFrame_child(e:Event):void
    {
        ox = fx;
        oy = fy;
        oz = fz;
        ovx = vx;
        ovy = vy;
        ovz = vz;

        fx = targetPlane.ox;
        fy = targetPlane.oy;
        fz = targetPlane.oz;
        vx = targetPlane.ovx;
        vy = targetPlane.ovy;
        vz = targetPlane.ovz;

        setAttitude();

        this.x = fx;
        this.y = fy;
        this.z = fz;
    }
 
    public function setAttitude():void
    {
        //ある方向に向けたい軸
        var StartVec:Number3D = new Number3D( this.transform.n12, this.transform.n22, this.transform.n32 );
        
        //目標になる座標
        var TargetPoint:Number3D = new Number3D( this.vx, this.vy, this.vz );
        
        //元のベクトルを揃わせたい最終的なベクトル
        var EndVec:Number3D = Number3D.add( StartVec, TargetPoint );
        StartVec.normalize();
        EndVec.normalize();

        //2つのベクトルの法線ベクトル(回転軸)
        var vcross:Number3D = Number3D.cross( EndVec, StartVec );
        vcross.normalize();
        //2つのベクトルから回転角度(ラジアン)算出
        var rot:Number = Math.acos(Number3D.dot( StartVec, EndVec));

        //ベクトルを合わせるための回転軸と回転角から回転行列作成
        var mat:Matrix3D = Matrix3D.rotationMatrix(vcross.x, vcross.y, vcross.z, rot);
        
        //行列を適用
        this.transform = Matrix3D.multiply3x3(mat, this.transform);
    }
}