使用Three.js围绕物体旋转相机

18

我使用WebGlRenderer和Three.js展示OBJ元素,现在我想允许用户以任何方向旋转相机围绕着对象,我找到了这个答案:

使用鼠标在Three.js中旋转相机

但是两个示例都返回错误,第一个说投影器没有定义,我不知道它指的是什么。我只有一个简单的相机、对象和一些灯光。 第二段代码说未定义的函数。

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

7个回答

39

这就是你想要的: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的最新版本已添加此控件。)


谢谢,但现在的物品是围绕相机旋转的...我该如何反转这种行为?谢谢。 - Fez Vrasta
1
@FezVrasta 你可以选择轨道的对象,因此如果你喜欢,可以将一个物体放在那里代替相机,例如“球体”,代码如下:new THREE.OrbitControls( sphere ); - Matthew Riches
我不知道如何在JSFiddle中包含.obj和纹理,我正在为一家公司工作,无法使用我的服务器来托管演示。 - Fez Vrasta
2
在代码中不需要编写 controls.addEventListener( 'change', render );。库会自己完成这个操作。而且 controls.update() 必须在 function render(){...} 中,而不是在 function animate(){...} 中。 - Ruben Kazumov
1
render()中使用controls.update()是不必要的,它仍然可以正常工作。 - Ruben Kazumov
显示剩余4条评论

5
如果您不想与 OrbitControls 打交道,只需将相机添加到一个 Group 中。
  const boom = new THREE.Group();
  boom.add(camera);
  scene.add(boom);
  camera.position.set( 0, 0, 100 ); // this sets the boom's length 
  camera.lookAt( 0, 0, 0 ); // camera looks at the boom's zero

那么,您可以旋转这个支臂而不是相机本身。

  boom.rotation.x += 0.01;

你也许想要在这个支架上添加一些额外的物品,例如灯等。

2
如果您正在使用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/zh/controls/OrbitControls


2

以下是一种快速的技巧,以防您由于某些原因不想使用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方法来改变它。


1

实际上,如果您将“相机”替换为所选择的对象,该对象将会旋转。但是,如果周围有其他物体(例如地板上的网格),它们仍将保持静止。这可能是您想要的,或者看起来很奇怪。(想象一下一把在空中旋转的椅子...?)

我选择在初始化轨道控制器后,从我的代码中覆盖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 有不同的版本,但我假设它们都使用这个中心对象)


0

添加一个监听器,以便在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();
}

0

对于寻找在限制条件下自动旋转方向更改的人提供额外信息:

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

 controls.update();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接