【问题标题】:Smooth camera control switch on Three.jsThree.js 上的平滑相机控制开关
【发布时间】:2016-03-23 07:48:52
【问题描述】:

我正在开发一个网站,该网站允许用户使用 VRControls 查看天空中的对象,并使用通过单击对象初始化的 Trackball 控件查看他们最喜欢的对象。这是演示。 https://jsfiddle.net/tushuhei/4f1Lum5n/6/

function focus (obj, target) {
  var dummyCamera = camera.clone();
  controls = new THREE.TrackballControls(dummyCamera);
  controls.target.set(obj.point.x, obj.point.y, obj.point.z);
  new TWEEN.Tween(camera.position)
    .to(target, 1000)
    .onComplete(function() {
      transitioning = false;
      controls.dispose();
      controls = new THREE.TrackballControls(camera);
      controls.target.set(obj.point.x, obj.point.y, obj.point.z);
  }).start();
}

TWEEN 非常适合从 WebVR 到 Trackball 模式的转换,反之亦然,但在转换结束时仍有一点差距。我猜这来自过渡完成阶段相机旋转的间隙。

考虑到相机的位置和旋转,有什么方法可以使两个不同的相机控件之间的过渡平滑?

谢谢,

【问题讨论】:

    标签: javascript 3d three.js webvr


    【解决方案1】:

    您在使用 dummyCamera 时走在了正确的轨道上。您需要在 tween 处理位置时,在初始四元数和最后一个四元数之间获取最终四元数和 slerp。

    // Save the initial quaternion so that we can use it as a 
    // starting point for the slerp.
    var startQuaternion = camera.quaternion.clone();
    
    // Apply the tracking controls to a cloned dummy camera so 
    // that we can get the final quaternion.
    var dummyCamera = camera.clone();
    dummyCamera.position.set(target.x, target.y, target.z);
    var dummyControls = new THREE.TrackballControls(dummyCamera);
    dummyControls.target.set(obj.point.x, obj.point.y, obj.point.z);
    dummyControls.update();
    
    // Disable VR controls, so that it doesn't compete with 
    // the tween for control  of the camera.
    // (Note: now you need to check if the controls are 
    // null in the animate function)
    controls.dispose();
    controls = null;
    
    new TWEEN.Tween(camera.position)
    .to(target, 1000)
    .onUpdate(function (timestamp){
      // Slerp the camera quaternion as well. 
      // timestamp is the eased time value from the tween.
      THREE.Quaternion.slerp(
        startQuaternion, dummyCamera.quaternion, camera.quaternion, timestamp);
    })
    .onComplete(function() {
      controls = new THREE.TrackballControls(camera);
      controls.target.set(obj.point.x, obj.point.y, obj.point.z);
    }).start();
    

    https://jsfiddle.net/4f1Lum5n/10/

    附:到目前为止,您实现这一点的方式可能会让 VR 用户感到恶心。接管用户观点的控制权通常是不好的做法。另一种解决方案可能是将用户放在宇宙飞船或平台上,然后对平台进行补间,以便用户始终控制相机。

    【讨论】:

    • 这很完美,谢谢!我也感谢你的笔记。
    猜你喜欢
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多