尝试在 OpenGL 3 中进行鼠标拾取时获取不正确的向量
Getting incorrect vectors when trying to do mouse picking in OpenGL 3
我正在尝试获取屏幕上光标所在位置的方向矢量,但它给了我很大的值而不是实际值。在进行鼠标拾取时,我的世界坐标得到的数字非常小,例如
Mouse is pointing at World X: 4.03225e-05 Y: -0.00048387 Z: -1
我是不是做错了什么,我已经从改编了这段代码。我正在使用 glm::intersectLineTriangle()
来测试直线是否指向有问题的三角形世界坐标。
相关代码如下:
double mouse_x, mouse_y;
glfwGetCursorPos(GL::g_window, &mouse_x, &mouse_y);
int width, height;
glfwGetFramebufferSize(GL::g_window, &width, &height);
// these positions must be in range [-1, 1] (!!!), not [0, width] and [0, height]
float mouseX = (float)mouse_x / ((float)width * 0.5f) - 1.0f;
float mouseY = (float)mouse_y / ((float)height * 0.5f) - 1.0f;
glm::mat4 invVP = glm::inverse(projection * view);
glm::vec4 screenPos = glm::vec4(mouseX, -mouseY, 1.0f, 1.0f);
glm::vec4 worldPos = invVP * screenPos;
glm::vec3 mouseClickVec = glm::normalize(glm::vec3(worldPos));
std::cout << "Mouse is pointing at World X: " << mouseClickVec.x << " Y: " << mouseClickVec.y << " Z: " << mouseClickVec.z << '\n';
glm::vec3 intersect;
if(glm::intersectLineTriangle(glm::vec3(0.0f, 0.0f, 0.0f), mouseClickVec, m_vertices_world[0], m_vertices_world[0], m_vertices_world[0], intersect))
{
std::cout << "Intersect at X: " << intersect.x << " Y: " << intersect.y << " Z: " << intersect.z << '\n';
setColor(glm::vec4(0.0f, 0.0f, 1.0f, 1.0f));
}
else
{
setColor(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
}
使用正交(平行)投影时,视点不是(0, 0, 0),(不在视野space当然也不在世界space)。您必须创建一条从近平面 (-1) 到远平面 (1) 的射线:
glm::vec4 worldPosFar = invVP * glm::vec4(mouseX, -mouseY, 1.0f, 1.0f);
glm::vec3 mouseClickVecFar = glm::normalize(glm::vec3(worldPosFar));
glm::vec4 worldPosNear = invVP * glm::vec4(mouseX, -mouseY, -1.0f, 1.0f);
glm::vec3 mouseClickVecNear = glm::normalize(glm::vec3(worldPosNear));
if (glm::intersectLineTriangle(mouseClickVecNear, mouseClickVecFar,
m_vertices_world[0], m_vertices_world[0], m_vertices_world[0], intersect))
{
// [...]
}
我正在尝试获取屏幕上光标所在位置的方向矢量,但它给了我很大的值而不是实际值。在进行鼠标拾取时,我的世界坐标得到的数字非常小,例如
Mouse is pointing at World X: 4.03225e-05 Y: -0.00048387 Z: -1
我是不是做错了什么,我已经从glm::intersectLineTriangle()
来测试直线是否指向有问题的三角形世界坐标。
相关代码如下:
double mouse_x, mouse_y;
glfwGetCursorPos(GL::g_window, &mouse_x, &mouse_y);
int width, height;
glfwGetFramebufferSize(GL::g_window, &width, &height);
// these positions must be in range [-1, 1] (!!!), not [0, width] and [0, height]
float mouseX = (float)mouse_x / ((float)width * 0.5f) - 1.0f;
float mouseY = (float)mouse_y / ((float)height * 0.5f) - 1.0f;
glm::mat4 invVP = glm::inverse(projection * view);
glm::vec4 screenPos = glm::vec4(mouseX, -mouseY, 1.0f, 1.0f);
glm::vec4 worldPos = invVP * screenPos;
glm::vec3 mouseClickVec = glm::normalize(glm::vec3(worldPos));
std::cout << "Mouse is pointing at World X: " << mouseClickVec.x << " Y: " << mouseClickVec.y << " Z: " << mouseClickVec.z << '\n';
glm::vec3 intersect;
if(glm::intersectLineTriangle(glm::vec3(0.0f, 0.0f, 0.0f), mouseClickVec, m_vertices_world[0], m_vertices_world[0], m_vertices_world[0], intersect))
{
std::cout << "Intersect at X: " << intersect.x << " Y: " << intersect.y << " Z: " << intersect.z << '\n';
setColor(glm::vec4(0.0f, 0.0f, 1.0f, 1.0f));
}
else
{
setColor(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
}
使用正交(平行)投影时,视点不是(0, 0, 0),(不在视野space当然也不在世界space)。您必须创建一条从近平面 (-1) 到远平面 (1) 的射线:
glm::vec4 worldPosFar = invVP * glm::vec4(mouseX, -mouseY, 1.0f, 1.0f);
glm::vec3 mouseClickVecFar = glm::normalize(glm::vec3(worldPosFar));
glm::vec4 worldPosNear = invVP * glm::vec4(mouseX, -mouseY, -1.0f, 1.0f);
glm::vec3 mouseClickVecNear = glm::normalize(glm::vec3(worldPosNear));
if (glm::intersectLineTriangle(mouseClickVecNear, mouseClickVecFar,
m_vertices_world[0], m_vertices_world[0], m_vertices_world[0], intersect))
{
// [...]
}