На примерах я знал, что есть способ спроецировать одну точку на экране (x, y) на точки «3d». Но я не могу понять, как это перевести обратно. Спасибо за любую подсказку.
Вероятно, используя проектор, но 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()
.
люди, которые попадают сюда, могут захотеть узнать об этом:
Пользуюсь этим, работает:
функция 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) для вложенного объекта после рендеринга, поэтому я адаптировал приведенные выше примеры.
Пожалуйста, обратите внимание:
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);
На всякий случай кто-нибудь столкнется с такой же проблемой.
Самый полезный комментарий
На случай, если это все еще понадобится после обновления ...