切换 threejs 控件(从 TrackBall 切换到 FlyControls,反之亦然)

Switch threejs controls ( from TrackBall to FlyControls and vice versa)

本文关键字:FlyControls 反之亦然 控件 threejs TrackBall 切换      更新时间:2023-09-26

我要实现的是拥有两种控制模式,一种是自由的"飞行"模式,另一种是以对象为中心的模式(轨迹球),只需按一下按钮即可在它们之间无缝切换。

我最初尝试使用TrackBallControls和FlyControls。这两个问题在于,TrackballControls是基于欧拉角度的,而FlyControls是基于Quartenions的。我尝试通过以下操作将 camera.rotate 矢量转换为四元数,

quaternion.setFromEuler( target ); //where target, a Vector3 that contains degrees

手动设置位置(因为它们使用相同的位置对象),当它似乎在工作时,稍微旋转相机 - 并切换控件,开始产生可怕的错误结果。此外,从四元数(setEulerFromQuaternion)中抓取欧拉角会导致错误的数据。

因此,

虽然我能够在它们之间切换,但我始终无法同步它们的旋转坐标,因此"切换"时,当相机位置正确时,旋转是错误的。

附言。我使用 FirstPersonControls(欧拉角)有一些结果,但它使用的屏幕纬度,长方法非常容易出错,并且在 Z 轴旋转时完全失败。

这样的事情呢?

function onClick() {
    var prevCamera = camera;
    camera = new THREE.PerspectiveCamera(...);
    camera.position.copy( prevCamera.position );
    camera.rotation.copy( prevCamera.rotation );
    var MODE = { TRACKBALL: 0, FLY: 1 };
    switch( mode ) {
        case MODE.FLY:
            controls = new THREE.TrackballControls( camera );
            mode = MODE.TRACKBALL;
            break;
        case MODE.TRACKBALL:
            controls = new THREE.FlyControls( camera );
            mode = MODE.FLY;
            break;
    }
}

创建新相机是取消绑定使用以前的控件设置的所有键盘/鼠标事件的最简单方法。如果您不这样做,您将在飞行模式打开的情况下触发轨道控制事件。