これと同じトピックが他の場所で説明されているのを見たことがありますが、ほとんどの場合、ソリューションプロバイダーは2D(正投影)投影を扱っているため、Z値を超えて光沢があります。私の世界には次のような特徴があります。
- 透視投影
- カメラの「上」ベクトルは常に{0、1、0}です。
- カメラのZ座標は常に正です(Z = 0に向かって)
- ヒットポイントを決定しようとしている平面はZ=0です
私はgluUnProjectのポートを使用しています。ポートの実装は適切だと思いますが、確かに何か問題がある可能性があります。しかし、私がコミュニティに尋ねたかったのは、以下の私のアルゴリズムが正しいように見えるかどうかです。winZ = 0(平面に近い)とwinZ = 1(平面に遠い)での世界座標を決定しています。次に、これら2つのポイントから光線を決定し、これを正規化し、この光線のZ座標が0になる値't'を決定します(どのポイントでZ = 0平面と交差するか、これが私が求めているものです)。 。ただし、問題は、原点(0,0,0)の近くをクリックすると機能しますが、原点から離れてクリックし始めるとすぐにエラーが大きくなります(たとえば、正しい世界座標が50、0 、 0以下の計算に基づくと、実際には85、0、0です。
以下の手順が適切であれば、gluUnProjectの実装の調査を開始できます。
public override void TouchesBegan (NSSet touches, UIEvent evt)
{
base.TouchesBegan (touches, evt);
var pt = (touches.AnyObject as UITouch).LocationInView(this);
int[] viewport = new int[4];
float[] proj = new float[16];
float[] model = new float[16];
GL.GetInteger(All.Viewport, viewport);
GL.GetFloat(All.ProjectionMatrix, proj);
GL.GetFloat(All.ModelviewMatrix, model);
float[] near = new float[3];
float[] far = new float[3];
Utils.gluUnProjectf(pt.X, viewport[3] - pt.Y, 0f, model, proj, viewport, out near);
Utils.gluUnProjectf(pt.X, viewport[3] - pt.Y, 1f, model, proj, viewport, out far);
Vector rayDirection = new Vector(far[0] - near[0], far[1] - near[1], far[2] - near[2]);
rayDirection.Normalize();
float t = (0 - near[2]) / rayDirection.dZ;
Vertex end = new Vertex();
end.X = near[0] + rayDirection.dX * t;
end.Y = near[1] + rayDirection.dY * t;
end.Z = 0;
}