forked from: DisplayObject3D.lookAt()をQuaternion使って実装
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/tepZ
*/
// forked from uwi's DisplayObject3D.lookAt()をQuaternion使って実装
package {
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.view.BasicView;
import org.papervision3d.objects.special.*;
import org.papervision3d.materials.special.*;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.core.math.*;
import flash.text.*;
[SWF(backgroundColor="0x000000", frameRate="60")]
public class FlashTest extends BasicView {
private var _targ : Number3D;
private var _tf : TextField;
public function FlashTest() {
super(0, 0, true, false);
_tf = new TextField();
addChild(_tf);
_tf.textColor = 0xffffff;
_tf.width = 465;
_tf.height = 100;
var pf : ParticleField = new ParticleField(
new ParticleMaterial(0xffffff, 10, ParticleMaterial.SHAPE_SQUARE),
500,
1,
200, 200, 200);
scene.addChild(pf);
camera.z = -70;
_qCur = new Quaternion();
setTarg();
startRendering();
}
private function setTarg() : void
{
// 目標視線ベクトルを決める
var t : Number = Math.random() * Math.PI * 2;
var u : Number = Math.random() * Math.PI;
_targ = new Number3D(
Math.cos(t) * Math.cos(u),
Math.sin(t) * Math.cos(u),
Math.sin(u)
);
// 差をとって回転用クォータニオンを生成
var front : Number3D = applyQuaternion(FRONT, _qCur);
var n : Number3D = Number3D.cross(front, _targ);
n.normalize();
var angle : Number = Math.acos(Number3D.dot(front, _targ));
_q = Quaternion.createFromAxisAngle(n.x, n.y, n.z, 0.01);
}
private var _q : Quaternion;
private var _qCur : Quaternion;
// クォータニオンのベクトルへの適用
private function applyQuaternion(src : Number3D, q : Quaternion) : Number3D
{
var qSrc : Quaternion = new Quaternion(src.x, src.y, src.z, 0);
var qDst : Quaternion = Quaternion.conjugate(q);
qDst.mult(qSrc);
qDst.mult(q);
return new Number3D(qDst.x, qDst.y, qDst.z);
}
private const FRONT : Number3D = new Number3D(0, 0, 1);
private const UP : Number3D = new Number3D(0, 1, 0);
override protected function onRenderTick(e : Event = null) : void
{
// _tf.text = "" + _q + "\n" + camera.scaleZ;
// 視線とカメラの上のベクトルを回転
_qCur.mult(_q);
var front : Number3D = applyQuaternion(FRONT, _qCur);
var up : Number3D = applyQuaternion(UP, _qCur);
// 行列をつくってカメラに適用
var xAxis : Number3D = Number3D.cross(front, up);
xAxis.normalize();
var look : Matrix3D = new Matrix3D();
look.n11 = xAxis.x * camera.scaleX;
look.n21 = xAxis.y * camera.scaleX;
look.n31 = xAxis.z * camera.scaleX;
look.n12 = -up.x * camera.scaleY;
look.n22 = -up.y * camera.scaleY;
look.n32 = -up.z * camera.scaleY;
look.n13 = front.x * camera.scaleZ;
look.n23 = front.y * camera.scaleZ;
look.n33 = front.z * camera.scaleZ;
camera.copyTransform(look);
// 方向転換
if(Number3D.dot(front, _targ) < 0.03){
setTarg();
}
super.onRenderTick(e);
}
}
}