首页 > 解决方案 > three.js(版本 102)如何使用 OrbitControls 设置相机的默认位置和旋转

问题描述

我创建了一个场景,不使用 OrbitControls 一切都很好。使用OrbitControls时,发现我的相机位置和旋转发生了变化,无法修改。

有人可以告诉我如何使用 OrbitControls 设置相机的默认位置和旋转。

谢谢! 三.js - OrbitControls

标签: javascriptthree.jsorbit

解决方案


OrbitControls需要一个target. 设置target这样你得到相同的视图。

  camera.position.set(1, 8, 7);

  const controls = new THREE.OrbitControls(camera, canvas);
  controls.target.set(0, 3, 0);
  controls.update();  

'use strict';

/* global THREE */

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas: canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 500;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(1, 8, 7);
  
  const controls = new THREE.OrbitControls(camera, canvas);
  controls.target.set(0, 3, 0);
  controls.update();  

  const scene = new THREE.Scene();

  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(-1, 2, 4);
    scene.add(light);
  }

  {
    const boxWidth = 1;
    const boxHeight = 10;
    const boxDepth = 1;
    const geometry = new THREE.BoxBufferGeometry(boxWidth, boxHeight, boxDepth);
    const material = new THREE.MeshPhongMaterial({color: 'red'});

    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    cube.position.y = .5;
  }
  
  {
    const geometry = new THREE.PlaneBufferGeometry(10, 10);
    const material = new THREE.MeshPhongMaterial({color: 'gray'});

    const plane = new THREE.Mesh(geometry, material);
    scene.add(plane);
    plane.rotation.x = Math.PI * -0.5;
  }

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render(time) {
    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();
body { margin: 0; }
#c { width: 100vw; height: 100vh; display: block; }
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r102/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r102/js/controls/OrbitControls.js"></script>

或者您可以根据当前相机视图计算目标。围绕目标的OrbitControls轨道,因此您需要选择与相机的距离作为目标

  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(1, 2, 5);
  camera.rotation.set(.1, .2, 0);

  // get the direction of the camera
  const direction = new THREE.Vector3();
  camera.getWorldDirection(direction);

  const controls = new THREE.OrbitControls(camera, canvas);

  // point the target from the camera in the
  // target direction
  camera.getWorldPosition(controls.target);
  controls.target.addScaledVector(direction, 5);
  controls.update();  

请注意,5 inaddScaledVector表示目标将在相机正面朝向相机前方 5 个单位处。5 距离是否合适取决于您。在我的示例场景中,相机从 z = 5 开始,因此相机前面的 5 个单位似乎是放置目标的合理位置

'use strict';

/* global THREE */

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas: canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 500;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(1, 2, 5);
  camera.rotation.set(.1, .2, 0);

  // compute a target direction
  const direction = new THREE.Vector3();
  camera.getWorldDirection(direction);

  const controls = new THREE.OrbitControls(camera, canvas);
  // point the target from the camera in the
  // target direction
  camera.getWorldPosition(controls.target);
  controls.target.addScaledVector(direction, 5);
  controls.update();  

  const scene = new THREE.Scene();

  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(-1, 2, 4);
    scene.add(light);
  }

  {
    const boxWidth = 1;
    const boxHeight = 10;
    const boxDepth = 1;
    const geometry = new THREE.BoxBufferGeometry(boxWidth, boxHeight, boxDepth);
    const material = new THREE.MeshPhongMaterial({color: 'red'});

    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);
    cube.position.y = .5;
  }
  
  {
    const geometry = new THREE.PlaneBufferGeometry(10, 10);
    const material = new THREE.MeshPhongMaterial({color: 'gray'});

    const plane = new THREE.Mesh(geometry, material);
    scene.add(plane);
    plane.rotation.x = Math.PI * -0.5;
  }

  function resizeRendererToDisplaySize(renderer) {
    const canvas = renderer.domElement;
    const width = canvas.clientWidth;
    const height = canvas.clientHeight;
    const needResize = canvas.width !== width || canvas.height !== height;
    if (needResize) {
      renderer.setSize(width, height, false);
    }
    return needResize;
  }

  function render(time) {
    if (resizeRendererToDisplaySize(renderer)) {
      const canvas = renderer.domElement;
      camera.aspect = canvas.clientWidth / canvas.clientHeight;
      camera.updateProjectionMatrix();
    }

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
}

main();
body { margin: 0; }
#c { width: 100vw; height: 100vh; display: block; }
<canvas id="c"></canvas>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r102/three.min.js"></script>
<script src="https://threejsfundamentals.org/threejs/resources/threejs/r102/js/controls/OrbitControls.js"></script>


推荐阅读