2012-01-23 134 views
3

我希望能够点击触摸屏并使用触摸的点作为用于拾取的光线的起始坐标。将触摸屏坐标转换为iPhone上的Opengl世界坐标

如何将触摸屏返回的点转换为我可以在GL世界坐标系中使用的点?

搜索带来了许多令人困惑的可能性,包括使用gluUnProject以及大量关于它是否受支持以及如何移植的报告。

有人可以直接为我打好吗?

我正在使用Objective C,Xcode和我正在为iPhone编译。

回答

3

步骤0:获取gluUnproject:

需要它的报道属实。该功能为您完成所有繁重的工作。我知道MESA项目有一个实现,在没有修改的情况下,在iOS上几乎完美的工作。我不确定这是否仍然可用。除此之外,你只需要对它进行一些研究,或者推出自己的或者移植别人的。线性代数有点沉重,祝你好运。

第1步:转换从UIKit的坐标OpenGL的坐标:

这通常包括两件事情:

  1. 翻转Y坐标,因为UIKit的喜欢它的左上角的起源,而OpenGL喜欢它的左下角。

    touchLocation.y = [[self view] bounds].size.height - touchLocation.y; 
    
  2. 从“屏幕单位”转换为像素。这可以保持标准和视网膜显示设备的一致性。

    CGFloat scale = [[UIScreen mainScreen] scale]; 
    touchLocation.y *= scale; 
    touchLocation.y *= scale; 
    

第3步:使用gluUnproject你的坐标系转换:

gluUnproject()窗口空间中的三维点转换技术在世界空间中的三维点。因此,要得到一束光线,您需要调用两次:一次用于近剪裁平面,一次用于远剪裁平面。这会给你两点,从中你可以得到一个射线。要调用gluUnproject(),您需要访问您的2D视图坐标,当前的OpenGL视口,当前的OpenGL模型视图矩阵和当前的OpenGL投影矩阵。伪代码:

Vector3 near, far; 
gluUnProject(touchLocation.x, touchLocation.y, 0, _modelview, _projection, _viewport, &near.x, &near.y, &near.z); 
gluUnProject(touchLocation.x, touchLocation.y, 1, _modelview, _projection, _viewport, &far.x, &far.y, &far.z); 
return MakeRay(near, Vector3Subtract(far, near)); 
+0

我已经实施gluUnproject了。在你的伪代码中,viewportcoord是在步骤1之后触摸的屏幕坐标?为什么从远近计算射线的远点? – Dave

+0

@Dave是,viewportcoord是视口中的水龙头位置。为了清晰起见,我编辑了代码。在数学上,一条射线被定义为一个向量原点,以及一个从原点开始的向量方向。所以“射线的远点”不是绝对点,它是从近点开始的向量,指向远点,它被计算为(远近)。 –

+0

我的解决方案并不完美,但我认为这与我的射线碰撞方程相比,我的射线坐标更重要。谢谢你通过帮助解释make ray部分。 – Dave

相关问题