使用 Three.js 围绕对象旋转相机

Posted

技术标签:

【中文标题】使用 Three.js 围绕对象旋转相机【英文标题】:Rotate camera around object with Three.js 【发布时间】:2013-08-30 06:25:56 【问题描述】:

我正在使用 WebGlRenderer 显示带有 Three.js 的 OBJ 元素,现在我想允许用户在任何方向上围绕对象旋转相机,我找到了这个答案:

Rotate camera in Three.js with mouse

但这两个例子都给我报错,第一个说没有定义投影仪,我不知道“投影仪”是什么意思。我只有一个简单的相机、物体和一些光线。 第二个代码说 undefined 不是一个函数。

有人知道如何获得我需要的结果吗?

【问题讨论】:

【参考方案1】:

这就是你想要的:http://threejs.org/examples/misc_controls_orbit.html

包括轨道控件(下载后):

<script src="js/controls/OrbitControls.js"></script>

设置变量:

var controls;

将控件附加到相机并添加监听器:

controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );

并在您的动画函数中更新控件:

controls.update();

[更新]controls.autoRotate = true;(在 v73 中测试。最新版本的 OrbitControls.js 已添加此控件。)

【讨论】:

谢谢,但现在是围绕相机旋转的项目......我怎样才能反转行为?谢谢 @FezVrasta 您可以选择要环绕的物体,因此如果您喜欢“球体”,您可以在其中放置一个物体而不是相机,例如:new THREE.OrbitControls(sphere);跨度> 谢谢,但我不能让它工作,我使用这段代码来加载 OBJ:jsfiddle.net/7aqmB 但如果我在 OrbitControls中使用 object > 它说对象未定义... 代码中不需要写controls.addEventListener( 'change', render );。图书馆自己做。并且controls.update() 必须在function render()... 中,而不是在function animate()... ... 甚至没有必要在render() 中使用controls.update()。它会起作用的。【参考方案2】:

确实,如果您将“相机”替换为您选择的对象,则该对象将旋转。但是如果周围有其他物体(例如地板上的网格),它们仍然会静止不动。这可能是你想要的,或者看起来很奇怪。 (想象一把椅子漂浮在地板上旋转……?)

在初始化 Orbit Controls 后,我选择从我的代码中覆盖 OrbitControls.JS 中的中心对象

controls = new THREE.OrbitControls(camera, renderer.domElement);
…
controls.center =  new THREE.Vector3(
    chair.position.x,
    chair.position.y,
    chair.position.z
);

(免责声明:我觉得 OrbitControls.js 有不同的版本,但我假设它们都使用这个中心对象)

【讨论】:

【参考方案3】:

添加监听器以在 OrbitControl 更改时触发渲染方法:

    const controls = new OrbitControls(camera, this.renderer.domElement);
    controls.enableDamping = true;   //damping 
    controls.dampingFactor = 0.25;   //damping inertia
    controls.enableZoom = true;      //Zooming
    controls.autoRotate = true;       // enable rotation
    controls.maxPolarAngle = Math.PI / 2; // Limit angle of visibility

   controls.addEventListener("change", () => 
      if (this.renderer) this.renderer.render(this.scene, camera);
    );

在动画更新控件中:

  start = () => 
    if (!this.frameId) 
      this.frameId = requestAnimationFrame(this.animate);
    
  ;
  stop = () => 
    cancelAnimationFrame(this.frameId);
  ;

  renderScene = () => 
    if (this.renderer) this.renderer.render(this.scene, camera);
  ;


animate = () => 
    // update controls
    controls.update();

【讨论】:

【参考方案4】:

查看自动旋转方向变化的人的额外信息:

if (
   controls.getAzimuthalAngle() >= Math.PI / 2 ||
   controls.getAzimuthalAngle() <= -Math.PI / 2
 ) 
   controls.autoRotateSpeed *= -1;
 

 controls.update();

【讨论】:

【参考方案5】:

这里有一个快速技巧,以防您出于某种原因不想使用 OrbitControls。

            camera.position.copy( target );
            camera.position.x+=Math.sin(camera.rotationy)*3;
            camera.position.z+=Math.cos(camera.rotationy)*3;
            camera.position.y+=cameraHeight; // optional
            tempVector.copy(target).y+=cameraHeight; // the += is optional
            camera.lookAt( tempVector );

camera.rotationy 是鼠标旋转值的副本,因为我们通过调用 lookAt 来更改它。

【讨论】:

【参考方案6】:

如果您使用的是 ES6,以下可用于 OrbitControls

import  OrbitControls  from 'three/examples/jsm/controls/OrbitControls';

// this would create the orbit controls
// it would allow camera control using mouse
const orbitControls = new OrbitControls(camera, renderer.domElement);

如果你需要自动旋转,

function init() 
  ...

  // following would enable autorotate
  const orbitControls.autoRotate = true;

  ..


function animate() 
  // need to update the orbitcontrols for autorotate camera to take effect
  orbitControls.update();

  ...
  renderer.render( scene, camera );
  requestAnimationFrame( animate );

参考:https://threejs.org/docs/#examples/en/controls/OrbitControls

【讨论】:

以上是关于使用 Three.js 围绕对象旋转相机的主要内容,如果未能解决你的问题,请参考以下文章

three.js:结合 tween.js 围绕世界轴旋转对象

如何在three.js中围绕对象的中心旋转?

Three.js如何让对象相对于另一个旋转?

three.js 在它的中心围绕 Y 轴旋转 Object3d

Three.js用相机选择对象,没有鼠标

Three.js - 围绕某个轴旋转球体