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 空间中的位置的主要内容,如果未能解决你的问题,请参考以下文章

用鼠标单击 OpenGL 拖动 3d 对象

单击窗口 x 轴的末端时,通过鼠标单击在 OpenGL 中创建的光线不正确?

OpenGL - 将变换应用于 3D 空间中的多边形

3D 空间中的 OpenGL 2D 文本 [C++/GLM] 矩阵乘法

OpenGL坐标转换场景到世界

OpenGL - 在 3D 空间中裁剪