Changeset 5c9d193 in opengl-game


Ignore:
Timestamp:
Mar 23, 2018, 2:18:44 AM (7 years ago)
Author:
Dmitry Portnoy <dmp1488@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
e82692b
Parents:
147ac6d
Message:

Created a faceClicked method to encapsulate checking for the intersection of the world ray with a given face, and check all the faces in the scene when trying to determine which object was clicked.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • new-game.cpp

    r147ac6d r5c9d193  
    55#define _USE_MATH_DEFINES
    66#define GLM_SWIZZLE
     7
     8// This is to fix a non-alignment issue when passing vec4 params.
     9// Check if it got fixed in a later version of GLM
     10#define GLM_FORCE_PURE
    711
    812#include <glm/mat4x4.hpp>
     
    5054SceneObject* selectedObject = NULL;
    5155
    52 bool insideTriangle(vec3 p, ObjectFace* face);
     56bool faceClicked(ObjectFace* face, vec4 world_ray, vec4 cam);
     57bool insideTriangle(vec3 p, array<vec3, 3> triangle_points);
    5358
    5459GLuint loadShader(GLenum type, string file);
     
    178183 *
    179184 * The mouse button callback will:
    180  *    -Set all selected flags in the objects array to false
    181185 *    -iterate through the faces array
    182186 *    -For each face, it will call faceClicked() with the following params:
     
    193197   glfwGetCursorPos(window, &mouse_x, &mouse_y);
    194198
    195    ObjectFace* face = &faces[0];
    196    SceneObject* obj = &objects[face->objectId];
    197 
    198199   if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
    199200      cout << "Mouse clicked (" << mouse_x << "," << mouse_y << ")" << endl;
     
    217218
    218219      vec4 ray_clip = vec4(x, y, NEAR_CLIP, 1.0f); // this should have a z equal to the near clipping plane
    219       vec4 ray_eye = ray_clip;
    220       vec3 ray_world = (inverse(obj->model_mat) * inverse(view_mat) * ray_eye).xyz();
     220      vec4 ray_eye = ray_clip; // Need to apply the projection matrix here
     221      vec4 ray_world = inverse(view_mat) * ray_eye;
    221222
    222223      /* LATEST NOTES:
     
    228229       */
    229230
    230       printVector("Initial world ray:", ray_world);
     231      printVector("Initial world ray:", ray_world.xyz());
    231232
    232233      vec4 cam_pos_origin = vec4(x, y, 0.0f, 1.0f);
    233       vec3 cam_pos_temp = (inverse(obj->model_mat) * inverse(view_mat) * cam_pos_origin).xyz();
    234 
    235       ray_world = ray_world-cam_pos_temp;
     234      vec4 cam_pos_temp = inverse(view_mat) * cam_pos_origin;
    236235
    237236      cout << "Ray clip -> (" << ray_clip.x << "," << ray_clip.y << "," << ray_clip.z << ")" << endl << endl;;
     
    239238      cout << "Camera -> (" << cam_pos_temp.x << "," << cam_pos_temp.y << "," << cam_pos_temp.z << ")" << endl;
    240239
    241       vec3 fp1 = face->points[0];
    242       vec3 fp2 = face->points[1];
    243       vec3 fp3 = face->points[2];
    244 
    245       cout << "Points on the plane" << endl;
    246       cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
    247       cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
    248       cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
    249 
    250       // LINE EQUATION:         P = O + Dt
    251       // O = cam_pos
    252       // D = ray_world
    253 
    254       // PLANE EQUATION:        P dot n + d = 0  (n is the normal vector and d is the offset from the origin)
    255 
    256       // Take the cross-product of two vectors on the plane to get the normal
    257       vec3 v1 = fp2 - fp1;
    258       vec3 v2 = fp3 - fp1;
    259 
    260       vec3 normal = vec3(v1.y*v2.z-v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
    261       printVector("v1", v1);
    262       printVector("v2", v2);
    263       printVector("Cross", normal);
    264       cout << "Test theory: " << glm::dot(cam_pos_temp, normal) << endl;
    265       cout << "Test 2: " << glm::dot(ray_world, normal) << endl;
    266 
    267       float d = -glm::dot(fp1, normal);
    268       cout << "d: " << d << endl;
    269 
    270       float t = - (glm::dot(cam_pos_temp, normal) + d) / glm::dot(ray_world, normal);
    271       cout << "t: " << t << endl;
    272 
    273       vec3 intersection = cam_pos_temp+t*ray_world;
    274       printVector("Intersection", intersection);
    275 
    276       if (insideTriangle(intersection, face)) {
    277          clickedObject = obj;
    278       }
    279       cout << (obj == clickedObject ? "true" : "false") << endl;
     240      // Need to account for faces that are behind one another
     241      // Using an iterator for the loop makes it difficult to get a reference to each face (for the faceClicked function)
     242      for (int i = 0; i<faces.size(); i++) {
     243         if (faceClicked(&faces[i], ray_world, cam_pos_temp)) {
     244            clickedObject = &objects[faces[i].objectId];
     245            cout << "Clicked object: " << faces[i].objectId << endl;
     246            break;
     247         }
     248      }
     249
     250      if (clickedObject == NULL) {
     251         cout << "No object was clicked" << endl;
     252      }
    280253   }
    281254}
     
    756729}
    757730
    758 bool insideTriangle(vec3 p, ObjectFace* face) {
    759    vec3 v21 = face->points[1]- face->points[0];
    760    vec3 v31 = face->points[2]- face->points[0];
    761    vec3 pv1 = p- face->points[0];
     731bool faceClicked(ObjectFace* face, vec4 world_ray, vec4 cam) {
     732   cout << "Points on the plane" << endl;
     733   printVector("fp1", face->points[0]);
     734   printVector("fp2", face->points[1]);
     735   printVector("fp3", face->points[2]);
     736
     737   // LINE EQUATION:            P = O + Dt
     738   // O = cam_pos
     739   // D = ray_world
     740
     741   // PLANE EQUATION:   P dot n + d = 0  (n is the normal vector and d is the offset from the origin)
     742
     743   // Take the cross-product of two vectors on the plane to get the normal
     744   vec3 v1 = face->points[1] - face->points[0];
     745   vec3 v2 = face->points[2] - face->points[0];
     746
     747   vec3 normal = vec3(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
     748   printVector("v1", v1);
     749   printVector("v2", v2);
     750   printVector("Cross", normal);
     751
     752   SceneObject* obj = &objects[face->objectId];
     753   vec3 local_ray = (inverse(obj->model_mat) * world_ray).xyz();
     754   vec3 local_cam = (inverse(obj->model_mat) * cam).xyz();
     755   local_ray = local_ray - local_cam;
     756
     757   cout << "Test theory: " << glm::dot(local_cam, normal) << endl;
     758   cout << "Test 2: " << glm::dot(local_ray, normal) << endl;
     759
     760   float d = -glm::dot(face->points[0], normal);
     761   cout << "d: " << d << endl;
     762
     763   float t = -(glm::dot(local_cam, normal) + d) / glm::dot(local_ray, normal);
     764   cout << "t: " << t << endl;
     765
     766   vec3 intersection = local_cam + t*local_ray;
     767   printVector("Intersection", intersection);
     768
     769   return insideTriangle(intersection, face->points);
     770}
     771
     772bool insideTriangle(vec3 p, array<vec3, 3> triangle_points) {
     773   vec3 v21 = triangle_points[1]- triangle_points[0];
     774   vec3 v31 = triangle_points[2]- triangle_points[0];
     775   vec3 pv1 = p- triangle_points[0];
    762776
    763777   float y = (pv1.y*v21.x - pv1.x*v21.y) / (v31.y*v21.x - v31.x*v21.y);
Note: See TracChangeset for help on using the changeset viewer.