Changeset 33a9664 in opengl-game


Ignore:
Timestamp:
Dec 16, 2017, 4:45:49 AM (7 years ago)
Author:
Dmitry Portnoy <dmitry.portnoy@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
1099b95
Parents:
c62eee6
Message:

Debug object detection for mouse clicks

Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • new-game.cpp

    rc62eee6 r33a9664  
    3131vec3 face_point1, face_point2, face_point3;
    3232
     33bool clicked = false;
     34int colors_i = 0;
     35
    3336mat4 view_mat;
    3437mat4 proj_mat;
     38
     39bool insideTriangle(vec3 p, vec3 v1, vec3 v2, vec3 v3);
    3540
    3641GLuint loadShader(GLenum type, string file);
     
    5156      float x = (2.0f*mouse_x) / width - 1.0f;
    5257      float y = 1.0f - (2.0f*mouse_y) / height;
    53 
    54       vec4 ray_clip = vec4(x, y, -1.0f, 1.0f);
     58      cout << "x: " << x << ", y: " << y << endl;
     59
     60      // Since the projection matrix gets applied before the view matrix,
     61      // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
     62
     63      // When getting the ray direction, you can use near and fov to get the
     64      // coordinates
     65
     66      vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
    5567      vec4 ray_eye = inverse(proj_mat) * ray_clip;
    5668      ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
    5769      vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
     70
     71      /* LATEST NOTES:
     72       *
     73       * Normalizing the world ray caused issues, although it should make sense with the projection
     74       * matrix, since the z coordinate has meaning there.
     75       *
     76       * Now, I need to figure out the correct intersection test in 2D space
     77       * Also, need to check that the global triangle points are correct
     78       */
     79
     80      // since ray_world is the end result we want anyway, we probably don't need to add cam_pos to
     81      // it, only to subtract it later
    5882
    5983      vec3 click_point = cam_pos + ray_world;
     
    6791       */
    6892
     93      // upper right corner is 1, 1 in opengl
     94
    6995      cout << "Converted -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
    7096      cout << "Camera -> (" << cam_pos.x << "," << cam_pos.y << "," << cam_pos.z << ")" << endl;
     
    84110       */
    85111
     112      vec3 fp1 = face_point1;
     113      vec3 fp2 = face_point2;
     114      vec3 fp3 = face_point3;
     115
    86116      cout << "Points on the plane" << endl;
    87       cout << "(" << face_point1.x << "," << face_point1.y << "," << face_point1.z << ")" << endl;
    88       cout << "(" << face_point2.x << "," << face_point2.y << "," << face_point2.z << ")" << endl;
    89       cout << "(" << face_point3.x << "," << face_point3.y << "," << face_point3.z << ")" << endl;
     117      cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
     118      cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
     119      cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
     120
     121      float pa = (fp2.y-fp1.y)*(fp3.z-fp1.z) - (fp3.y-fp1.y)*(fp2.z-fp1.z);
     122      float pb = (fp2.z-fp1.z)*(fp3.x-fp1.x) - (fp3.z-fp1.z)*(fp2.x-fp1.x);
     123      float pc = (fp2.x-fp1.x)*(fp3.y-fp1.y) - (fp3.x-fp1.x)*(fp2.y-fp1.y);
     124      float pd = -(pa*fp1.x+pb*fp1.y+pc*fp1.z);
     125
     126      cout << pa << "x+" << pb << "y+" << pc << "z+" << pd << "=0" << endl;
    90127
    91128      // get intersection
     129
     130      // the intersection this computes is incorrect
     131      // it doesn't match the equation of the plane
     132      vec3 i;
     133      i.z = -cam_pos.z - pc*pd/(pa*a+pb*b);
     134      i.x = cam_pos.x + a * (i.z-cam_pos.z) / c;
     135      i.y = cam_pos.y + b * (i.z-cam_pos.z) / c;
     136
     137      cout << "The holy grail?" << endl;
     138      cout << "(" << i.x << "," << i.y << "," << i.z << ")" << endl;
     139
     140      bool hit = insideTriangle(i, fp1, fp2, fp3);
     141      cout << (hit ? "true" : "false")  << endl;
     142
     143      if (hit) {
     144         clicked = true;
     145      }
     146   }
     147}
     148
     149void mouse_button_callback_new(GLFWwindow* window, int button, int action, int mods) {
     150   double mouse_x, mouse_y;
     151   glfwGetCursorPos(window, &mouse_x, &mouse_y);
     152
     153   if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
     154      cout << "Mouse clicked (" << mouse_x << "," << mouse_y << ")" << endl;
     155
     156      float x = (2.0f*mouse_x) / width - 1.0f;
     157      float y = 1.0f - (2.0f*mouse_y) / height;
     158      cout << "x: " << x << ", y: " << y << endl;
     159
     160      // CHECK: Looks good up to here
     161
     162      // Since the projection matrix gets applied before the view matrix,
     163      // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
     164
     165      // When getting the ray direction, you can use near and fov to get the
     166      // coordinates
     167
     168      // vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
     169      // vec4 ray_eye = inverse(proj_mat) * ray_clip;
     170      // ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
     171      // vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
     172
     173      vec4 ray_clip = vec4(x, y, 1.0f, 1.0f); // this should have a z equal to the near clipping plane
     174      vec3 ray_world = (inverse(view_mat) * ray_clip).xyz();
     175
     176      /* LATEST NOTES:
     177       *
     178       * Normalizing the world ray caused issues, although it should make sense with the projection
     179       * matrix, since the z coordinate has meaning there.
     180       *
     181       * Now, I need to figure out the correct intersection test in 2D space
     182       * Also, need to check that the global triangle points are correct
     183       */
     184
     185      // since ray_world is the end result we want anyway, we probably don't need to add cam_pos to
     186      // it, only to subtract it later
     187
     188      vec3 click_point = cam_pos + ray_world;
     189
     190      /* Now, we need to generate the constants for the equations describing
     191       * a 3D line:
     192       *   (x - x0) / a = (y - y0) / b = (z - z0) / c
     193       *
     194       * The line goes through the camera position, so
     195       * cam_pos = <x0, y0, z0>
     196       */
     197
     198      // upper right corner is 1, 1 in opengl
     199
     200      cout << "Converted -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
     201      cout << "Camera -> (" << cam_pos.x << "," << cam_pos.y << "," << cam_pos.z << ")" << endl;
     202      cout << "Click point -> (" << click_point.x << "," << click_point.y << "," << click_point.z << ")" << endl;
     203
     204      float a = 1.0f;
     205      float b = a * (click_point.y - cam_pos.y) / (click_point.x - cam_pos.x);
     206      float c = a * (click_point.z - cam_pos.z) / (click_point.x - cam_pos.x);
     207
     208      cout << "(x - " << cam_pos.x << ") / " << a << " = ";
     209      cout << "(y - " << cam_pos.y << ") / " << b << " = ";
     210      cout << "(z - " << cam_pos.z << ") / " << c << endl;;
     211
     212      /* Now, we need to generate the constants for the equations describing
     213       * a 3D plane:
     214       * dx + ey +fz +g = 0
     215       */
     216
     217      vec3 fp1 = face_point1;
     218      vec3 fp2 = face_point2;
     219      vec3 fp3 = face_point3;
     220
     221      cout << "Points on the plane" << endl;
     222      cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
     223      cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
     224      cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
     225
     226      float pa = (fp2.y-fp1.y)*(fp3.z-fp1.z) - (fp3.y-fp1.y)*(fp2.z-fp1.z);
     227      float pb = (fp2.z-fp1.z)*(fp3.x-fp1.x) - (fp3.z-fp1.z)*(fp2.x-fp1.x);
     228      float pc = (fp2.x-fp1.x)*(fp3.y-fp1.y) - (fp3.x-fp1.x)*(fp2.y-fp1.y);
     229      float pd = -(pa*fp1.x+pb*fp1.y+pc*fp1.z);
     230
     231      cout << pa << "x+" << pb << "y+" << pc << "z+" << pd << "=0" << endl;
     232
     233      // get intersection
     234
     235      // the intersection this computes is incorrect
     236      // it doesn't match the equation of the plane
     237      vec3 i;
     238      i.z = -cam_pos.z - pc*pd/(pa*a+pb*b);
     239      i.x = cam_pos.x + a * (i.z-cam_pos.z) / c;
     240      i.y = cam_pos.y + b * (i.z-cam_pos.z) / c;
     241
     242      cout << "The holy grail?" << endl;
     243      cout << "(" << i.x << "," << i.y << "," << i.z << ")" << endl;
     244
     245      bool hit = insideTriangle(i, fp1, fp2, fp3);
     246      cout << (hit ? "true" : "false")  << endl;
     247
     248      if (hit) {
     249         clicked = true;
     250      }
    92251   }
    93252}
     
    176335
    177336   GLfloat points[] = {
    178       0.0f,  0.5f,  0.0f,
     337      0.0f,  0.5f, -0.001f,
    179338     -0.5f, -0.5f,  0.0f,
    180339      0.5f, -0.5f,  0.0f,
    181340      0.5f, -0.5f,  0.0f,
    182341     -0.5f, -0.5f,  0.0f,
    183       0.0f,  0.5f,  0.0f,
    184    };
     342      0.0f,  0.5f, -0.001f,
     343   };
     344   /*
     345   GLfloat points[] = {
     346      0.0f,  1.0f,  0.0f,
     347     -1.0f,  0.0f,  0.0f,
     348      1.0f,  0.0f,  0.0f,
     349      1.0f,  0.0f,  0.0f,
     350     -1.0f,  0.0f,  0.0f,
     351      0.0f,  1.0f,  0.0f,
     352   };
     353   */
    185354
    186355   // initialize global variables for click intersection test
     
    196365     0.0, 0.0, 1.0,
    197366     1.0, 0.0, 0.0,
     367   };
     368
     369   GLfloat colors_new[] = {
     370     0.0, 1.0, 0.0,
     371     0.0, 1.0, 0.0,
     372     0.0, 1.0, 0.0,
     373     0.0, 1.0, 0.0,
     374     0.0, 1.0, 0.0,
     375     0.0, 1.0, 0.0,
    198376   };
    199377
     
    242420
    243421   mat4 T_model2 = translate(mat4(), vec3(-1.0f, 0.0f, 0.0f));
     422   // mat4 T_model2 = translate(mat4(), vec3(0.0f, 0.0f, 0.0f));
    244423   mat4 R_model2 = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
    245424   mat4 model_mat2 = T_model2*R_model2;
     
    306485
    307486   cam_pos = vec3(0.0f, 0.0f, 2.0f);
     487   //cam_pos = vec3(0.0f, 0.0f, 0.0f);
    308488   float cam_yaw = 0.0f;
    309489
    310490   mat4 T = translate(mat4(), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
    311491   mat4 R = rotate(mat4(), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
     492   /*
     493   mat4 T = translate(mat4(), vec3(0.0f, 0.0f, 0.0f));
     494   mat4 R = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
     495   */
    312496   view_mat = R*T;
    313497
     
    329513     0.0f, 0.0f, Pz, 0.0f,
    330514   };
     515   /*
     516   float proj_arr[] = {
     517     1.0f, 0.0f, 0.0f, 0.0f,
     518     0.0f, 1.0f, 0.0f, 0.0f,
     519     0.0f, 0.0f, 1.0f, 0.0f,
     520     0.0f, 0.0f, 0.0f, 1.0f,
     521   };
     522   */
    331523   proj_mat = make_mat4(proj_arr);
    332524
     
    361553      }
    362554
     555     if (clicked) {
     556        glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
     557
     558        if (colors_i == 0) {
     559           glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors_new, GL_STATIC_DRAW);
     560           colors_i = 1;
     561        } else {
     562           glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
     563           colors_i = 0;
     564        }
     565
     566        clicked = false;
     567     }
     568
    363569      /*
    364570      model[12] = last_position + speed*elapsed_seconds;
     
    380586      glBindVertexArray(vao2);
    381587
    382       glDrawArrays(GL_TRIANGLES, 0, numPoints2);
     588      int numPoints3 = numPoints2;
     589      numPoints2 = numPoints3;
     590      // glDrawArrays(GL_TRIANGLES, 0, numPoints2);
    383591
    384592      glfwPollEvents();
     
    421629         T = translate(mat4(), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
    422630         R = rotate(mat4(), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
    423          view_mat = R*T;
     631         // view_mat = R*T;
    424632
    425633         glUniformMatrix4fv(view_mat_loc, 1, GL_FALSE, value_ptr(view_mat));
     
    481689  return image_data;
    482690}
     691
     692bool insideTriangle(vec3 p, vec3 v1, vec3 v2, vec3 v3) {
     693   vec3 v21 = v2-v1;
     694   vec3 v31 = v3-v1;
     695   vec3 pv1 = p-v1;
     696
     697   float y = (pv1.y*v21.x - pv1.x*v21.y) / (v31.y*v21.x - v31.x*v21.y);
     698   float x = (pv1.x-y*v31.x) / v21.x;
     699
     700   cout << "(" << x << ", " << y << ")" << endl;
     701
     702   return x > 0.0f && y > 0.0f && x+y < 1.0f;
     703}
Note: See TracChangeset for help on using the changeset viewer.