Three.js: unproject - Как получить реальную позицию на «экране (вверху, слева)» конкретного 3D-объекта?

Созданный на 4 янв. 2011  ·  21Комментарии  ·  Источник: mrdoob/three.js

На примерах я знал, что есть способ спроецировать одну точку на экране (x, y) на точки «3d». Но я не могу понять, как это перевести обратно. Спасибо за любую подсказку.

Question

Самый полезный комментарий

На случай, если это все еще понадобится после обновления ...

function screenXY(obj){

  var vector = obj.clone();
  var windowWidth = window.innerWidth;
  var minWidth = 1280;

  if(windowWidth < minWidth) {
    windowWidth = minWidth;
  }

  var widthHalf = (windowWidth/2);
  var heightHalf = (window.innerHeight/2);

  vector.project(camera);

  vector.x = ( vector.x * widthHalf ) + widthHalf;
  vector.y = - ( vector.y * heightHalf ) + heightHalf;
  vector.z = 0;

  return vector;

};

Все 21 Комментарий

Вероятно, используя проектор, но MrDoob явно знает об этом больше :)

Хм, может быть, нам нужно иметь object3d.screen который будет Vector2 и обновлять его при каждом рендере?

Если этот объект object3D.screen Vector используется только для перевода object3D.position каждого объекта object3D в 2D, тогда не будет ли object3D.screen иметь слишком маленькое значение? Я имею в виду: я думаю, было бы более полезно иметь возможность переводить любую точку x, y, z любой сетки в позиции x, y, z в 2D-координаты.

Это, в свою очередь, означает, что невозможно заранее рассчитать каждую трехмерную позицию каждого объекта.

Имхо было бы полезно иметь, например, функцию THREE.3dto2d() которая принимает либо Vector3 (представляющий точку на сцене), либо Vector3 и объект (где Vector3 представляет точку на объекте).
Затем функция вычисляет трехмерную позицию в сцене.
Наконец, он берет камеру, ее положение, поворот, матрицу проекции и т. Д. И переводит точку обратно в 2D.

Думаю, камера тоже должна быть параметром функции ...

Что ж ... Projector.projectScene вроде уже это делает;)

Видишь ли, я знал, что это проектор ... ;-)

Есть пример, использующий это?

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

Я сейчас в отпуске, но я сделаю демонстрацию вспышки линз (или что-то в этом роде), как только вернусь (на следующей неделе).

Конечно, желаю вам приятного отдыха, и я с нетерпением жду нового демо! :-)

Хм, у меня это работало (r32), больше не работает в r35 ..

  toScreenXY: function(position, camera, jqdiv) {
    // converts 3D position to screen coords
    var pos = position.clone();
    projScreenMat = new THREE.Matrix4();
    projScreenMat.multiply( camera.projectionMatrix, camera.matrix);
    projScreenMat.multiplyVector3(pos);
    return { x: (pos.x+1)*jqdiv.width()/2 + jqdiv.offset().left, 
             y:(-pos.y+1)*jqdiv.height()/2 +jqdiv.offset().top }; 
  },

pos после projScreenMat.multiplyVector3(pos); раньше ограничивался диапазоном от -1 до 1 ((0,0) в центре обзора.), но теперь, кажется, неожиданно меняется ..

Да, camera.matrix нужно заменить на camera.matrixWorldInverse .
Попробуйте с этим:

toScreenXY: function ( position, camera, jqdiv ) {

    var pos = position.clone();
    projScreenMat = new THREE.Matrix4();
    projScreenMat.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
    projScreenMat.multiplyVector3( pos );

    return { x: ( pos.x + 1 ) * jqdiv.width() / 2 + jqdiv.offset().left,
         y: ( - pos.y + 1) * jqdiv.height() / 2 + jqdiv.offset().top };

}

Да, это сработало, не знал об изменениях матриц. Надеюсь, эта функция проекции ответила на вопрос Livedise.

Я думаю, это правильная ветка, чтобы задать свой вопрос о 3D Cube. У меня нарисован куб на холсте с интерактивными гранями. Куб свободно вращается по оси X и оси Y. Я хочу, чтобы лицевая сторона была максимально видимой, когда пользователь отпускает мышь, и сделать ее полностью видимой за счет автоматического поворота. Любая помощь в этом контексте будет очень благодарна.

Спасибо.

@ imrantariq2011 : На самом деле это не связано с этой проблемой, не могли бы вы открыть новую? Благодарю.

Для целей наложения текстур я хотел бы иметь возможность получать экранные координаты x, y для каждой вершины данной грани.

Я вижу, как это можно сделать, используя приведенную выше (toScreenXY: функцию), но сначала требуются преобразованные (масштабированные, перемещенные и повернутые) вершины для данной грани. Я потратил некоторое время на изучение Projector.projectScene, и мне интересно, есть ли более простой способ достижения указанной выше цели, и похоже, что object.matrixWorld.getPosition () может получить центроид объекта, а не вершины лица.

Да, приведенный выше код был для одного из. Если вам нужно спроецировать много точек, лучше всего вычленить биты кода из самого .projectScene() .

люди, которые попадают сюда, могут захотеть узнать об этом:

https://github.com/zachberry/threejs-tracking-3d-to-2d

Пользуюсь этим, работает:

функция toScreenXY (pos3D)
{
вар проектор = новый ТРИ.Проектор ();
var v = проектор.projectVector (pos3D, камера);
вар percX = (vx + 1) / 2;
var percY = (-vy + 1) / 2;
var left = percX * window.innerWidth;
var top = percY * window.innerHeight;

вернуть новый THREE.Vector2 (слева, вверху);
}

В пятницу, 1 августа 2014 г., 11:24, Артем Фитискин [email protected] написал:

Когда я использую toScreenXY, я получаю очень большие значения.
console.log (pos): // x: -1474.1436403989792, y: -730.829023361206, z: 3.0004000663757324
и после умножения на jqdiv функция возвращает очень большие x и y.
Что я делаю не так?
-
Ответьте на это письмо напрямую или просмотрите его на GitHub.

@arieljake

Как указано в руководстве , запросы справки следует направлять в stackoverflow . Эта доска предназначена для сообщений об ошибках и запросов функций.

ладно ... еще mr doob сам код поставил, ну и что дает?

@arieljake # 1979

На случай, если это все еще понадобится после обновления ...

function screenXY(obj){

  var vector = obj.clone();
  var windowWidth = window.innerWidth;
  var minWidth = 1280;

  if(windowWidth < minWidth) {
    windowWidth = minWidth;
  }

  var widthHalf = (windowWidth/2);
  var heightHalf = (window.innerHeight/2);

  vector.project(camera);

  vector.x = ( vector.x * widthHalf ) + widthHalf;
  vector.y = - ( vector.y * heightHalf ) + heightHalf;
  vector.z = 0;

  return vector;

};

Хорошо, очень старая проблема, но у меня был вложенный объект, который не работал с приведенным выше кодом.
Мой случай был таков: мне нужны реальные координаты x и y (и z) для вложенного объекта после рендеринга, поэтому я адаптировал приведенные выше примеры.
Пожалуйста, обратите внимание:

  1. Теперь вы указываете в качестве аргумента весь объект, а не только object.position в приведенных выше примерах.
  2. Также это будет работать только после того, как рендерер выполнил свою работу и вызвал
  3. Он также работает с невложенными объектами, но будет выполнять несколько вычислений слишком много.
  4. Он также дает вам экран-Z, который можно использовать для сортировки меток domElements или zSort.
    Относительное значение screen-z находится между 0 и 1 относительно передней и задней плоскостей отсечения камеры / рендерера, и это отлично подходит для моих целей (сортировка).
  5. Вы можете получить текущую ширину и высоту отрисовщика с помощью renderer.domElement.width и renderer.domElement.height.
scene.updateMatrixWorld(); 

и

parent.updateMatrixWorld(); 

`` js
функция nestedObjecttoScreenXYZ (объект, камера, ширина, высота)
{
var vector = new THREE.Vector3 ();
vector.setFromMatrixPosition (obj.matrixWorld);
var widthHalf = (ширина / 2);
var heightHalf = (высота / 2);
vector.project (камера);
vector.x = (vector.x * widthHalf) + widthHalf;
vector.y = - (vector.y * heightHalf) + heightHalf;
вектор возврата;
};



typical call:
```js
var screenpos=NestedObjecttoScreenXY(object,camera,renderer.domElement.width,renderer.domElement.height,true);

На всякий случай кто-нибудь столкнется с такой же проблемой.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги