2015-05-01 109 views
1

我有對象(很遠的地方)在三維場景,使用透視相機和2D HUD設置使用正交相機:three.js所:從三維視角場景轉換到2D正交HUD場景

this.scene = new THREE.Scene(); 
this.hud = new THREE.Scene(); 

this.camera = new THREE.PerspectiveCamera(30, aspect, front, back); 
this.camera.position.set(0,0,0); 

this.hudCamera = new THREE.OrthographicCamera (-this.windowHalfX,this.windowHalfX, this.windowHalfY, -this.windowHalfY, 1, 10); 
this.hudCamera.position.set(0,0,10); 

這裏是我的渲染循環:

updateFrame : function() { 
    this.renderer.clear(); 
    this.renderer.render(this.scene, this.camera); 
    this.renderer.clearDepth(); 
    this.renderer.render(this.hud, this.hudCamera); 
    }, 

我如何才能找到在HUD對象的位置,使用在3D場景中的位置?

+0

你的問題沒有任何意義,因爲你的正交相機參數是以像素爲單位。閱讀http://stackoverflow.com/questions/17558085/three-js-orthographic-camera/17567292#17567292。 – WestLangley

+0

我已經意識到這一點。我有一個解決方案,我會立即發佈。 – Boogiechillin

回答

2

爲了找到一個3D對象的2D HUD位置(使用three.js所版本R71),可以執行以下操作,這是我從this post改性:

findHUDPosition : function (obj) { 
     var vector = new THREE.Vector3(); 

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

     vector.x = (vector.x * this.windowHalfX); 
     vector.y = (vector.y * this.windowHalfY); 

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

參數obj是對象你試圖找到在HUD中的位置。

vector.project(this.camera);通過相機的near平面將物體的矢量繪製到位置this.camera

vector分量的新值是投影向量和this.camera的近平面的交點。

儘管座標是在three.js的世界座標系中,所以我們必須快速轉換爲像素座標,以便放大到我們畫布的大小。

vector.x = (vector.x * this.windowHalfX); 
    vector.y = (vector.y * this.windowHalfY); 

上述的轉換是對於其中HUD的座標系統具有位於屏幕的中心爲原點(0,0)的設置,並且具有半畫布的分辨率的最大值。例如,如果您的畫布是1024 x 768像素,則右上角的位置將是(512,384)。

對於典型的屏幕座標系統,右下角將是(1024,768),屏幕中間是(512,384)。要進行此設置,可以使用以下轉換,如this post中所示。

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

請注意,現在z座標並不重要,因爲我們在2D中。

您要做的最後一件事是確保您以2D顯示的對象實際上對透視攝影機可見。這與查看對象是否落在this.camera的平截頭體內一樣簡單。 source for following code

checkFrustrum : function (obj) { 
    var frustum = new THREE.Frustum(); 
    var projScreenMatrix = new THREE.Matrix4(); 

    this.camera.updateMatrix(); 
    this.camera.updateMatrixWorld(); 

    projScreenMatrix.multiplyMatrices(this.camera.projectionMatrix, this.camera.matrixWorldInverse); 

    frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(this.camera.projectionMatrix, 
                this.camera.matrixWorldInverse)); 
    return frustum.containsPoint (obj.position); 
} 

如果不這樣做,你可以有一個對象,它是攝像機被註冊爲2D場景中可見背後(這會帶來問題的對象跟蹤)。更新obj的矩陣和矩陣世界也是很好的做法。