クォータニオンカメラにイージング
クォータニオンカメラにイージング
参考:http://wonderfl.net/code/4747cd77837f2d8b9db08dce4e7cf5f269e165aa
/**
* 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;
}
}