OpenGL 鼠标在 3D 空间中的位置
Posted
技术标签:
【中文标题】OpenGL 鼠标在 3D 空间中的位置【英文标题】:OpenGL Mouse position in 3D space 【发布时间】:2021-08-09 10:38:41 【问题描述】:我正在成功实施拾取射线球策略,以获取被点击的对象。 在图中,我选择了绿色立方体,左下角的顶点用一个红色的小立方体突出显示。
但我无法在平面 z 上移动立方体。 特别是,我的鼠标位置与我发现移动光标的顶点位置不匹配。它仅适用于顶视图(XY 平面)。
我正在疯狂地理解我错在哪里,但我无法理解。
我确定我没听懂,但是什么?
一开始,我存储了鼠标的 x,y 坐标(_init_drag_pos),然后我在之前的坐标和新的坐标之间做差异
dx = (mouse.X - _init_drag_pos.X); //pixel
dy = -1* (pmouse.Y - _init_drag_pos.Y); //pixel
//world position
vec3 res = glm.unProject(new vec3(mouse.Y, mouse.Y, 0), ModelViewMtx, ProjectionMtx, ViewPortVec);
我尝试了不同的方法,这是最有效的方法。阅读许多文章!
我想看与光标位置相同的小红方块!
有什么建议吗?
【问题讨论】:
请参阅 ***.com/a/51764105/2521214 、 ***.com/a/50908533/2521214 和 ***.com/a/52905600/2521214 以获得一些灵感。我不使用 GLM 或 unProject,所以我可能是错的,但我错过了传递给转换的任何深度/距离信息,所以 unProject 将如何知道如何转换您的鼠标(除非它自己来自深度缓冲区的glReadPixels
)。另外你是如何转换 dx,dy 的?
我会检查一下
请记住,这些转换不能以相对方式完成,因此您不能转换dx,dy
,而是必须转换实际和最后一个鼠标位置并从中获取dx,dy,dz
并将其用作平移向量对于移动...但是要注意之前鼠标位置的深度也必须来自上一帧...所以它更好地记住已经转换的鼠标位置
我知道,但我尝试了不同的方法,这是目前最好的方法。另一个想法是我正在寻找的点位于射线矢量上。如果我知道计划 z,我可以使用以下公式计算该点的确切位置:physicsforums.com/threads/…
您不需要知道 z 平面,您有 2D 屏幕位置(鼠标)和距焦点的距离(深度缓冲区),您只需通过反转透视和应用逆变换将其转换为 3D 位置...因此您从那里获得了鼠标目标点的 3D 位置,您只需应用按距离/透视缩放的平移矢量(鼠标拖动)...粗略的只有当锚点被对象(而不是背景像素)覆盖时才有效。
【参考方案1】:
最后我发现了错误......它在我的公式中。
这个想法很简单:我得到了光线矢量,然后将它与平面图相交。 3D Line Segment and Plane Intersection
vec3 v1 = glm.unProject(new vec3(winX, winY, 0f), mModelView, vp.ProjectionMtx, vp.GetVPVector());
vec3 v2 = glm.unProject(new vec3(winX, winY, 1f), mModelView, vp.ProjectionMtx, vp.GetVPVector());
//intersection in z=0
vec3 intersection = XglHelper.GetPointIn3DSegment(v1, v2, 0);
public vec3 GetPointIn3DSegment(vec3 p1, vec3 p2, float z)
float t = (z - p1.z) / (p2.z - p1.z);
float x = (1 - t) * p1.x + t * p2.x;
float y = (1 - t) * p1.y + t * p2.y;
return new vec3(x,y,z);
【讨论】:
以上是关于OpenGL 鼠标在 3D 空间中的位置的主要内容,如果未能解决你的问题,请参考以下文章
单击窗口 x 轴的末端时,通过鼠标单击在 OpenGL 中创建的光线不正确?