スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

クォータニオンの補間の刻み幅を変えてみる

2008-02-10 | 15:36

クォータニオンの捕間の係数(0~1)の刻み幅を変えてみるテスト。
緑は間隔が均等。
赤は時間間隔の変化が真ん中にいくほど早くなる(サインカーブの0~π)ように係数を

にしてみたもの。(微分するとになる)
青は終点にいくほど時間間隔の変化が大きくなる(y=x^2の0~1)ように係数を

にしてみたもの。(微分するとになる)

package {
    import flash.display.*;
    import flash.events.*;
    import flash.utils.*;

    import org.papervision3d.core.*;
    import org.papervision3d.core.geom.*;
    import org.papervision3d.core.math.*;
    import org.papervision3d.scenes.* ;
    import org.papervision3d.objects.*;
    import org.papervision3d.objects.primitives.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;
    import org.papervision3d.materials.shadematerials.* ;
    import org.papervision3d.materials.utils.*;
    import org.papervision3d.view.*;
    import org.papervision3d.render.*;
    import org.papervision3d.lights.*;
    import org.papervision3d.materials.special.LineMaterial ;

    [SWF(width="600", height="400", frameRate="10", backgroundColor="#ffffff")]
        public class SlerpTest extends Sprite{
            private var renderer:BasicRenderEngine = new BasicRenderEngine();
            private var viewport:Viewport3D = new Viewport3D(600, 800, false, true);
            private var scene:Scene3D = new Scene3D();
            private var camera:FreeCamera3D = new FreeCamera3D();

            private var lines:Array = null;

            private var cube1:Cube;
            private var cube2:Cube;
            private var cube3:Cube;

            private var timer:Timer=null;
            private var cnt:int = 0;
            // 元の姿勢のクォータニオン
            private var qSrc:Quaternion;
            // 移動後の姿勢のクォータニオン
            private var qDst:Quaternion;
            private var rr:Number;

            private var fromPos:Number3D;
            private var toPos:Number3D;

            private var tt:Number = 0;
            private var fwd:Boolean = true;

            public function SlerpTest():void
            {
                stage.align = StageAlign.TOP_LEFT;
                stage.scaleMode = StageScaleMode.NO_SCALE;

                addChild(viewport);

                camera.y = -300;
                camera.z = -1100;
                camera.x = 0;
                camera.focus = 1100;
                camera.zoom = 1;

                cube1= new Cube(new MaterialsList({all:new WireframeMaterial(0xff00)}), 
                        100, 200, 300);
                scene.addChild(cube1);

                cube2= new Cube(new MaterialsList({all:new WireframeMaterial()}), 
                        100, 200, 300);
                scene.addChild(cube2);

                cube3= new Cube(new MaterialsList({all:new WireframeMaterial(0xff)}), 
                        100, 200, 300);
                scene.addChild(cube3);

                qSrc = Quaternion.createFromAxisAngle(0,0,1, -Math.PI/2);
                qDst = Quaternion.createFromAxisAngle(0,0,1, Math.PI/2);

                var t:Timer = new Timer(100);
                t.addEventListener(TimerEvent.TIMER, onTimer);
                t.start();
            }

            private function onTimer(e:*):void{
                var q:Quaternion = (fwd) 
                    ? Quaternion.slerp(qSrc, qDst, tt)
                    : Quaternion.slerp(qDst, qSrc, tt);

                tt += 0.1;
                if (tt > 1){
                    fwd = !fwd;
                    tt = 0;
                }

                var t2:Number = (-Math.cos(Math.PI*tt) + 1) / 2;
                var q2:Quaternion = (fwd) 
                    ? Quaternion.slerp(qSrc, qDst, t2)
                    : Quaternion.slerp(qDst, qSrc, t2);

                var t3:Number = Math.pow(tt,3)/3;
                var q3:Quaternion = (fwd) 
                    ? Quaternion.slerp(qSrc, qDst, t3)
                    : Quaternion.slerp(qDst, qSrc, t3);

                cube1.transform = Matrix3D.quaternion2matrix(q.x, q.y, q.z, q.w);
                cube1.x = -300;
                cube2.transform = Matrix3D.quaternion2matrix(q2.x, q2.y, q2.z, q2.w);
                cube2.x = 0;
                cube3.transform = Matrix3D.quaternion2matrix(q3.x, q3.y, q3.z, q3.w);
                cube3.x = 300;
                renderer.renderScene(scene, camera, viewport);
            }
        }
}


スポンサーサイト

Comment

Post a comment

Secret

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。