首页 > 解决方案 > 将立方体放置在相机位置但有点落后时,如何避免圆周运动?

问题描述

所以这是我的代码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>three.js</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link type="text/css" rel="stylesheet" href="main.css">
    <style>
      body {
        overflow: hidden;
        margin: 0;
      }
    </style>
  </head>
  <body>
    <script src="three.js"></script>
    <script src="pointerlockcontrols.js"></script>
    <script>
      var camera, scene, renderer, controls;
      var cube;

      var previous_time = performance.now();
      var color = new THREE.Color();

      camera = new THREE.PerspectiveCamera(99, window.innerWidth / window.innerHeight, 1, 100);
      camera.position.y = 10;

      scene = new THREE.Scene();
      scene.background = new THREE.Color(0x0000ff);
      scene.fog = new THREE.Fog(0xffffff, 0, 750);

      var light = new THREE.HemisphereLight(0xeeeeff, 0x777788, 0.75);
      light.position.set(0.5, 1, 0.75);
      scene.add(light);

      controls = new THREE.PointerLockControls(camera);

      document.body.addEventListener("click", function() { controls.lock(); });

      scene.add(controls.getObject());

      var geometry = new THREE.BoxBufferGeometry(0.8*5, 1.5*5, 0.4*5);
      var material = new THREE.MeshPhongMaterial({ color: 0xffffff });
      cube = new THREE.Mesh(geometry, material);
      scene.add(cube);

      raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, - 1, 0), 0, 10);

      var floorGeometry = new THREE.PlaneBufferGeometry(2000, 2000, 100, 100);
      floorGeometry.rotateX(- Math.PI / 2);

      floorGeometry = floorGeometry.toNonIndexed(); // ensure each face has unique vertices

      position = floorGeometry.attributes.position;
      var colors = [];

      for (var i = 0, l = position.count; i < l; i ++) {
        color.setHSL(Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75);
        colors.push(color.r, color.g, color.b);
      }

      floorGeometry.addAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

      var floorMaterial = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors });

      var floor = new THREE.Mesh(floorGeometry, floorMaterial);
      scene.add(floor);

      renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);

      window.addEventListener('resize', on_window_resize, false);

      function on_window_resize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        renderer.setSize(window.innerWidth, window.innerHeight);
      }

      function loop() {
        requestAnimationFrame(loop);

        if (controls.isLocked === true) {
          raycaster.ray.origin.copy(controls.getObject().position);

          var vector = new THREE.Vector3();
          controls.getObject().getWorldDirection(vector);
          cube.rotation.y = Math.atan2(vector.x, vector.z);

          cube.position.x = controls.getObject().position.x;
          cube.position.z = controls.getObject().position.z+1;
        }

        renderer.render(scene, camera);
      }

      loop();
    </script>
  </body>
</html>

这里的重要部分是:

// This makes the cube always look in the direction of the camera.
var vector = new THREE.Vector3();
controls.getObject().getWorldDirection(vector);
cube.rotation.y = Math.atan2(vector.x, vector.z);

// This makes the cube always be on the position of the camera (for later when there's movement)
cube.position.x = controls.getObject().position.x;
cube.position.z = controls.getObject().position.z+1;

这一切都很好,但是由于最后+1(我希望立方体在相机后面一点),立方体在旋转相机时会做圆周运动。

我试过了

cube.rotation.y = Math.atan2(vector.x, vector.z+1);

然而,这使得立方体根本不旋转。

如何避免圆周运动?我只想把立方体放在我的位置上,在我身后一点,同时它也面向我看的方向。

标签: javascriptthree.js3dcameraatan2

解决方案


推荐阅读