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

クォータニオンカメラにイージング

クォータニオンカメラにイージング
参考:http://wonderfl.net/code/4747cd77837f2d8b9db08dce4e7cf5f269e165aa
Get Adobe Flash player
by Nyarineko 04 Feb 2016
/**
 * Copyright Nyarineko ( http://wonderfl.net/user/Nyarineko )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/AcF5
 */

//クォータニオンカメラにイージング
//参考:http://wonderfl.net/code/4747cd77837f2d8b9db08dce4e7cf5f269e165aa
package{
    import flash.display.*;
    import flash.events.*;
    import flash.utils.*;
    import flash.filters.*;
    import flash.geom.*;
    import org.papervision3d.view.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.core.math.*;
    import org.papervision3d.core.effects.*;
    import org.papervision3d.view.layer.BitmapEffectLayer;
    import org.papervision3d.core.effects.BitmapLayerEffect;
    
    [SWF(backgroundColor="0x000000", frameRate="60")]
    public class Silhouette extends BasicView{
        
        private var _c : SphereCamera;
        private var _bfx:BitmapEffectLayer;
        
        //コンストラクタを作成
        public function Silhouette() {
            
            //エフェクト
            _bfx = new BitmapEffectLayer(viewport, 465, 465);
            _bfx.addEffect(new BitmapLayerEffect(new BlurFilter(8, 8, 2)));
            viewport.containerSprite.addLayer(_bfx);
            
            // カメラの設定
            _camera = new SphereCamera(new Number3D(0, 0, 0), 500, new Number3D(0, 0, 1), new Number3D(0, 1, 0));
            
            //マテリアルを作成
            var matColor : ColorMaterial = new ColorMaterial( 0x0000FF ,0.1);
            var matWireA : WireframeMaterial = new WireframeMaterial(0x9999FF,0.3,2);
            var matWireB : WireframeMaterial = new WireframeMaterial(0x66ff66,0.2,1);
            //裏面表示設定
            matColor.doubleSided = true;
            matWireA.doubleSided = true;
            matWireB.doubleSided = true;
            
            //オブジェクトを作成
            var mySphere:Sphere = new Sphere(matWireB,200,8,8);
            scene.addChild( mySphere );
            
            //オブジェクトを作成
            var myCone:Cone = new Cone(matWireA,130,200,1,1);
            var myCone2:Cone = new Cone(matColor,130,200,1,1);
            myCone.y = 20;
            myCone2.y = 20;
            _bfx.addDisplayObject3D(myCone);
            scene.addChild( myCone );
            scene.addChild( myCone2 );
            
            //毎フレーム時のイベントを追加
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            // レンダリング開始
            startRendering();
            stage.addEventListener(MouseEvent.MOUSE_MOVE, evMouseMove);
            stage.addEventListener(Event.ENTER_FRAME, onFrame);
            
            // 毎フレーム時のアニメーション
            function enterFrameHandler(event:Event):void
            {
                //円錐を横回転
                myCone.rotationX += .5;
                myCone2.rotationX += .5;
                myCone.rotationY += 1;
                myCone2.rotationY += 1;
            }
        }
        
        private var _prevX : Number = 0;
        private var _prevY : Number = 0; 
        private var _accelerationX : Number = 0;
        private var _accelerationY : Number = 0;
        private var EASING : Number = 16;
        
        private function onFrame(event:Event):void
        {
            //カメラの移動
            var sc : SphereCamera = SphereCamera(_camera);
            sc.move(_accelerationX,_accelerationY);
            _accelerationX = _accelerationX - _accelerationX / EASING;
            _accelerationY = _accelerationY - _accelerationY / EASING;
        }
        // マウスを移動したときの動作
        private function evMouseMove(e : MouseEvent) : void
        {
            if(e.buttonDown){
                // ボタンをおしている状態のときのみカメラを移動
                if(_prevX != 0 && _prevY != 0){
                    _accelerationX = (stage.mouseX - _prevX) * 0.005;
                    _accelerationY = (stage.mouseY - _prevY) * 0.005;
                }
                _prevX = stage.mouseX;
                _prevY = stage.mouseY;
            }else{
                _prevX = 0;
                _prevY = 0;
            }
        }
    }
} 

import org.papervision3d.core.math.*;
import org.papervision3d.objects.*;
import org.papervision3d.cameras.*;

// 球面上を動き、球の中心を見るカメラ
class SphereCamera extends Camera3D
{
    private var _O : DisplayObject3D; // 球の中心
    public var _front : Number3D; // カメラの前の向きの単位ベクトル
    public var _up : Number3D; // カメラの上の向きの単位ベクトル
    private var _R : Number; // 球の半径
    
    public function SphereCamera(O : Number3D, R : Number, front : Number3D, up : Number3D) : void
    {
        _O = new DisplayObject3D();
        _O.x = O.x;
        _O.y = O.y;
        _O.z = O.z;
        _R = R;
        _front = front.clone();
        _front.normalize();
        _up = up.clone();
        _up.normalize();
        
        update1();
    }
    
    // カメラの右方向へx[rad], 上方向へy[rad]回転させる
    public function move(x : Number, y : Number) : void
    {
        // X方向の移動
        _front = applyQuaternion([_front], _up, -x)[0];
        
        // Y方向の移動
        var right : Number3D = Number3D.cross(_up, _front);
        right.normalize();
        var ret : Array = applyQuaternion([_front, _up], right, y);
        _front = ret[0];
        _up = ret[1];
        
        update1();
    }
    
    private function update1() : void
    {
        this.x = _front.x * -_R + _O.x;
        this.y = _front.y * -_R + _O.y;
        this.z = _front.z * -_R + _O.z;
        this.lookAt(_O, _up);
    }
    
    // axisを軸にangle回転させる変換を、srcsの要素それぞれに適用する。
    public static function applyQuaternion(srcs : Array, axis : Number3D, angle : Number) : Array
    {
        var q : Quaternion = Quaternion.createFromAxisAngle(
            axis.x / axis.modulo, 
            axis.y / axis.modulo, 
            axis.z / axis.modulo,
            angle
            );
        var qc : Quaternion = Quaternion.conjugate(q);
        
        var ret : Array = [];
        for each(var src : Number3D in srcs){
            var qSrc : Quaternion = new Quaternion(src.x, src.y, src.z, 0);
            var qDst : Quaternion = Quaternion.multiply(qc, qSrc);
            qDst.mult(q);
            ret.push(new Number3D(qDst.x, qDst.y, qDst.z));
        }
        return ret;
    }
    
}