0

我在其他地方看到过同样的话题,但在大多数情况下,解决方案提供商正在处理 2D(正交)投影,因此他们忽略了 Z 值。我的世界有以下特点:

  1. 透视投影
  2. 相机的“向上”向量始终为 {0, 1, 0}
  3. 相机的 Z 坐标始终为正(朝向 Z=0)
  4. 我试图确定命中点的平面是 Z=0

我正在使用 gluUnProject 的端口,虽然我认为我的端口实现是合理的,但肯定有问题。不过,我希望向社区提出的问题是,我下面的算法是否正确。我正在确定 winZ=0(近平面)和 winZ=1(远平面)的世界坐标。然后我从这两个点确定射线,对其进行归一化,并确定该射线的 Z 坐标在什么值“t”处将为 0(在什么点与 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;
}
4

1 回答 1

0

我用完整版的 OpenGL(用 gluUnProject 完成)实现了相同的算法,并得到了想要的结果。该算法是合理的,我的 gluUnProject 实现不是。

于 2011-04-19T16:48:34.277 回答