C++ 使用glm::unproject()获取Z=0平面上的光标位置?
我试图只使用光标坐标来获取网格(z=0)的坐标(x,y)。经过长时间的搜索,我找到了使用C++ 使用glm::unproject()获取Z=0平面上的光标位置?,c++,opengl,cursor,glfw,glm-math,C++,Opengl,Cursor,Glfw,Glm Math,我试图只使用光标坐标来获取网格(z=0)的坐标(x,y)。经过长时间的搜索,我找到了使用glm::unproject的方法 首先,我使用回调函数获取光标坐标: void cursorCallback(GLFWwindow*窗口,双x,双y) { this->cursorCoordinate=glm::vec3(x,(this->windowHeight-y-1.0f),0.0f); } A然后转换这些坐标: glm::vec3光标坐标世界坐标() { glm::vec3 pointInitia
glm::unproject
的方法
首先,我使用回调函数获取光标坐标:
void cursorCallback(GLFWwindow*窗口,双x,双y)
{
this->cursorCoordinate=glm::vec3(x,(this->windowHeight-y-1.0f),0.0f);
}
A然后转换这些坐标:
glm::vec3光标坐标世界坐标()
{
glm::vec3 pointInitial=glm::unProject(
glm::vec3(this->cursorCoordinate.x,this->cursorCoordinate.y,0.0),
此->模型矩阵*此->视图矩阵,
这个->投影矩阵,
此->视口
);
glm::vec3 pointFinal=glm::取消项目(
glm::vec3(this->cursorCoordinate.x,this->cursorCoordinate.y,1.0),
此->模型矩阵*此->视图矩阵,
这个->投影矩阵,
此->视口
);
glm::vec3 vectorDirector=pointFinal-pointInitial;
双λ=(-pointInitial.y)/vectorDirector.y;
double x=pointInitial.x+lambda*vectorDirector.x;
双y=初始点z+λ*矢量控制器z;
返回glm::vec3(x,y,0.0f);
}
我使用ArcBall相机围绕指定轴旋转世界,因此这就是生成MVP矩阵的方式:
this->position=glm::vec3(0.0f、10.0f、5.0f);
这->向上=glm::vec3(0.0f,1.0f,0.0f);
这->注视=glm::vec3(0.0f,0.0f,0.0f);
此->fieldView=99.0f;
此->远距=100.0f;
该->近距离=0.1f;
该->模型矩阵=glm::mat4(1.0f);
this->viewMatrix=glm::lookAt(this->position,this->lookAt,this->up)*glm::rotate(glm::degrees(this->rotationAngle)*this->dragSpeed,this->rotationAxis);
此->projectionMatrix=glm::perspective(glm::radians(此->fieldView),1.0f,此->近距离,此->远距离);
但是有些事情出了问题,因为我没有得到正确的结果。查看此应用程序的打印:
每个正方形为1个单位,立方体在位置(0,0,0)处渲染。当a把光标放在(0,0),(1,1),(2,2),(3,3),(4,4),(5,5)时,我分别得到(0,5.7),(0.8,6.4),(1.6,6.9),(2.4,7.6),(3.2,8.2),(4.2,8.8)。这是预料不到的
- 为什么
延迟6个单位李>y
- 有必要根据旋转角度旋转结果
不是吗李>光标或坐标世界坐标
- 已检查视口是否与
-OKglViewport
- 检查opengl坐标(
向上,而不是Y
)-OKZ
glm::vec3(this->cursorCoordinate.x,this->cursorCoordinate.y,0.0)
到glm::vec3(this->cursorCoordinate.x,this->cursorCoordinate.y,1.0)
的光线与世界空间中的栅格相交,而不是(长方体的)模型空间相交。
您必须跳过此。modelMatrix:
glm::vec3 pointInitial=glm::unProject(
glm::vec3(this->cursorCoordinate.x,this->cursorCoordinate.y,0.0),
这个->视图矩阵,
这个->投影矩阵,
这个->视口);
glm::vec3 pointFinal=glm::取消项目(
glm::vec3(this->cursorCoordinate.x,this->cursorCoordinate.y,1.0),
这个->视图矩阵,
这个->投影矩阵,
这个->视口);
在任何情况下,
this->modelMatrix*this->viewMatrix
都是不正确的。如果不希望光线与模型空间中的对象相交,则光线必须是this->viewMatrix*this->modelMatrix
。矩阵乘法不正确。!=用于光线/平面相交测试的光线方向向量lineSegment=nearPoint-farPoint
(显然,平面方程为z=0
)指向错误的方向。它从远点
指向近点
。求反线段
以获得正确的光线方向。@httpdigest谢谢!但问题仍然存在。网格的z坐标(假设它位于xy平面上)必须在最终演算中起作用,而不仅仅是来自远点、近点的坐标。我的意思是,未投射的光线必须与网格所在的平面相交。@Ripi2我想我明白了,但不是。。。怎么了?谢谢你的帮助。你以前的回答都很好,帮助我解决了这个问题。对于未来的读者:记住检查视口、opengl坐标系,正确获取导向器向量并对其进行规格化。