哦。我其實解決了這個問題。
我首先,從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
當我們採摘射線,我在做什麼只是測試拾取射線與這些「可拾取」物體的「中心」之間的距離。 (當然,你可以有更復雜的測試算法)。
This works great xandy!對此解決方案有兩點評論。對於Android,您需要將Android屏幕原點(屏幕左上角)和Opengl原點(左下角)之間的兼容性轉換爲winy(winy = screenheight-winy)。此外,如果您擁有相機的位置,則可以將一個電話保存到unProject,並使用相機的眼睛位置構建拾取光圈:Vec3 pickingRay =減(近,眼睛) – 2012-02-13 00:53:41
woooohhhhoooo!謝謝!完善! – SAKrisT 2012-04-10 14:45:21