web-dev-qa-db-fra.com

Conversion de la position 3D en position d'écran 2D [r69!]

J'ai besoin du code Three.js pour convertir les coordonnées des objets 3D en coordonnées 2D dans un élément `` div '' afin de pouvoir placer les étiquettes de texte là où elles doivent être (sans que ces étiquettes soient à l'échelle/se déplaçant/pivotant avec le mouvement 3D). Malheureusement, tous les exemples que j'ai vus et essayés jusqu'à présent semblent utiliser des fonctions/techniques obsolètes. Dans mon cas, je crois que j'utilise r69 de Three.js.

Voici un exemple d'une technique "plus ancienne" qui ne fait que produire des erreurs pour moi:

Three.js: conversion de la position 3D en position d'écran 2D

Voici un extrait de code plus récent (?) Qui ne fournit pas de contexte suffisant pour que je puisse travailler, mais semble beaucoup plus propre:

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

26
Darren Enns

J'ai écrit pour mon projet la fonction suivante; il reçoit un THREE.Object3D instance et une caméra comme paramètres et renvoie la position sur l'écran.

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
    };

};

J'ai ensuite créé un THREE.Object3D juste pour maintenir la position div (elle est attachée à un maillage dans la scène) et si nécessaire, elle peut facilement être convertie en position d'écran en utilisant la fonction toScreenPosition et elle met à jour les coordonnées de l'élément div.

var proj = toScreenPosition(divObj, camera);

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

Ici un violon avec une démo.

34
meirm

Vous pouvez convertir une position 3D en coordonnées d'écran en utilisant un motif comme celui-ci:

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

22
WestLangley

Pour moi, cette fonction fonctionne (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;
    }
6
Julia Savinkova