Добавить максимальное движение в onMouseMove для сцены в Three.JS

Я успешно добавил действительно хорошее движение мыши в сцену в Three.js, где камера находится внутри сцены, лицом к одной из четырех стен. Перемещая мышь влево или вправо, слегка качает сцену.

Если вы продолжаете удерживать мышь над одной стороной экрана, вы в конечном итоге «летите» за пределы сцены и теперь видите весь трехмерный объект снаружи, а не внутри него.

Мне было интересно, как я могу обновить свой код ниже, чтобы ограничить максимальную сумму, которую вы можете переместить влево или вправо, чтобы вы не могли оказаться вне сцены?

Если я смогу избежать добавления другой библиотеки, такой как Orbit Controls, это было бы идеально, но если это единственный способ, я сделаю это. Я чувствую, что был близок к добавлению какого-то Math.Max ​​в положение камеры в моей функции animate (), но пока не достиг успеха.

Заранее благодарю за любую помощь!

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


}

Всего 1 ответ


Three.js поставляется с некоторыми служебными методами в своем классе Math которые могут помочь с этим. Вы можете использовать THREE.Math.Clamp чтобы ограничить минимальное и максимальное значения mouseX и mouseY :

function onMouseMove(event) {
    mouseX = THREE.Math.clamp((event.clientX - windowHalfX) / 10, -20, 20);
    mouseY = THREE.Math.clamp((event.clientY - windowHalfY) / 30, -10, 10);
}

Минимальные и максимальные значения -20, 20 и т. Д. .gltf от границ вашего объекта .gltf , поэтому вам придется их соответствующим образом скорректировать.

Это просто вспомогательный метод, который использует встроенные в JavaScript Math.min() и Math.max() для «зажима» значения.

Обновление для r113 +:

Я только что узнал, что в следующей версии Three.js (редакция 113) класс THREE.Math будет THREE.Math в THREE.MathUtils (возможно, чтобы избежать конфликта с собственным классом Math JavaScript), поэтому убедитесь, что вы используете правильное имя на основе в версии Three.js, которую вы используете.


Есть идеи?

10000