如果相机移动,则unproject不能用于对象拾取

时间:2016-11-11 15:51:48

标签: c++ opengl glfw orthographic

我正在尝试实施对象拣选系统,到目前为止,如果我不移动相机,它就能正常工作。

如果我不移动相机,它会在世界坐标中正确显示鼠标位置。我无法在截图中捕获鼠标,但它位于白色“圆圈”内,坐标位于图像的左上角。

enter image description here

但如果我将相机向下移动一点,它会再次在屏幕中央显示(0,0)。

enter image description here

我想要的并期望它是(0,-5)或其他什么。

这是我的代码:

double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
vec3 mouse_pos = vec3(float(mouse_x), float(mouse_y), 0.0f);
world_mouse_pos = unProject(mouse_pos, view, projection, vec4(0, 0, window_width, window_height));

mouse_offset.x = last_mouse_pos.x - world_mouse_pos.x;
mouse_offset.y = last_mouse_pos.y - world_mouse_pos.y;

last_mouse_pos.x = world_mouse_pos.x;
last_mouse_pos.y = world_mouse_pos.y;

m_state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE);
if (m_state == GLFW_PRESS){
    view = translate(view, vec3(-mouse_offset, 0.0f));
    glUniformMatrix4fv(view_loc, 1, GL_FALSE, &view.data[0][0]);
}

unProject功能:

inline vec3 unProject(const vec3 &pos, const mat4 &modelview, const mat4 &proj, const vec4 &viewport){
     mat4 inv = inverse(proj * modelview);
     vec4 temp = vec4(pos, 1.0f);
     temp.x = ((temp.x - viewport.x) / viewport.z);
     temp.y = ((temp.y - viewport.y) / viewport.w);
     temp = temp * 2 - 1;
     temp.y = - temp.y; 

     vec4 obj = inv * temp;

     return vec3(obj.x, obj.y, obj.z);
}

我正在使用正投影。尽管相机处于另一个位置,但基本上unProject总是返回相同的值。 我错过了什么?

1 个答案:

答案 0 :(得分:0)

如果其他人有同样的问题,我想出来了。所以我忘记了我的矩阵是行主要因此我的unProject函数是错误的,这是正确的函数:

inline vec3 unProject(const vec3 &pos, const mat4 &modelview, const mat4 &proj, const vec4 &viewport){
    mat4 inv = inverse(modelview * proj);

    vec4 temp = vec4(pos, 1.0f);
    temp.x = ((temp.x - viewport.x) / viewport.z);
    temp.y = ((temp.y - viewport.y) / viewport.w);
    temp = temp * 2 - 1;
    temp.y = -temp.y;

    vec4 obj = transpose(inv) * temp;

    obj /= obj.w;

    return vec3(obj.x, obj.y, obj.z);
}

基本上我改变了第一次乘法的顺序并转置了逆矩阵,以便能够将它乘以vec4。我还用obj.w划分了最终的vec4 obj,只是为了更通用的功能和在Perspective投影中工作,它在正交投影中没有区别。 我还对其他代码做了一些小改动。

double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
vec3 mouse_pos = vec3(float(mouse_x), float(mouse_y), 0.0f);
world_mouse_pos = unProject(mouse_pos, view, projection, vec4(0, 0, window_width, window_height));

mouse_offset.x = last_mouse_pos.x - world_mouse_pos.x;
mouse_offset.y = last_mouse_pos.y - world_mouse_pos.y;

last_mouse_pos.x = world_mouse_pos.x;
last_mouse_pos.y = world_mouse_pos.y;
mouse_offset = -mouse_offset;

m_state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE);
if (m_state == GLFW_PRESS){
    view = translate(view, vec3(mouse_offset*0.5, 0.0f));
    glUniformMatrix4fv(view_loc, 1, GL_FALSE, &view.data[0][0]);
}

我将mouse_offset乘以-1得到反转控件,这只是一个偏好,但我也将它乘以0.5,这基本上是平移相机的速度。