相机意外转动(three.js + tween + lookat)

unexpected turn of the camera (three.js + tween + lookat)

我有一个关于 three.js + tween + lookat 的问题 这是一个例子:https://intera3d.ru/tween_test/tokyo.html 我希望当按下“TWEEN”按钮时,相机从上方查看 3D 模型。

事情就这样发生了,但最后镜头/3D模型出现了意想不到的转向。

如何避免这种情况?

这里是“tween”函数代码:

function TWEEN_begin_CAMERA_1() {

    const tweenCamera1 = new TWEEN.Tween( 
        {x: camera.position.x, y: camera.position.y, z: camera.position.z, 
            lookAtX: 0, lookAtY: 0, lookAtZ: 0} 
        )
    .to( {x: 0, y: 20, z: 0, lookAtX: 0, lookAtY: 0, lookAtZ: 0}, 1000 )

    const updateCamera = function (object, elapsed) {
        camera.position.set(object.x, object.y, object.z);
        camera.lookAt(new THREE.Vector3(object.lookAtX, object.lookAtY, object.lookAtZ))
    }
    tweenCamera1.onUpdate(updateCamera)
    tweenCamera1.start()
}

非常感谢您的帮助!

这是一个 THREE.Spherical 的示例,它不允许将相机设置为 x=0 和 z=0(在任何 y) ,在文档中查看方法 .makeSafe() 的作用:

body{
  overflow: hidden;
  margin: 0;
}
<button id="btn_Tween" style="position:absolute; margin: 10px;">TWEENME</button>
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three@0.134.0";
import {OrbitControls} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/controls/OrbitControls.js";
import {TWEEN} from "https://cdn.skypack.dev/three@0.134.0/examples/jsm/libs/tween.module.min.js"

let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 5, 10);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
});

let controls = new OrbitControls(camera, renderer.domElement);

let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));


scene.add(new THREE.GridHelper());
scene.add(new THREE.Mesh(
  new THREE.BoxGeometry(5, 5, 5), 
  new THREE.MeshLambertMaterial(
    {
      map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/uv_grid_opengl.jpg")
    }
  )
));

btn_Tween.addEventListener("click", ()=> {
  let spherical = new THREE.Spherical();
  spherical.setFromVector3(camera.position);
  spherical.radius = 20;
  spherical.phi = 0;
  spherical.makeSafe();
  let v = new THREE.Vector3().setFromSpherical(spherical);
  let t = new TWEEN.Tween(camera.position).to(v, 2000).onUpdate(() => {
    camera.lookAt(scene.position);
    controls.update();
  });
  t.start();
});

renderer.setAnimationLoop(() => {
  TWEEN.update();
  renderer.render(scene, camera);
});
</script>