【问题标题】:Trying to get mouse picking to work, but not sure where I'm lost试图让鼠标选择工作,但不知道我迷路了
【发布时间】:2015-10-19 09:42:51
【问题描述】:

我正在绘制一个深度为 0 的 10x10 方格,并试图突出显示鼠标所在的方格。我已经尝试过这里的教程:http://antongerdelan.net/opengl/raycasting.html 但我不知道我是否做得对。最后我得到了一个向量,但我不确定如何处理它。

这是正方形的屏幕截图(不知道它有什么帮助..)

http://postimg.org/image/dau330qwt/2

/* Enable attribute index 1 as being used */
    glEnableVertexAttribArray(1);
        float camera_z = 50;
        float camera_x = 0;
        float camera_y = 0;

        GLuint MatrixID = glGetUniformLocation(program, "MVP");
        GLuint ColorID = glGetUniformLocation(program, "input_color");

        int mouse_x;
        int mouse_y;


        while (1) {

                int window_width;
                int window_height;
                SDL_GetWindowSize(win, &window_width, &window_height);
                glm::mat4 Projection = glm::perspective(45.0f, ((float)window_width) / window_height, 0.1f, 100.0f);



                // printf("Camera at %f %f\n", camera_x, camera_y);
                glm::mat4 View = glm::lookAt(glm::vec3(camera_x,camera_y,camera_z), // camera position
                                                                         glm::vec3(camera_x,camera_y,0), // looking at
                                                                         glm::vec3(0,1,0)); // up



                int map_width = map.width();
                int map_height = map.height();

          /* Make our background black */
           glClearColor(0.0, 0.0, 0.0, 1.0);
            glClear(GL_COLOR_BUFFER_BIT);

                // go through my 10x10 map and
                for (int i = 0; i < map_width; i++) {
                        for ( int j = 0; j < map_height; j++) {

                                glm::mat4 Model = glm::translate(glm::mat4(1.0f), glm::vec3(i, j, 0.0f));              
                                glm::mat4 MVP = Projection * View * Model;
                                glm::vec3 color = random_color();

                                glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
                                glUniform3fv(ColorID, 1, &color[0]);
                            glDrawArrays(GL_LINE_LOOP, 0, 4);

                        }
                }


        /* Swap our buffers to make our changes visible */
                SDL_GL_SwapWindow(win);
                // printf("Window dimensions %d x %d\n", window_width, window_height);

                float normalized_mouse_x =  (2.0f * mouse_x) / window_width - 1.0f;
                float normalized_mouse_y = 1.0f - (2.0f * mouse_y) / window_height;

                printf("Normalized mouse position %f x %f\n", normalized_mouse_x, normalized_mouse_y);
                glm::vec3 normalized_mouse_vector = glm::vec3(normalized_mouse_x, normalized_mouse_y, 1.0f);

                glm::vec4 ray_clip = glm::vec4 (normalized_mouse_vector.x, normalized_mouse_vector.y, -1.0, 1.0);

                glm::vec4 ray_eye = glm::inverse(Projection) * ray_clip;
                ray_eye = glm::vec4(ray_eye.xy(), -1.0, 0.0);


                glm::vec3 ray_world = (glm::inverse(View) * ray_eye).xyz();

                ray_world = glm::normalize(ray_world);

                // this prints out values like: World ray: 0.000266, 0.000382, 1.000000
                printf("World ray: %f, %f, %f\n", ray_world.x, ray_world.y, ray_world.z);

                // l = -(camera_z / ray_world.z)
                float l = -(camera_z / ray_world.z);

                float mouse_world_x = camera_x + l * ray_world.x;
                float mouse_world_y = camera_y + l * ray_world.y;

                printf("mouse world %f, %f\n", mouse_world_x, mouse_world_y);

    }

使用 BDL 评论中的代码进行了更新。我现在得到的输出是:

归一化鼠标位置 0.087500 x 0.145833 世界射线:0.065083、0.081353、499.000000 世界射线:0.000130、0.000163、1.000000 鼠标世界 -0.006521, -0.008152

我希望“鼠标世界”行的数字在 1-10 范围内,而不是在 .00x 范围内,不过,根据上面的屏幕截图显示 x 和 y 范围为 0- 的正方形网格10.

感谢收看。

【问题讨论】:

  • 当你计算出射线后,你必须将它与几何体相交,并测试哪一个首先被击中。
  • 如果我知道我的平面是 z=0 处的 X/Y 平面,这会变得容易吗?
  • 如果您投票结束我的问题,请评论我可以做些什么来改进它。

标签: opengl matrix projection mouse-picking


【解决方案1】:

从点 C(在本例中为相机位置)开始的给定射线 r 与 z=0 的 x/y 平面的交点可以计算如下:

C ... Camera position [cx,cy,cz]
r ... ray direction [rx,ry,rz]

We are searching for the point on the ray that has z=0

C + l*r = [x,y,0]

=>

cz + l*rz = 0
l * rz = -cz
l = -(cz / rz)

The xy-coordinates of the intersection are now:

x = cx + l * rx
y = cy + l * ry

剩下要做的就是检查这个 (x,y) 坐标位于哪个矩形中。

【讨论】:

  • 我尝试实施你所说的,但我得到的结果比我预期的要低 3-4 个数量级。我根据您的答案以及它的输出使用我编写的代码更新了问题。任何额外的帮助将不胜感激。
  • 除了你的代码之外,我想我错过了教程中第 3 步的后半部分,因为我得到了它的工作。
  • 现在一切都很时髦。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 2017-02-06
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多