Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision e82692b1725b5a92ab35e332743605d47b7d8ab9)
+++ new-game.cpp	(revision fc424f66db7f96a33d8d51e52e8dffa177417e09)
@@ -30,4 +30,14 @@
 #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444
 
+/*
+ * If I use one array to store the points for all the object faces in the scene, I'll probably remove the ObjectFace object,
+ * and store the start and end indices of a given object's point coordinates in that array in the SceneObject.
+ *
+ * Should probably do something similar with colors and texture coordinates, once I figure out the best way to store tex coords
+ * for all objects in one array.
+ */
+
+
+// might also want to store the shader to be used for the object
 struct SceneObject {
    mat4 model_mat;
@@ -62,4 +72,5 @@
 
 void printVector(string label, vec3 v);
+void print4DVector(string label, vec4 v);
 
 float NEAR_CLIP = 0.1f;
@@ -71,127 +82,4 @@
 
 void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
-   /*
-   double mouse_x, mouse_y;
-   glfwGetCursorPos(window, &mouse_x, &mouse_y);
-
-   if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
-      cout << "Mouse clicked (" << mouse_x << "," << mouse_y << ")" << endl;
-
-      float x = (2.0f*mouse_x) / width - 1.0f;
-      float y = 1.0f - (2.0f*mouse_y) / height;
-      cout << "x: " << x << ", y: " << y << endl;
-
-      // Since the projection matrix gets applied before the view matrix,
-      // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
-
-      // When getting the ray direction, you can use near and fov to get the
-      // coordinates
-
-      vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
-      vec4 ray_eye = inverse(proj_mat) * ray_clip;
-      ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
-      vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
-
-      / * LATEST NOTES:
-       *
-       * Normalizing the world ray caused issues, although it should make sense with the projection
-       * matrix, since the z coordinate has meaning there.
-       *
-       * Now, I need to figure out the correct intersection test in 2D space
-       * Also, need to check that the global triangle points are correct
-       * /
-
-      // since ray_world is the end result we want anyway, we probably don't need to add cam_pos to
-      // it, only to subtract it later
-
-      vec3 click_point = cam_pos + ray_world;
-
-      / * Now, we need to generate the constants for the equations describing
-       * a 3D line:
-       *   (x - x0) / a = (y - y0) / b = (z - z0) / c
-       *
-       * The line goes through the camera position, so
-       * cam_pos = <x0, y0, z0>
-       * /
-
-      // upper right corner is 1, 1 in opengl
-
-      cout << "Converted -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
-      cout << "Camera -> (" << cam_pos.x << "," << cam_pos.y << "," << cam_pos.z << ")" << endl;
-      cout << "Click point -> (" << click_point.x << "," << click_point.y << "," << click_point.z << ")" << endl;
-
-      float a = 1.0f;
-      float b = a * (click_point.y - cam_pos.y) / (click_point.x - cam_pos.x);
-      float c = a * (click_point.z - cam_pos.z) / (click_point.x - cam_pos.x);
-
-      cout << "(x - " << cam_pos.x << ") / " << a << " = ";
-      cout << "(y - " << cam_pos.y << ") / " << b << " = ";
-      cout << "(z - " << cam_pos.z << ") / " << c << endl;;
-
-      / * Now, we need to generate the constants for the equations describing
-       * a 3D plane:
-       * dx + ey +fz +g = 0
-       * /
-
-      vec3 fp1 = triangle_face[0];
-      vec3 fp2 = triangle_face[1];
-      vec3 fp3 = triangle_face[2];
-
-      cout << "Points on the plane" << endl;
-      cout << "(" << fp1.x << ", " << fp1.y << ", " << fp1.z << ")" << endl;
-      cout << "(" << fp2.x << ", " << fp2.y << ", " << fp2.z << ")" << endl;
-      cout << "(" << fp3.x << ", " << fp3.y << ", " << fp3.z << ")" << endl;
-
-      float pa = (fp2.y-fp1.y)*(fp3.z-fp1.z) - (fp3.y-fp1.y)*(fp2.z-fp1.z);
-      float pb = (fp2.z-fp1.z)*(fp3.x-fp1.x) - (fp3.z-fp1.z)*(fp2.x-fp1.x);
-      float pc = (fp2.x-fp1.x)*(fp3.y-fp1.y) - (fp3.x-fp1.x)*(fp2.y-fp1.y);
-      float pd = -(pa*fp1.x+pb*fp1.y+pc*fp1.z);
-
-      cout << pa << "x+" << pb << "y+" << pc << "z+" << pd << "=0" << endl;
-
-      // get intersection
-
-      // the intersection this computes is incorrect
-      // it doesn't match the equation of the plane
-      vec3 i;
-      i.z = -cam_pos.z - pc*pd/(pa*a+pb*b);
-      i.x = cam_pos.x + a * (i.z-cam_pos.z) / c;
-      i.y = cam_pos.y + b * (i.z-cam_pos.z) / c;
-
-      cout << "The holy grail?" << endl;
-      cout << "(" << i.x << "," << i.y << "," << i.z << ")" << endl;
-
-      clicked = insideTriangle(i, triangle_face);
-      cout << (clicked ? "true" : "false")  << endl;
-   }
-   */
-}
-
-/* REFACTORING PLAN:
- *
- * Have an array of object structs
- * Each object struct has:
- *    -a model matrix
- *    -a selected boolean
- * Eventually, maybe also want to store a reference to the correct shader
- * or whatever other info I need to properly render it
- *
- * Have an array of face structs
- * Each face struct has
- *    -an object index indicating which object it is a part of
- *    -an array of three points
- *
- * The mouse button callback will:
- *    -iterate through the faces array
- *    -For each face, it will call faceClicked() with the following params:
- *       -Probably a world ray created from the mouse click coordinates
- *       -An array of 3 points representing the face
- *       -The object struct represnting the object the face is a part of
- *
- *       -Really, all I need to pass in are the world ray and an ObjectFace reference
- *       -The world ray will first need to be multiplied by the view and projection matrices before being passed in
- */
-
-void mouse_button_callback_new(GLFWwindow* window, int button, int action, int mods) {
    double mouse_x, mouse_y;
    glfwGetCursorPos(window, &mouse_x, &mouse_y);
@@ -206,49 +94,20 @@
       cout << "x: " << x << ", y: " << y << endl;
 
-      // Since the projection matrix gets applied before the view matrix,
-      // treat the initial camera position (aka origin of the ray) as (0, 0, 0)
-
-      // When getting the ray direction, you can use near and fov to get the
-      // coordinates
-
-      // vec4 ray_clip = vec4(x, y, -1.0f, 1.0f); // this should have a z equal to the near clipping plane
-      // vec4 ray_eye = inverse(proj_mat) * ray_clip;
-      // ray_eye = vec4(ray_eye.xy(), -1.0f, 0.0f);
-      // vec3 ray_world = normalize((inverse(view_mat) * ray_eye).xyz());
-
-      vec4 ray_clip = vec4(x, y, NEAR_CLIP, 1.0f); // this should have a z equal to the near clipping plane
-      vec4 ray_eye = ray_clip; // Need to apply the projection matrix here
+      vec4 ray_clip = vec4(x, y, -1.0f, 1.0f);
+      vec4 ray_eye = inverse(proj_mat) * ray_clip;
+      ray_eye = vec4(ray_eye.xy(), -1.0f, 1.0f);
       vec4 ray_world = inverse(view_mat) * ray_eye;
 
-      /* LATEST NOTES:
-       *
-       * Normalizing the world ray caused issues, although it should make sense with the projection
-       * matrix, since the z coordinate has meaning there.
-       * Plus, we really want to normalize it only once we recompute it below as the difference of two points,
-       * although doing so shouldn't effect the results. Check the book to see if there is a good reason for doing so.
-       */
-
-      printVector("Initial world ray:", ray_world.xyz());
-
-      vec4 cam_pos_origin = vec4(x, y, 0.0f, 1.0f);
-      vec4 cam_pos_temp = inverse(view_mat) * cam_pos_origin;
-
-      cout << "Ray clip -> (" << ray_clip.x << "," << ray_clip.y << "," << ray_clip.z << ")" << endl << endl;;
-      cout << "Ray world -> (" << ray_world.x << "," << ray_world.y << "," << ray_world.z << ")" << endl << endl;;
-      cout << "Camera -> (" << cam_pos_temp.x << "," << cam_pos_temp.y << "," << cam_pos_temp.z << ")" << endl;
+      vec4 cam_pos_temp = vec4(cam_pos, 1.0f);
 
       vec4 click_point;
-      vec3 closest_point;
+      vec3 closest_point = vec3(0.0f, 0.0f, -FAR_CLIP); // Any valid point will be closer than the far clipping plane, so initial value to that
       int closest_face_id = -1;
 
-      // Need to account for faces that are behind one another
-      // Using an iterator for the loop makes it difficult to get a reference to each face (for the faceClicked function)
       for (int i = 0; i<faces.size(); i++) {
          if (faceClicked(&faces[i], ray_world, cam_pos_temp, click_point)) {
             click_point = view_mat * click_point;
 
-            // Check against clipping planes once I start applying the projection matrix
-            // if (NEAR_CLIP <= click_point.z && click_point.z < FAR_CLIP && ...) {
-            if (-1.0f <= click_point.z && click_point.z < 1.0f && click_point.z < closest_point.z) {
+            if (-NEAR_CLIP >= click_point.z && click_point.z > -FAR_CLIP && click_point.z > closest_point.z) {
                closest_point = click_point.xyz();
                closest_face_id = i;
@@ -262,5 +121,4 @@
          clickedObject = &objects[faces[closest_face_id].object_id];
          cout << "Clicked object: " << faces[closest_face_id].object_id << endl;
-         printVector("Click point", closest_point);
       }
    }
@@ -309,7 +167,5 @@
    }
 
-   bool squareSelected = false;
-
-   glfwSetMouseButtonCallback(window, mouse_button_callback_new);
+   glfwSetMouseButtonCallback(window, mouse_button_callback);
 
    glfwMakeContextCurrent(window);
@@ -317,5 +173,6 @@
    glewInit();
 
-   // Check if we might ever need this. If not, remove it.
+   // Check the extended initialization section of the book to learn how to use this
+   // Maybe move this and other OpenGL setup/settings code into a separate function
    // glViewport(0, 0, width*2, height*2);
 
@@ -383,10 +240,10 @@
 
    GLfloat points2[] = {
-      0.5f,  0.5f,  0.0f,
+       0.5f,  0.5f,  0.0f,
       -0.5f,  0.5f,  0.0f,
       -0.5f, -0.5f,  0.0f,
-      0.5f,  0.5f,  0.0f,
+       0.5f,  0.5f,  0.0f,
       -0.5f, -0.5f,  0.0f,
-      0.5f, -0.5f,  0.0f,
+       0.5f, -0.5f,  0.0f,
    };
 
@@ -412,6 +269,4 @@
    int numPoints2 = (sizeof(points2) / sizeof(float)) / 3;
 
-   // initialize global variables for click intersection tests
-
    mat4 T_model, R_model;
 
@@ -419,8 +274,5 @@
    objects.push_back(SceneObject());
 
-   /*
-   mat4 R_model = rotate(mat4(), 4.0f, vec3(0.0f, 1.0f, 0.0f));
-   */
-   T_model = translate(mat4(), vec3(0.0f, 0.0f, 0.0f));
+   T_model = translate(mat4(), vec3(0.25f, 0.0f, 0.0f));
    R_model = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
    objects[0].model_mat = T_model*R_model;
@@ -437,7 +289,6 @@
    objects.push_back(SceneObject());
 
-   // mat4 T_model2 = translate(mat4(), vec3(-1.0f, 0.0f, 0.0f));
-   T_model = translate(mat4(), vec3(-0.5f, 0.0f, 0.1f));
-   R_model = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
+   T_model = translate(mat4(), vec3(-0.5f, 0.0f, -1.00f));
+   R_model = rotate(mat4(), 0.5f, vec3(0.0f, 1.0f, 0.0f));
    objects[1].model_mat = T_model*R_model;
 
@@ -516,14 +367,12 @@
    float cam_yaw_speed = 60.0f*ONE_DEG_IN_RAD;
 
-   //cam_pos = vec3(0.0f, 0.0f, 2.0f);
-   cam_pos = vec3(0.0f, 0.0f, 0.3f);
+   // glm::lookAt can create the view matrix
+   // glm::perspective can create the projection matrix
+
+   cam_pos = vec3(0.0f, 0.0f, 2.0f);
    float cam_yaw = 0.0f * 2.0f * 3.14159f / 360.0f;
 
    mat4 T = translate(mat4(), vec3(-cam_pos.x, -cam_pos.y, -cam_pos.z));
    mat4 R = rotate(mat4(), -cam_yaw, vec3(0.0f, 1.0f, 0.0f));
-   /*
-   mat4 T = translate(mat4(), vec3(0.0f, 0.0f, 0.0f));
-   mat4 R = rotate(mat4(), 0.0f, vec3(0.0f, 1.0f, 0.0f));
-   */
    view_mat = R*T;
 
@@ -537,5 +386,4 @@
    float Pz = -(2.0f * FAR_CLIP * NEAR_CLIP) / (FAR_CLIP - NEAR_CLIP);
 
-   /*
    float proj_arr[] = {
      Sx, 0.0f, 0.0f, 0.0f,
@@ -544,11 +392,4 @@
      0.0f, 0.0f, Pz, 0.0f,
    };
-   */
-   float proj_arr[] = {
-     1.0f, 0.0f, 0.0f, 0.0f,
-     0.0f, 1.0f, 0.0f, 0.0f,
-     0.0f, 0.0f, 1.0f, 0.0f,
-     0.0f, 0.0f, 0.0f, 1.0f,
-   };
    proj_mat = make_mat4(proj_arr);
 
@@ -605,4 +446,6 @@
       glUseProgram(shader_program);
 
+      // Since every object will have a different model matrix, maybe it shouldn't be a uniform
+
       // this is temporary.
       // It's needed to offset the code for the recoloring of the square working during click detection
@@ -614,5 +457,4 @@
 
       if (clickedObject == &objects[1]) {
-         squareSelected = !squareSelected;
          selectedObject = &objects[1];
       }
@@ -743,14 +585,11 @@
 
 bool faceClicked(ObjectFace* face, vec4 world_ray, vec4 cam, vec4& click_point) {
-   cout << "Points on the plane" << endl;
-   printVector("fp1", face->points[0]);
-   printVector("fp2", face->points[1]);
-   printVector("fp3", face->points[2]);
-
    // LINE EQUATION:		P = O + Dt
-   // O = cam_pos
+   // O = cam
    // D = ray_world
 
-   // PLANE EQUATION:	P dot n + d = 0  (n is the normal vector and d is the offset from the origin)
+   // PLANE EQUATION:	P dot n + d = 0
+   // n is the normal vector
+   // d is the offset from the origin
 
    // Take the cross-product of two vectors on the plane to get the normal
@@ -759,15 +598,12 @@
 
    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);
-   printVector("v1", v1);
-   printVector("v2", v2);
-   printVector("Cross", normal);
+
+   print4DVector("Full world ray", world_ray);
 
    SceneObject* obj = &objects[face->object_id];
    vec3 local_ray = (inverse(obj->model_mat) * world_ray).xyz();
    vec3 local_cam = (inverse(obj->model_mat) * cam).xyz();
+
    local_ray = local_ray - local_cam;
-
-   cout << "Test theory: " << glm::dot(local_cam, normal) << endl;
-   cout << "Test 2: " << glm::dot(local_ray, normal) << endl;
 
    float d = -glm::dot(face->points[0], normal);
@@ -804,2 +640,6 @@
    cout << label << " -> (" << v.x << "," << v.y << "," << v.z << ")" << endl;
 }
+
+void print4DVector(string label, vec4 v) {
+   cout << label << " -> (" << v.x << "," << v.y << "," << v.z << "," << v.w << ")" << endl;
+}
