Подтвердить что ты не робот

Преобразование трехмерного положения в положение 2d экрана [r69!]

Мне нужен код Three.js для преобразования координат трехмерных объектов в 2d в элементе div, чтобы я мог размещать текстовые метки там, где они должны быть (без этих меток масштабирования/перемещения/вращения вместе с движением 3D), К сожалению, все примеры, которые я видел и пытались до сих пор, похоже, используют устаревшие функции/методы. В моем случае, я считаю, что я использую r69 из Three.js.

Вот пример "более старого" метода, который просто создает ошибки для меня:

Three.js: преобразование позиции 3d в положение 2d

Вот фрагмент некоторого более нового кода (?), который не обеспечивает достаточный контекст для меня, чтобы работать, но выглядит намного чище:

https://github.com/mrdoob/three.js/issues/5533

4b9b3361

Ответ 1

Я написал для своего проекта следующую функцию; он получает экземпляр THREE.Object3D и камеру в качестве параметров и возвращает позицию на экране.

function toScreenPosition(obj, camera)
{
    var vector = new THREE.Vector3();

    var widthHalf = 0.5*renderer.context.canvas.width;
    var heightHalf = 0.5*renderer.context.canvas.height;

    obj.updateMatrixWorld();
    vector.setFromMatrixPosition(obj.matrixWorld);
    vector.project(camera);

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

    return { 
        x: vector.x,
        y: vector.y
    };

};

Затем я создал THREE.Object3D только для того, чтобы удерживать позицию div (она привязана к сетке в сцене), и при необходимости ее можно легко преобразовать в позицию экрана с помощью функции toScreenPosition, и она обновит координаты div элемент.

var proj = toScreenPosition(divObj, camera);

divElem.style.left = proj.x + 'px';
divElem.style.top = proj.y + 'px';

Здесь сценарий с демонстрацией.

Ответ 2

Вы можете преобразовать трехмерную позицию в координаты экрана, используя такой шаблон:

var vector = new THREE.Vector3();
var canvas = renderer.domElement;

vector.set( 1, 2, 3 );

// map to normalized device coordinate (NDC) space
vector.project( camera );

// map to 2D screen space
vector.x = Math.round( (   vector.x + 1 ) * canvas.width  / 2 );
vector.y = Math.round( ( - vector.y + 1 ) * canvas.height / 2 );
vector.z = 0;

three.js r.69

Ответ 3

Для меня эта функция работает (Three.js version 69):

function createVector(x, y, z, camera, width, height) {
        var p = new THREE.Vector3(x, y, z);
        var vector = p.project(camera);

        vector.x = (vector.x + 1) / 2 * width;
        vector.y = -(vector.y - 1) / 2 * height;

        return vector;
    }