2012-07-20 269 views
27

有關Three.js中的未投影的幾個優秀堆棧問題(1,2),即如何將瀏覽器中的(x,y)鼠標座標轉換爲(x,y,z)座標在Three.js畫布空間中。他們大多遵循這個模式:使用投影在Three.js中將世界座標轉換爲屏幕座標

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

我一直在試圖做反向 - 而不是從正在進行的「屏世界」的空間,從走「世界篩選」的空間。如果我知道Three.js中對象的位置,我如何確定它在屏幕上的位置?

似乎沒有任何已發佈的解決方案來解決這個問題。 Another question about this just showed up on Stack,但作者聲稱用一個不適合我的功能解決了這個問題。他們的解決方案不使用投影射線,並且我確信從2D到3D使用unprojectVector(),3D到2D解決方案將需要projectVector()。

也有this issue Github上打開。

任何幫助表示讚賞。

+0

非常感謝「屏幕到世界」翻譯模式。這是一個痛苦好幾個小時.. – LePhleg 2014-04-17 02:54:49

回答

31

嘗試這樣的:

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; 
+0

在另一個堆棧問題發佈此鏈接,也有解決方案。再次感謝! https://github.com/mrdoob/three.js/issues/78 – BishopZ 2012-07-24 15:13:12

+2

getPosition()已被棄用。改爲: var vector = projector.projectVector(new THREE.Vector3()。getPositionFromMatrix(object.matrixWorld),camera); – imbrizi 2013-06-02 01:17:29

+0

已被更新回答。謝謝@imbrizi! – mrdoob 2013-07-01 02:22:31

1

不能因爲丟失了信息,將(x,y)座標轉換爲(x,y,z)座標。你所引用的是如何找到場景中與(x,y)所產生的射線相交的所有物體上的所有點。

按照您的要求從「世界到屏幕」進行的是投影的全部內容,相當於渲染單個點(x,y,z)。你所做的是將投影矩陣應用於你的點(x,y,z)。據推測,Projector.projectVector(vector, camera)函數爲http://mrdoob.github.com/three.js/docs/49/#Projector,但由於它輸出的是3d矢量,因此我只能假設其中一個維度爲0,您可以忽略它。

3

對於現代three.js所(R75),向量可以投影到屏幕:

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

對於大家越來越deprecatedwarnings日誌中,接受的答案是舊的Three.js版本。現在,它更容易:

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); 
+0

「對象」未定義 – 2018-01-31 16:31:42

相關問題