2011-06-07 56 views
0

我需要一些關於3D採摘的幫助。關於Android中3D採摘的問題(使用OpenGL ES 2)

我正在使用它的工作方式here。總之,我有什麼是:

normalizedPoint[0] = (x * 2/screenW) -1; 
normalizedPoint[1] = 1 - (y * 2/screenH); 
normalizedPoint[2] = ? 
normalizedPoint[3] = ? 

2和3,我不知道它應該是什麼(我把1,-1就像引用,它不工作)

然後,我的根對象(以下只是僞代碼):

matrix = perspective_matrix x model_matrix 
inv_matrix = inverse(matrix) 
outpoint = inv_matrix x normalizedPoint 

這就是我的,但它不工作,我收到外點甚至沒有靠近點,我假設點擊。我在網上搜索了一個多星期。但不知道如何解決它。幫幫我!

回答

3

哦。我其實解決了這個問題。

我首先,從glUnproject的源代碼修改爲具有以下:

public static Vec3 unProject(
     float winx, float winy, float winz, 
     Matrix44 resultantMatrix, 
     int width, int height){ 
    float[] m = new float[16], 
    in = new float[4], 
    out = new float[4]; 

    m = Matrix44.invert(resultantMatrix.get()); 

    in[0] = (winx/(float)width) * 2 - 1; 
    in[1] = (winy/(float)height) * 2 - 1; 
    in[2] = 2 * winz - 1; 
    in[3] = 1; 

    Matrix.multiplyMV(out, 0, m, 0, in, 0); 

    if (out[3]==0) 
     return null; 

    out[3] = 1/out[3]; 
    return new Vec3(out[0] * out[3], out[1] * out[3], out[2] * out[3]); 
} 

輸入到上面會在投影視域座標(即,屏輸入)的點。例如:

unProject(30, 50, 0, mvpMatrix, 800, 480) 

將轉化爲(30,50)輸入的屏幕(點擊)世界座標,其中對象正坐在。第三個參數winz實際上在發生點擊的投影平面上,這裏0表示投影平面的nearZ。

我做出選擇功能的方式,是通過unprojecting兩分,使用上述功能,在遠近裁剪平面,所以:

Vec3 near = unProject(30, 50, 0, mvpMatrix, 800, 480); 
Vec3 far = unProject(30, 50, 1, mvpMatrix, 800, 480); // 1 for winz means projected on the far plane 
Vec3 pickingRay = Subtract(far, near); // Vector subtraction 

當我們採摘射線,我在做什麼只是測試拾取射線與這些「可拾取」物體的「中心」之間的距離。 (當然,你可以有更復雜的測試算法)。

+0

This works great xandy!對此解決方案有兩點評論。對於Android,您需要將Android屏幕原點(屏幕左上角)和Opengl原點(左下角)之間的兼容性轉換爲winy(winy = screenheight-winy)。此外,如果您擁有相機的位置,則可以將一個電話保存到unProject,並使用相機的眼睛位置構建拾取光圈:Vec3 pickingRay =減(近,眼睛) – 2012-02-13 00:53:41

+0

woooohhhhoooo!謝謝!完善! – SAKrisT 2012-04-10 14:45:21