Неточная лучевая трансляция с орфографической камерой в three.js - PullRequest
2 голосов
/ 28 мая 2019

Я разрабатываю средство просмотра 2D-чертежей САПР с использованием библиотеки three.js, и для этого проекта мне нужно иметь возможность щелкать объекты на сцене, чтобы выполнять некоторые операции.

При использовании ортографической камеры, радиопередача Three.js не является точной, как я ожидаю.

Вот код и скрипка, которая показывает именно то, что я имею в виду https://jsfiddle.net/toriphes/a0o7td1u/

var camera, scene, renderer, square, raycaster;
init();
animate();

function init() {

  output = document.getElementById('output');

  raycaster = new THREE.Raycaster();
  // Renderer.
  renderer = new THREE.WebGLRenderer();
  //renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  // Add renderer to page
  document.body.appendChild(renderer.domElement);

  // Create camera.
  var aspect = window.innerWidth / window.innerHeight;
  var d = 20;
  camera = new THREE.OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 1, 1000);
  camera.position.z = 10;
  camera.position.x = 25;
  camera.position.y = 25;
  camera.zoom = 10
  camera.updateProjectionMatrix()

  controls = new THREE.OrbitControls(camera, renderer.domElement);
  controls.enableRotate = false
  controls.target.x = camera.position.x;
  controls.target.y = camera.position.y;

  controls.update();


  // Create scene.
  scene = new THREE.Scene();

  var points = [
    new THREE.Vector2(10, 10),
    new THREE.Vector2(40, 10),
    new THREE.Vector2(40, 40),
    new THREE.Vector2(10, 40),
    new THREE.Vector2(10, 10)
  ]

  var shape = new THREE.Shape(points);

  var geometry = new THREE.Geometry().setFromPoints(points);

  var square = new THREE.Line(geometry, new THREE.LineBasicMaterial({
    color: 0xFF0000
  }));
  scene.add(square)

  document.addEventListener('mousemove', findIntersections, false);
}

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

function updateMousePosition(event) {
  return new THREE.Vector3(
    (event.clientX - renderer.domElement.offsetLeft) /
    renderer.domElement.clientWidth *
    2 -
    1,
    -(
      (event.clientY - renderer.domElement.offsetTop) /
      renderer.domElement.clientHeight
    ) *
    2 +
    1,
    0
  );
}

function findIntersections(e) {
  var mouseposition = updateMousePosition(e);
  raycaster.setFromCamera(mouseposition, camera);
  const intersects = raycaster.intersectObjects(scene.children);
  output.innerHTML = intersects.length > 0 ?
    'Intersect: TRUE' :
    'Intersect: FALSE';
}

Если вы проведете мышью рядом с красным квадратом, вы увидите, что пересечение сработало до наведения края.

Что я делаю не так?

1 Ответ

2 голосов
/ 28 мая 2019

Обнаружение пересечения линий зависит от свойства .linePrecision Raycaster.

, например

raycaster.linePrecision = 0.1;
const intersects = raycaster.intersectObjects(scene.children);

Параметр должен быть установлен в зависимости от масштаба сцены. Значение 0,1 является эмпирическим значением, которое дает хорошие результаты для вашего примера. К сожалению, в документации нет дополнительной информации (возможно, я что-то упустил, но не нашел).

...