使用 glm::unproject() 获取 Z = 0 平面上的光标位置?
Get cursor position on Z = 0 plane using glm::unproject()?
我正在尝试仅使用光标坐标获取网格 (z = 0) 的坐标 (x,y)。经过长时间的搜索,我发现使用 glm::unproject
.
可以做到这一点
首先我使用回调获取光标坐标:
void cursorCallback(GLFWwindow *window, double x, double y)
{
this->cursorCoordinate = glm::vec3(x, (this->windowHeight - y - 1.0f), 0.0f);
}
然后转换这些坐标:
glm::vec3 cursorCoordinatesToWorldCoordinates()
{
glm::vec3 pointInitial = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 0.0),
this->modelMatrix * this->viewMatrix,
this->projectionMatrix,
this->viewPort
);
glm::vec3 pointFinal = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 1.0),
this->modelMatrix * this->viewMatrix,
this->projectionMatrix,
this->viewPort
);
glm::vec3 vectorDirector = pointFinal - pointInitial;
double lambda = (-pointInitial.y) / vectorDirector.y;
double x = pointInitial.x + lambda * vectorDirector.x;
double y = pointInitial.z + lambda * vectorDirector.z;
return glm::vec3(x, y, 0.0f);
}
我使用 ArcBall 相机围绕指定轴旋转世界,这就是我生成 MVP 矩阵的方式:
this->position = glm::vec3(0.0f, 10.0f, 5.0f);
this->up = glm::vec3(0.0f, 1.0f, 0.0f);
this->lookAt = glm::vec3(0.0f, 0.0f, 0.0f);
this->fieldView = 99.0f;
this->farDistance = 100.0f;
this->nearDistance = 0.1f;
this->modelMatrix = glm::mat4(1.0f);
this->viewMatrix = glm::lookAt(this->position, this->lookAt, this->up) * glm::rotate(glm::degrees(this->rotationAngle) * this->dragSpeed, this->rotationAxis);
this->projectionMatrix = glm::perspective(glm::radians(this->fieldView), 1.0f, this->nearDistance, this->farDistance);
但是出了点问题,因为我没有得到正确的结果。看看这个应用程序的印刷品:
每个正方形为1个单位,立方体在位置(0, 0, 0)处渲染。当 rotationAngle = 0
将光标放在 (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) 分别。这不是预期的。
- 为什么
y
延迟了6个单位?
- 有必要根据
rotationAngle
旋转结果 cursorCoordinatesToWorldCoordinates
不是吗?
--
我已经做过了:
- 检查视口是否与
glViewport
匹配 - OK
- 检查了 opengl 坐标(
Y
已启动,而不是 Z
)- OK
您希望从 glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 0.0)
到 glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 1.0)
的射线与世界 space 中的网格相交,而不是模型 space(长方体)。
你必须跳过 this.modelMatrix
:
glm::vec3 pointInitial = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 0.0),
this->viewMatrix,
this->projectionMatrix,
this->viewPort);
glm::vec3 pointFinal = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 1.0),
this->viewMatrix,
this->projectionMatrix,
this->viewPort);
无论如何this->modelMatrix * this->viewMatrix
都是不正确的。如果你想让光线与模型 space 中的物体相交,那么它必须是 this->viewMatrix * this->modelMatrix
。矩阵乘法不是Commutative.
我正在尝试仅使用光标坐标获取网格 (z = 0) 的坐标 (x,y)。经过长时间的搜索,我发现使用 glm::unproject
.
首先我使用回调获取光标坐标:
void cursorCallback(GLFWwindow *window, double x, double y)
{
this->cursorCoordinate = glm::vec3(x, (this->windowHeight - y - 1.0f), 0.0f);
}
然后转换这些坐标:
glm::vec3 cursorCoordinatesToWorldCoordinates()
{
glm::vec3 pointInitial = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 0.0),
this->modelMatrix * this->viewMatrix,
this->projectionMatrix,
this->viewPort
);
glm::vec3 pointFinal = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 1.0),
this->modelMatrix * this->viewMatrix,
this->projectionMatrix,
this->viewPort
);
glm::vec3 vectorDirector = pointFinal - pointInitial;
double lambda = (-pointInitial.y) / vectorDirector.y;
double x = pointInitial.x + lambda * vectorDirector.x;
double y = pointInitial.z + lambda * vectorDirector.z;
return glm::vec3(x, y, 0.0f);
}
我使用 ArcBall 相机围绕指定轴旋转世界,这就是我生成 MVP 矩阵的方式:
this->position = glm::vec3(0.0f, 10.0f, 5.0f);
this->up = glm::vec3(0.0f, 1.0f, 0.0f);
this->lookAt = glm::vec3(0.0f, 0.0f, 0.0f);
this->fieldView = 99.0f;
this->farDistance = 100.0f;
this->nearDistance = 0.1f;
this->modelMatrix = glm::mat4(1.0f);
this->viewMatrix = glm::lookAt(this->position, this->lookAt, this->up) * glm::rotate(glm::degrees(this->rotationAngle) * this->dragSpeed, this->rotationAxis);
this->projectionMatrix = glm::perspective(glm::radians(this->fieldView), 1.0f, this->nearDistance, this->farDistance);
但是出了点问题,因为我没有得到正确的结果。看看这个应用程序的印刷品:
每个正方形为1个单位,立方体在位置(0, 0, 0)处渲染。当 rotationAngle = 0
将光标放在 (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) 分别。这不是预期的。
- 为什么
y
延迟了6个单位? - 有必要根据
rotationAngle
旋转结果cursorCoordinatesToWorldCoordinates
不是吗?
--
我已经做过了:
- 检查视口是否与
glViewport
匹配 - OK - 检查了 opengl 坐标(
Y
已启动,而不是Z
)- OK
您希望从 glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 0.0)
到 glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 1.0)
的射线与世界 space 中的网格相交,而不是模型 space(长方体)。
你必须跳过 this.modelMatrix
:
glm::vec3 pointInitial = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 0.0),
this->viewMatrix,
this->projectionMatrix,
this->viewPort);
glm::vec3 pointFinal = glm::unProject(
glm::vec3(this->cursorCoordinate.x, this->cursorCoordinate.y, 1.0),
this->viewMatrix,
this->projectionMatrix,
this->viewPort);
无论如何this->modelMatrix * this->viewMatrix
都是不正确的。如果你想让光线与模型 space 中的物体相交,那么它必须是 this->viewMatrix * this->modelMatrix
。矩阵乘法不是Commutative.