我希望能够点击触摸屏并使用触摸的点作为用于拾取的光线的起始坐标。
如何将触摸屏幕返回的点转换为我可以在GL世界坐标中使用的点?
搜索带来了许多令人困惑的可能性,包括使用gluUnProject以及关于它是否受支持以及如何移植它的大量报告。
有人可以直接为我准备吗?
我正在使用Objective C,Xcode,而我正在为iphone编译。
答案 0 :(得分:3)
第0步:获取gluUnproject:
需要它的报告是真实的。该功能为您完成了所有繁重的工作。我知道MESA项目在某一点上有一个实现,几乎完美地在iOS上工作而没有修改。我不确定这是否仍然可用。除此之外,你只需要对它做一些研究,或者自己滚动或移植别人的。它在线性代数上有点沉重,祝你好运。
步骤1:从UIKit坐标转换为OpenGL坐标:
这通常涉及两件事:
翻转Y坐标,因为UIKit喜欢它的左上角,而OpenGL喜欢它的起源位于左下角。
touchLocation.y = [[self view] bounds].size.height - touchLocation.y;
从“屏幕单位”转换为像素。这样可以使标准和视网膜显示设备保持一致。
CGFloat scale = [[UIScreen mainScreen] scale];
touchLocation.y *= scale;
touchLocation.y *= scale;
第3步:在转换后的坐标上使用gluUnproject:
gluUnproject()
从技术上将窗口空间中的3D点转换为世界空间中的3D点。因此,要获得光线,您需要调用两次:一次用于近剪裁平面,一次用于远剪裁平面。这将给你两点,你可以从中得到一条光线。要调用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));