简体   繁体   English

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

[英]Rotate camera around object with Three.js

I'm displaying an OBJ element with Three.js using WebGlRenderer, now I'd like to allow users to rotate the camera around the object in any direction, I've found this answer:我正在使用 WebGlRenderer 用 Three.js 显示一个 OBJ 元素,现在我想允许用户以任何方向围绕对象旋转相机,我找到了这个答案:

Rotate camera in Three.js with mouse 用鼠标在 Three.js 中旋转相机

But both examples return me errors, the first says that projector is not defined, and I don't know what it means with "projector".但是这两个例子都给我带来了错误,第一个说投影仪没有定义,我不知道“投影仪”是什么意思。 I've just a simple camera, the object and some light.我只有一个简单的相机、物体和一些光。 The second code says that undefined is not a function.第二个代码表示 undefined 不是函数。

Does someone know how to get the result I need?有人知道如何获得我需要的结果吗?

This is what you want: http://threejs.org/examples/misc_controls_orbit.html这就是你想要的: http : //threejs.org/examples/misc_controls_orbit.html

Include the orbit controls (after you have downloaded them):包括轨道控制(下载后):

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

Setup the variable:设置变量:

var controls;

Attach the controls to the camera and add a listener:将控件附加到相机并添加一个侦听器:

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

and in your animate function update the controls:并在您的动画功能中更新控件:

controls.update();

[Update] controls.autoRotate = true; [更新] controls.autoRotate = true; (tested in v73. Recent versions of OrbitControls.js has added this control.) (在 v73 中测试。最近版本的 OrbitControls.js 已添加此控件。)

Here is a quick hack, in case you don't want to use the OrbitControls for some reason.这是一个快速技巧,以防您出于某种原因不想使用 OrbitControl。

            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 is a copy of the mouse rotation value since we are changing it with the call to lookAt. camera.rotationy 是鼠标旋转值的副本,因为我们通过调用 lookAt 来更改它。

Indeed, if you substitute 'camera' with the object of your choice, the object will rotate.事实上,如果你用你选择的对象替换“相机”,对象会旋转。 But if there are other objects surrounding it (for example a grid on the floor), they will still stand still.但是如果周围有其他物体(例如地板上的网格),它们仍然会静止不动。 That might be what you want, or it might look weird.这可能是你想要的,或者它可能看起来很奇怪。 (Imagine a chair rotating floating above the floor...?) (想象一下漂浮在地板上方的椅子旋转......?)

I choose to override the center object from OrbitControls.JS from my code after initializing the Orbit Controls在初始化 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
);

(disclaimer: I have the impression there are different versions of OrbitControls.js around, but I assume they all use this center-object) (免责声明:我的印象是周围有不同版本的 OrbitControls.js,但我假设它们都使用这个中心对象)

If you are using ES6, following could be used for OrbitControls如果您使用的是 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);

If you need autorotate,如果您需要自动旋转,

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 );
}

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

Add a listener to trigger render method on change of OrbitControl :添加侦听器以在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);
    });

and in animate update controls:并在动画更新控件中:

  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();
}

Extra info for who looking auto rotate direction change on a limit:有关在限制上寻找自动旋转方向更改的人的额外信息:

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

 controls.update();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM