用babylon.js简单实现类似cesium的flyTo方法

flyTo方法是在三维场景开发中一个常用的方法,主要用于在控制相机从当前位置,通过差值流畅的运动到目标点,比如在列表中点击某个定位按钮需要将相机飞行到目标点

cesium的flyTo比较复杂,它的相机运动的时候,会计算高度啥的,太低的时候会先升空然后在飞过去再下降,感觉相机的运动轨迹像是一条曲线;在设置参数方面上,除了最主要的目标点和运动时间,还可以设置相机的欧拉角,相机差值时候的差值函数,执行结束后的回调等等;

我们这里就主要实现从当前点运到目标点就行了,运动轨迹为一条直线,可以说是一个乞丐版的flyTo, 要加上欧拉角的话只需要再添加一个动画,因为用的是BABYLON.AnimationGroup,可以实现多个动画

我们这里用js闭包的方式不暴露出执行结束后的动画,在新的动画开始前,停止或者销毁上一个动画

    function FlyTo(): (
        camera: BABYLON.FreeCamera,
        targetPoint: BABYLON.Vector3,
        flyDuration: number
    ) => void {
        let currentAnimationGroup: BABYLON.AnimationGroup | null = null;

        return function (
            camera: BABYLON.FreeCamera,
            targetPoint: BABYLON.Vector3,
            flyDuration: number
        ): void {
            // 在每次调用前检查并清除之前的动画
            if (currentAnimationGroup) {
                currentAnimationGroup.stop();
                currentAnimationGroup.dispose();
            }

            // 创建动画组
            const animationGroup = new BABYLON.AnimationGroup("cameraAnimationGroup");
            currentAnimationGroup = animationGroup;

            // 动画:相机位置
            const positionAnimation = new BABYLON.Animation(
                "positionAnimation",
                "position",
                60,
                BABYLON.Animation.ANIMATIONTYPE_VECTOR3,
                BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
            );
            positionAnimation.setKeys([
                { frame: 0, value: camera.position.clone() },
                { frame: flyDuration * 60, value: targetPoint }
            ]);
            animationGroup.addTargetedAnimation(positionAnimation, camera);

            // 启动动画组
            animationGroup.play(true);
        };
    }

上一种只是简单的平移相机,我们在上一点强度,加上想相机的欧拉角,这个时候,就是要有两个变量的差值,一个是postition,另一个是rotation,不过这次需要在方法内部访问到scene和camera

   const flyTo = (position: BABYLON.Vector3, rotation: BABYLON.Vector3) => {
        // 动画:相机位置
        const positionAnimation = new BABYLON.Animation(
            "positionAnimation",
            "position",
            2 * 60,
            BABYLON.Animation.ANIMATIONTYPE_VECTOR3,
            BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
        );
        positionAnimation.setKeys([
            { frame: 0, value: map.camera.position.clone() },
            { frame: 2 * 60, value: position }
        ]);
        // 动画:相机姿态
        const rotationAnimation = new BABYLON.Animation(
            "rotaionAnimation",
            "rotation",
            2 * 60,
            BABYLON.Animation.ANIMATIONTYPE_VECTOR3,
            BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
        );
        rotationAnimation.setKeys([
            { frame: 0, value: map.camera.rotation.clone() },
            { frame: 60, value: rotation }
        ]);
        map.scene.beginDirectAnimation(map.camera, [positionAnimation, rotationAnimation], 0, 2 * 60, false);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值