为 Three.JS 中的场景添加最大移动到 onMouseMove

Add max movement to onMouseMove for scene in Three.JS

我已经成功地向 three.js 中的一个场景添加了一个非常好的鼠标移动,其中相机位于场景内部,面向四堵墙之一。向左或向右移动鼠标可平移和轻微摇晃场景。

如果你一直将鼠标悬停在屏幕的一侧,你最终会 'flying' 在场景之外,现在从外面而不是在里面查看整个 3D 对象。

我想知道如何更新下面的代码以限制您可以向左或向右移动的最大数量,这样您就不会离开场景?

如果我能避免添加另一个库,例如 Orbit Controls,那将是理想的,但如果这是唯一的方法,那么我会这样做。我觉得我已经接近在我的函数 animate() 中添加某种 Math.Max 到相机位置,但到目前为止还没有成功。

在此先感谢您的帮助!

window.addEventListener("load", loadGltf, false);
window.addEventListener("resize", onWindowResize, false);
const progressBar = document.querySelector("progress");

//store our imported glTF scene when loaded successfully
const gltfStore = {};

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.getElementById( 'container' );



//camera
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

camera.position.set(0, 0, 0);
camera.lookAt(0, 0, 5);

windowHalfX = window.innerWidth / 2,
        windowHalfY = window.innerHeight / 2,
        mouseX = 0,
        mouseY = 0;

//re-establish camera view on window resize
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

//lighting
const lightFill = new THREE.PointLight(0xffffff, 1, 500);
lightFill.position.set(0, 0, 5);
scene.add(lightFill);

const lightKey = new THREE.PointLight(0xffffff, 1, 500);
lightKey.position.set(20, 0, 20);
scene.add(lightKey);

const loader = new THREE.GLTFLoader();


function loadGltf() {
  loader.load(
    "<?php echo get_template_directory_uri();?>/objects/SM_LookDev_TextureTest_FromFBX.glb",
    //onLoad
    function(gltf) {
      scene.add(gltf.scene);
       mesh = gltf.scene;
      //set material emissive to 0
      gltf.scene.children[0];
      gltfStore.scene = gltf.scene;
       document.addEventListener("mousemove", onMouseMove);

    }

  );

  container.appendChild(renderer.domElement); 

// Mouse movement

function onMouseMove(event) {

          mouseX = (event.clientX - windowHalfX) / 10;
          mouseY = (event.clientY - windowHalfY) / 30;
}


function getMouseX(event) {
    if (event.type.indexOf("touch") == -1)
        return event.clientX;
    else
        return event.touches[0].clientX;
}

function getMouseY(event) {
    if (event.type.indexOf("touch") == -1)
        return event.clientY;
    else
        return event.touches[0].clientY;
}

  function animate() {
    requestAnimationFrame(animate);


    camera.position.x += (mouseX - camera.position.x) * .0005;
        camera.position.y += (-mouseY - camera.position.y) * .0003;
        camera.lookAt(0,0,10);
    renderer.render(scene, camera);

  }



  animate();


}

Three.js 在其 MathUtils class 中附带了一些实用方法,可以帮助解决这个问题。您可以使用 THREE.MathUtils.clamp 来限制 mouseXmouseY:

的最小值和最大值
function onMouseMove(event) {
    mouseX = THREE.MathUtils.clamp((event.clientX - windowHalfX) / 10, -20, 20);
    mouseY = THREE.MathUtils.clamp((event.clientY - windowHalfY) / 30, -10, 10);
}

-20, 20 的最小值和最大值等取决于您的 .gltf 对象的边界,因此您必须相应地调整它们。

这只是一个辅助方法,它在内部使用 JavaScript 的原生 Math.min() and Math.max() 来“钳制”值。

r112 及更低版本的注意事项:

在 Three.js 修订版 113 之前,THREE.MathUtils class 曾经被称为 THREE.Math 但这可能会导致与 JavaScript 的原生 Math class。确保您根据所使用的 Three.js 版本使用正确的名称,请参阅 here for more details