2012-07-17 125 views
3

這個問題有很多答案,但我不確定它們是否都與XTK一起工作,比如在Three.JS中看到多個答案,當然還有XTK和Three.JS顯然沒有相同的API。使用光線和Matrix似乎非常類似於其他框架的許多其他解決方案,但我仍然沒有在這裏抓住一個可能的解決方案。現在只需找到座標X,Y和Z並將它們記錄到Console.Log就可以了,後來我希望創建一個標題/工具提示來顯示信息,但還有其他方法可以顯示它。但是至少有人能告訴我這是否可以使用射線與物體發生碰撞?我不確定碰撞在XTK中如何與網格或任何其他文件一起工作。現在任何提示都會很棒!從屏幕座標查找世界座標

+1

這也是我從我的研究中學到的信息。所以基本上我們做一個Unproject函數來將2d轉換爲3d。無論我們的鼠標在屏幕上(從我的標題/工具提示想法),那就是光線垂直投射到「3D世界」中的「屏幕」的位置。然後我們找到與射線相交的最接近的三角形,給出我們的三維座標。沒有? – Karijuana 2012-07-18 17:08:50

+1

你確定光線投射到屏幕上嗎?我認爲它是通過反投影視圖矩陣在屏幕上的(x,y)座標乘積給出的方向上投射的。所以,當你有方向時,你試圖通過使用二分法找到與物體三角形的交點(如果可能的話,邊界框加快速度) – Ricola3D 2012-07-23 08:15:18

+0

我也需要它,所以我也會嘗試一些東西。 – Ricola3D 2012-07-23 08:20:08

回答

4

這裏是我的功能XTK到unproject。請告訴我,如果你看到錯誤。現在由此產生的點和相機位置,我應該能夠找到我的交點。爲了使下一步的計算速度更快,我將在pick事件中調用它,所以我只需要嘗試與給定對象的交集。如果我有時間,我也會嘗試測試邊界框。

注意:最後一行不是必需的,我可以在光線而不是點上工作。

X.camera3D.prototype.unproject = function (x,y) { 

    // get the 4x4 model-view matrix 
    var mvMatrix = this._view; 

    // create the 4x4 projection matrix from the flatten gl version 
    var pMatrix = new X.matrix(4,4); 
    for (var i=0 ; i<16 ; i++) { 
    pMatrix.setValueAt(i - 4*Math.floor(i/4), Math.floor(i/4), this._perspective[i]); 
    } 
    // compute the product and inverse it 
    var mvpMatrxix = pMatrix.multiply(mwMatrix); /** Edit : wrong product corrected **/ 
    var inverse_mvpMatrix = mvpMatrxix.getInverse(); 
    if (!goog.isDefAndNotNull(inverse_mvpMatrix)) throw new Error("Could not inverse the transformation matrix."); 

    // check if x & y are map in [-1,1] interval (required for the computations) 
    if (x<-1 || x>1 || y<-1 || y>1) throw new Error("Invalid x or y coordinate, it must be between -1 and 1"); 

    // fill the 4x1 normalized (in [-1,1]⁴) vector of the point of the screen in word camera world's basis 
    var point4f = new X.matrix(4,1); 
    point4f.setValueAt(0, 0, x); 
    point4f.setValueAt(1, 0, y); 
    point4f.setValueAt(2, 0, -1.0); // 2*?-1, with ?=0 for near plan and ?=1 for far plan 
    point4f.setValueAt(3, 0, 1.0); // homogeneous coordinate arbitrary set at 1 

    // compute the picked ray in the world's basis in homogeneous coordinates 
    var ray4f = inverse_mvpMatrix.multiply(point4f); 
    if (ray4f.getValueAt(3,0)==0) throw new Error("Ray is not valid."); 
    // return in not-homogeneous coordinates to compute the 3D direction vector 
    var point3f = new X.matrix(3,1); 
    point3f.setValueAt(0, 0, ray4f.getValueAt(0, 0)/ray4f.getValueAt(3, 0)); 
    point3f.setValueAt(1, 0, ray4f.getValueAt(1, 0)/ray4f.getValueAt(3, 0)); 
    point3f.setValueAt(2, 0, ray4f.getValueAt(2, 0)/ray4f.getValueAt(3, 0)); 
    return point3f; 
}; 

編輯

Here,在我的回購,你可以找到在camera3D.js功能和renderer3D.js在XTK高效的3D採摘。

+0

我意識到你使用的概念在這裏是完美的,但我是一個相當新的編程,所以我不完全確定這會正常工作。我相信海恩想回顧一下。 – Karijuana 2012-07-23 13:48:21

+0

這看起來不錯,你測試過嗎?如果是的話,你可以發送拉請求嗎? – haehn 2012-07-24 13:55:42

+0

我正在測試,但目前它似乎沒有給予好射線(我繪製了相機的位置和一條射線從計算出的方向進行測試) – Ricola3D 2012-07-24 14:43:00

2

現在這是不容易的。我想你可以抓住相機的視圖矩陣來計算位置。如果你這樣做,那將它作爲內置功能帶回到XTK將會很棒!

目前,僅採摘的對象可能是這樣的(r是X.renderer3D):

/** 
* Picks an object at a position defined by display coordinates. If 
* X.renderer3D.config['PICKING_ENABLED'] is FALSE, this function always returns 
* -1. 
* 
* @param {!number} x The X-value of the display coordinates. 
* @param {!number} y The Y-value of the display coordinates. 
* @return {number} The ID of the found X.object or -1 if no X.object was found. 
*/ 
var pick = r.pick($X, $Y); 
+0

好吧,如果我找到解決方案,我會繼續關注它並回到ya。 – Karijuana 2012-07-18 14:27:15

+0

我在Github上發現了另一個處理矩陣和向量操作的JS庫。這兩個都是「屏幕座標到世界座標」所需要的。問題現在。這解釋了爲什麼他們需要我在這個問題下的評論。 https://github.com/toji/gl-matrix – Karijuana 2012-07-18 18:33:14

+0

是的測試你可以使用這些,但在XTK我們使用谷歌封閉庫,它有很多vec和mat操作以及 – haehn 2012-07-19 14:52:55