おー。私は実際に問題を解決しました。
まず、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) での画面入力 (クリック) を、オブジェクトが置かれているワールド座標に変換します。3 番目のパラメータwinz
は、実際にはクリックが発生した投影面です。ここで、0 は投影面の NearZ を意味します。
ピッキング関数を作成する方法は、上記の関数を使用して、遠くと近くのクリッピング プレーンで 2 点を非投影にすることです。
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
ピッキング レイを取得したら、ピッキング レイと「選択可能な」オブジェクトの「中心」との間の距離をテストするだけです。(もちろん、より洗練されたテスト アルゴリズムを使用することもできます)。