Zamieniam współrzędne świata na współrzędne ekranu w trzy.js za pomocą projekcji

Istnieje kilka doskonałych pytań dotyczących stosu (1, 2) o nieprojekowaniu za trzy.js, czyli jak skonwertować (X,y) współrzędne myszy w przeglądarce na (X,y, Z) współrzędne w trzech.przestrzeń js canvas. Najczęściej podążają za tym wzorem:

    var elem = renderer.domElement, 
        boundingRect = elem.getBoundingClientRect(),
        x = (event.clientX - boundingRect.left) * (elem.width / boundingRect.width),
        y = (event.clientY - boundingRect.top) * (elem.height / boundingRect.height);

    var vector = new THREE.Vector3( 
        ( x / WIDTH ) * 2 - 1, 
        - ( y / HEIGHT ) * 2 + 1, 
        0.5 
    );

    projector.unprojectVector( vector, camera );
    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
    var intersects = ray.intersectObjects( scene.children );
[1]}starałem się zrobić coś odwrotnego - zamiast przechodzić z "ekranu do świata", przejść z "świata do ekranu". Jeśli znam pozycję obiektu w trzech.js, jak określić jego pozycję na ekran?

Wydaje się, że nie ma żadnego opublikowanego rozwiązania tego problemu. kolejne pytanie na ten temat pojawiło się właśnie na stosie, ale autor twierdzi, że rozwiązał problem z funkcją, która nie działa dla mnie. Ich rozwiązanie nie używa rzutowanego promienia i jestem prawie pewien, że ponieważ 2D do 3D używa unprojectVector(), rozwiązanie 3D do 2D będzie wymagało projectVector().

Istnieje również ten problem otwarty na Githubie.

Każda pomoc jest doceniam to.

Author: Community, 2012-07-21

4 answers

Spróbuj z tym:

var width = 640, height = 480;
var widthHalf = width / 2, heightHalf = height / 2;

var vector = new THREE.Vector3();
var projector = new THREE.Projector();
projector.projectVector( vector.setFromMatrixPosition( object.matrixWorld ), camera );

vector.x = ( vector.x * widthHalf ) + widthHalf;
vector.y = - ( vector.y * heightHalf ) + heightHalf;
 31
Author: mrdoob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-18 23:52:36

Dla nowoczesnej Trójki.js (r75), wektor może być rzutowany na ekran za pomocą:

var width = window.innerWidth, height = window.innerHeight;
var widthHalf = width / 2, heightHalf = height / 2;

var pos = object.position.clone();
pos.project(camera);
pos.x = ( pos.x * widthHalf ) + widthHalf;
pos.y = - ( pos.y * heightHalf ) + heightHalf;
 5
Author: dkobozev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-19 01:26:17

Dla wszystkich dostających deprecated lub warnings dzienniki, akceptowana odpowiedź jest dla starszych trzech.wersje js. Teraz jest jeszcze łatwiej z:

let pos = new THREE.Vector3();
pos = pos.setFromMatrixPosition(object.matrixWorld);
pos.project(camera);

let widthHalf = canvasWidth / 2;
let heightHalf = canvasHeight / 2;

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

console.log(pos);
 3
Author: martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-31 21:43:01

Ty nie możesz Konwertować współrzędnych (x,y) na (X,y,z), ponieważ tracisz informacje. To, co zacytowałeś, to jak znaleźć wszystkie punkty na wszystkich obiektach w scenie, które przecinają promień generowany przez (x, y).

Przejście od" świata do ekranu", o które prosisz, jest tym, o co chodzi w projekcji i jest równoznaczne z renderowaniem pojedynczego punktu (x, y,z). Tym, co robisz, jest zastosowanie macierzy projekcji do punktu (x, y,z). Jest to prawdopodobnie funkcja {[0] } w http://mrdoob.github.com/three.js/docs/49/#Projector , ale ze względu na to, że wyprowadza wektor 3d, mogę tylko założyć, że jeden z wymiarów jest równy 0 i można go zignorować.

 1
Author: ninjagecko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-20 20:53:12