OrbitControls in Three.js not working proper in sync with camera

77 views Asked by At

so I have been trying all day to get the camera working, basically I want this exhibition to be visible, it is a runway with pictures on the left and the right. I want to start at the beginning of the model and walk till the end. Since the beginning of the day, it stops and starts glitching in the middle. I have never had such issues with the arrow keys and controls but here seems to be a problem. I just would like the camera to be blocked at human eyesight and that can turn to see the photos on mouse drag and on click a modal pop up with the description. but that is a detail.

Here is the code with the missing 3d model, but hopefully you will get it with the code provided and the photo, I just added fog in three.

Exhibition runway with photos on the left and on the right, I would like to block the camera so that the user cannot go underground, only forward or backward and just a turn to see the photos with the mouse

    import * as THREE from 'three';
    import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
    import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
    import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';
    import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';

    let camera, scene, renderer, controls;
    let moveForward = false;
    let moveBackward = false;
    let moveLeft = false;
    let moveRight = false;
    let clock = new THREE.Clock();

    init();
    animate();

    function init() {
      const container = document.createElement('div');
      document.body.appendChild(container);

      camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
      camera.position.set(400, 200, 0);

      renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.toneMapping = THREE.ACESFilmicToneMapping;
      renderer.toneMappingExposure = 1;
      container.appendChild(renderer.domElement);

      const environment = new RoomEnvironment();
      const pmremGenerator = new THREE.PMREMGenerator(renderer);

      scene = new THREE.Scene();
      scene.background = new THREE.Color(0xbbbbbb);
      scene.environment = pmremGenerator.fromScene(environment).texture;
      environment.dispose();

      const grid = new THREE.GridHelper(500, 10, 0xffffff, 0xffffff);
      grid.material.opacity = 0.5;
      grid.material.depthWrite = false;
      grid.material.transparent = true;
      scene.add(grid);

      const ktx2Loader = new KTX2Loader()
        .setTranscoderPath('jsm/libs/basis/')
        .detectSupport(renderer);

      const loader = new GLTFLoader().setPath('models/gltf/');
      loader.setKTX2Loader(ktx2Loader);
      loader.setMeshoptDecoder(MeshoptDecoder);
      loader.load('Photography-museum.glb', function (gltf) {
        gltf.scene.position.y = 8;
        gltf.scene.position.z = 0;
        gltf.scene.position.x = -18;
        scene.add(gltf.scene);
      });

      controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true;
      controls.dampingFactor = 0.05;
      controls.enableRotate = true; // Allow rotation
      controls.enablePan = false; // Disable panning
      controls.maxPolarAngle = Math.PI / 2; // Limit vertical rotation
      controls.minDistance = 100; // Set minimum distance
      controls.maxDistance = 500; // Set maximum distance

      const geometry = new THREE.PlaneGeometry(5000, 5000);
      const material = new THREE.MeshBasicMaterial({ color: 0x808080, side: THREE.DoubleSide });
      const floor = new THREE.Mesh(geometry, material);
      floor.position.y = 0;
      floor.rotation.x = -Math.PI / 2;
      scene.add(floor);

      // Add fog
      scene.fog = new THREE.FogExp2(0xcccccc, 0.002);

      window.addEventListener('resize', onWindowResize);
      document.addEventListener('keydown', onKeyDown);
      document.addEventListener('keyup', onKeyUp);
    }

    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
      render();
    }

    function onKeyDown(event) {
      switch (event.code) {
        case 'KeyW':
        case 'ArrowUp':
          moveForward = true;
          break;
        case 'KeyS':
        case 'ArrowDown':
          moveBackward = true;
          break;
        case 'KeyA':
        case 'ArrowLeft':
          moveLeft = true;
          break;
        case 'KeyD':
        case 'ArrowRight':
          moveRight = true;
          break;
      }
    }

    function onKeyUp(event) {
      switch (event.code) {
        case 'KeyW':
        case 'ArrowUp':
          moveForward = false;
          break;
        case 'KeyS':
        case 'ArrowDown':
          moveBackward = false;
          break;
        case 'KeyA':
        case 'ArrowLeft':
          moveLeft = false;
          break;
        case 'KeyD':
        case 'ArrowRight':
          moveRight = false;
          break;
      }
    }

    function animate() {
      requestAnimationFrame(animate);
      const delta = clock.getDelta();
      const moveSpeed = 100; // Units per second

      if (moveForward) camera.translateZ(-moveSpeed * delta);
      if (moveBackward) camera.translateZ(moveSpeed * delta);
      if (moveLeft) camera.translateX(-moveSpeed * delta);
      if (moveRight) camera.translateX(moveSpeed * delta);

      controls.update();
      render();
    }

    function render() {
      renderer.render(scene, camera);
    }
<!DOCTYPE html>
<html lang="en">
<head>
  <title>three.js webgl - GLTFloader + compressed</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">
</head>

<body>
  <script type="importmap">
    {
      "imports": {
        "three": "../build/three.module.js",
        "three/addons/": "./jsm/"
      }
    }
  </script>

  <script type="module" src="script.js">

  </script>
</body>
</html>
0

There are 0 answers