スポンサーサイト

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

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

PV3D オブジェクトの姿勢の補間間隔をTweenerで

2008-03-10 | 20:56

左側のトランジッション名をクリックするとそれにあわせて姿勢を変えます。


package {
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
    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.utils.*;
    import org.papervision3d.view.*;
    import org.papervision3d.render.*;
    import org.papervision3d.materials.special.LineMaterial ;

    import caurina.transitions.Tweener;

    [SWF(width="600", height="400", frameRate="10", backgroundColor="#ffffff")]
        public class SlerpTweener 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 cube:SlerpObject;

            private var transitions:Array = ["linear",
                "easeInSine", "easeOutSine", "easeInOutSine",
                "easeInQuad", "easeOutQuad", "easeInOutQuad",
                "easeInCubic", "easeOutCubic", "easeInOutCubic",
                "easeInQuart", "easeOutQuart", "easeInOutQuart",
                "easeInQuint", "easeOutQuint", "easeInOutQuint",
                "easeInExpo", "easeOutExpo", "easeInOutExpo",
                "easeInCirc", "easeOutCirc", "easeInOutCirc",
                "easeInElstic", "easeOutElstic", "easeInOutElstic",
                "easeInBack", "easeOutBack", "easeInOutBack",
                "easeInBounce", "easeOutBounce", "easeInOutBounce" ];

            public function SlerpTweener():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;

                var c:Cube = new Cube(new MaterialsList(
                                {all:new WireframeMaterial(0xff00)}), 
                            100, 200, 300);
                cube = new SlerpObject(c);
                scene.addChild(c);
                renderer.renderScene(scene, camera, viewport);

                SlerpUtil.init();

                for(var i:int = 0 ; i < transitions.length ; i++){

                    var tf:TextField = new TextField();
                    tf.text = transitions[i];
                    tf.addEventListener(MouseEvent.MOUSE_DOWN, function(e:*):void{
                            slerp(e.target);
                            });
                    addChild(tf);
                    tf.y = i*12;
                }
            }

            private function slerp(tf:TextField):void{
                Tweener.addTween(cube, {time:2, _t:1, transition:tf.text, 
                        onUpdate:function():void{
                        renderer.renderScene(scene, camera, viewport);
                        }, onComplete:function():void{
                        cube.onComplete();
                        }
                        });
                Tweener.addTween(tf, {time:2, x:400, transition:tf.text, 
                        onComplete:function():void{
                        tf.x = 0;
                        }
                        });
            }
        }
}

internal class SlerpObject{
    public var t:Number=0;
    public var o3d:DisplayObject3D;
    // 元の姿勢のクォータニオン
    public var qSrc:Quaternion;
    // 移動後の姿勢のクォータニオン
    public var qDst:Quaternion;

    public function SlerpObject(o:DisplayObject3D){
        o3d = o;

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

    public function onComplete():void{
        t = 0;
        var temp:Quaternion = qSrc;
        qSrc = qDst;
        qDst = temp;
    }
}

import org.papervision3d.core.math.*;
import org.papervision3d.objects.*;
import caurina.transitions.Tweener;

internal class SlerpUtil{
    public static function init(): void {
        Tweener.registerSpecialProperty("_t", _get_t, _set_t, ["t"]);
    }

    protected static function _get_t(p_obj:Object, p_parameters:Array, p_extra:Object = null):Number
    {
        return p_obj.t;
    }

    protected static function _set_t(p_obj:Object, p_value:Number, p_parameters:Array, p_extra:Object = null):void
    {
        trace(p_value);
        p_obj.t = p_value;
        var q:Quaternion = Quaternion.slerp(p_obj.qSrc, p_obj.qDst, p_value);
        p_obj.o3d.transform = q.toMatrix();
    }
}

スポンサーサイト

Comment

Post a comment

Secret

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