我一直在一个OpenGL项目上处理鼠标选择器,并遵循本指南将我的2D鼠标位置转换为单击时的3D矢量。
我遇到的问题是选择对象/网格的计算中。如果我处于相机的原点位置,它似乎可以正常工作,但是一旦我开始使用相机移动,我计算出的边界球体的网格距离就脱离了位置。我认为我需要进行某种矩阵转换来解决此问题,但我无法弄清楚。我确实可以访问查看矩阵,但是我不确定是否应该在计算中实现它。
我问题的视频。无需单击声音就很难理解问题。当我能够通过单击旁边选择对象时,它在视觉上更加清晰。
我对计算的数据:
- 相机的位置(计算中的Rayorigin(
- 网格及其所有顶点以及网格在世界空间中的位置。
- 用与上述指南相同的方法计算的鼠标点击的3D向量。
我所做的第一件事是重新计算所有对象顶点,以适合世界空间中网格的位置。网格的位置也应该是网格的中心(至少在我之前链接的视频中(。
vertecies[i] = vec3(worldMatrix * vec4(vertecies[i], 1));
在我的第二步中,我将每个顶点与中心位置进行比较,并计算哪个顶点与中心最大。这个向量lenght我用作边界球的半径。
我对边界球测试的计算,raydir是鼠标位置向量,rayorigin是相机位置:
vec3 oc = rayOrigin - center;
float doc = dot(oc , rayDir);
if (doc > 0 || (dot(doc, doc) < radiusSquared)) return false; // no hit
vec3 a = oc - doc * rayDir;
float aSquared = dot(a, a);
if (aSquared > radiusSquared) return false; // no hit
return true; // hit
我的线性代数不是最好的,所以我希望你们能帮助我,并告诉我我在这里做错了什么。
我一直在研究这个问题,但指的是此网页。我发现您的参考很难从开发人员的角度遵循,并且您的数学与我的参考不一致。例如,您的第一个条件应为:
if (doc < 0) return false;
我不会研究您的代码,以查看它是否在数学上等效。但是,我建议您从我的参考底部的代码开始。另外,验证center
是与射线同一坐标系中球体的中心。
作为旁注:
当我遇到此类问题时,它总是帮助我在场景中绘制线条。在这种情况下,我会将射线转换为世界空间,并且不要忘记从反视图矩阵中提取的相机眼(在世界空间中(。我更喜欢将其直接从反向中提取出来,因此我不必质疑我是否依靠陈旧的缓存数据。