Как получить видимую ширину и высоту объекта сетки ThreeJS в пикселях

#javascript #three.js

Вопрос:

Я сталкиваюсь с проблемой определения ширины и высоты видимого вида объекта сетки ThreeJS в единицах пикселей.

На скриншоте ниже вы можете видеть объекты, плавающие в 3D-пространстве, по щелчку мыши мне нужно определить, какую ширину и высоту они занимают в пикселях введите описание изображения здесь

Поскольку я довольно новичок в ThreeJS, мне требуется довольно много времени, чтобы найти решение, поэтому я был бы рад любой помощи.

Приведенная ниже функция показывает, какие подходы я пробовал.

 getObjectSizeInViewSpace(object){
      const size = new THREE.Vector3()
      const box = new THREE.Box3().setFromObject(object).getSize(size)
      size.project(this.camera)

      let halfWidth = window.innerWidth / 2;
      let halfHeight = window.innerHeight / 2;

      size.x = (size.x*halfWidth)
      size.y = (size.y*halfHeight)
      
      return new THREE.Vector2(size.x,size.y)
  }
 

Ответ №1:

Ты ищешь Vector3.project() . Это в основном принимает координаты мирового пространства (3D) и использует видовое окно камеры для преобразования в нормализованные координаты устройства, которые варьируются от [-1, 1] . Например x: -1 , это левая сторона экрана, а x: 1 это правая сторона. Таким образом, вам придется взять 4 вектора (верхний левый, верхний правый, нижний левый, нижний правый) вашей плоскости, чтобы рассчитать их размеры в пикселях в вашем браузере:

 // Get 3D positions of top left corner (assuming they're not rotated)
vec3 topLeft = new Vector3(
    plane.position.x - planeWidth / 2, 
    plane.position.y - planeHeight / 2,
    plane.positon.z
);

// This converts x, y, z to the [-1, 1] range
topLeft.project(camera);

// This converts from [-1, 1] to [0, windowWidth]
const topLeftX = (1   topLeft.x) / 2 * window.innerWidth;
const topLeftY = (1 - topLeft.y) / 2 * window.innerHeight;
 

Обратите topLeftY внимание, что значение инвертировано, так -y как в 3D пространство переходит y в пиксельные координаты. Сделайте это 4 раза (по одному разу для каждого угла), а затем вы можете вычесть (справа налево), чтобы получить ширину, и то же самое для высоты.

Комментарии:

1. Спасибо вам за направление, Маркизцо. Я извлек также topRightXY, как показано ниже. const topRight = новые ТРИ.Вектора3( объект.положение.x объект.геометрия.параметры.ширина / 2, объект.положение. y объект.геометрия.параметры.высота / 2, объект.положение.z ); Когда я вычитаю TopLeftX-topRightX, я не получаю правильное значение пикселя… Возможно, важным фактом, который я упустил в описании, является то, что если я нажимаю на объект, он перемещается в поле зрения. (центр камеры).

2. @Kreshnihasanaj Затем выполняет вычисления ПОСЛЕ того, как объект переместился в конечный пункт назначения.