Changeset e9347b4 in opengl-game


Ignore:
Timestamp:
Aug 3, 2018, 2:16:17 AM (6 years ago)
Author:
Dmitry Portnoy <dmp1488@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
1f3d32b
Parents:
612d1f6
git-author:
Dmitry Portnoy <dmp1488@…> (08/03/18 02:12:11)
git-committer:
Dmitry Portnoy <dmp1488@…> (08/03/18 02:16:17)
Message:

Implement an algorithm to find the closest object in a laser's path and
shorten the laser so it ends at the intersection point with that object.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • new-game.cpp

    r612d1f6 re9347b4  
    9595unsigned char* loadImage(string file_name, int* x, int* y);
    9696
    97 void printVector(string label, vec3 v);
    98 void print4DVector(string label, vec4 v);
     97void printVector(string label, vec3& v);
     98void print4DVector(string label, vec4& v);
    9999
    100100void initObject(SceneObject& obj);
     
    146146
    147147void translateLaser(SceneObject& laser, const vec3& translation, GLuint ubo);
     148void updateLaserTarget(SceneObject& laser, vector<SceneObject>& objects, GLuint points_vbo);
     149bool getLaserAndAsteroidIntersection(vec3& start, vec3& end, SceneObject& asteroid, vec3& intersection);
    148150
    149151void renderMainMenu();
     
    215217
    216218/*
    217 * TODO: Asteroid movement currently depends on framerate, fix this in a generic/reusable way
     219* TODO: Asteroid and ship movement currently depend on framerate, fix this in a generic/reusable way
     220* Disabling vsync is a great way to test this
    218221*/
    219222
     
    10051008         elapsed_seconds_spawn += elapsed_seconds;
    10061009         if (elapsed_seconds_spawn > 0.5f) {
    1007             spawnAsteroid(vec3(getRandomNum(-1.3f, 1.3f), getRandomNum(-3.0f, -1.0f), getRandomNum(-5.5f, -4.5f)), color_sp,
     1010            //spawnAsteroid(vec3(getRandomNum(-1.3f, 1.3f), getRandomNum(-3.0f, -1.0f), getRandomNum(-5.5f, -4.5f)), color_sp,
     1011            spawnAsteroid(vec3(getRandomNum(-1.3f, 1.3f), -1.2f, getRandomNum(-5.5f, -4.5f)), color_sp,
    10081012               shaderBufferInfo,
    10091013               points_vbo,
     
    10421046            transformObject(objects[0], translate(mat4(1.0f), vec3(0.01f, 0.0f, 0.0f)), ubo);
    10431047
    1044             if (leftLaserIdx != -1) {
     1048            if (leftLaserIdx != -1 && !objects[leftLaserIdx].deleted) {
    10451049               translateLaser(objects[leftLaserIdx], vec3(0.01f, 0.0f, 0.0f), ubo);
    10461050            }
    1047             if (rightLaserIdx != -1) {
     1051            if (rightLaserIdx != -1 && !objects[rightLaserIdx].deleted) {
    10481052               translateLaser(objects[rightLaserIdx], vec3(0.01f, 0.0f, 0.0f), ubo);
    10491053            }
     
    10521056            transformObject(objects[0], translate(mat4(1.0f), vec3(-0.01f, 0.0f, 0.0f)), ubo);
    10531057
    1054             if (leftLaserIdx != -1) {
     1058            if (leftLaserIdx != -1 && !objects[leftLaserIdx].deleted) {
    10551059               translateLaser(objects[leftLaserIdx], vec3(-0.01f, 0.0f, 0.0f), ubo);
    10561060            }
    1057             if (rightLaserIdx != -1) {
     1061            if (rightLaserIdx != -1 && !objects[rightLaserIdx].deleted) {
    10581062               translateLaser(objects[rightLaserIdx], vec3(-0.01f, 0.0f, 0.0f), ubo);
    10591063            }
     
    11091113         }
    11101114
    1111          // TODO: Probablu remove this since it was only added to test that object removal owrks
    1112          if (key_state[GLFW_KEY_SPACE] == GLFW_PRESS) {
    1113             removeObjectFromScene(objects[0], ubo);
     1115         if (leftLaserIdx != -1 && !objects[leftLaserIdx].deleted) {
     1116            updateLaserTarget(objects[leftLaserIdx], objects, points_vbo);
     1117         }
     1118         if (rightLaserIdx != -1 && !objects[rightLaserIdx].deleted) {
     1119            updateLaserTarget(objects[rightLaserIdx], objects, points_vbo);
    11141120         }
    11151121      }
     
    14001406}
    14011407
    1402 void printVector(string label, vec3 v) {
     1408void printVector(string label, vec3& v) {
    14031409   cout << label << " -> (" << v.x << "," << v.y << "," << v.z << ")" << endl;
    14041410}
    14051411
    1406 void print4DVector(string label, vec4 v) {
     1412void print4DVector(string label, vec4& v) {
    14071413   cout << label << " -> (" << v.x << "," << v.y << "," << v.z << "," << v.w << ")" << endl;
    14081414}
     
    15351541   GLfloat radius_z = max_z - obj.bounding_center.z;
    15361542
    1537    // This actually underestimates the radius. Might need to be fixed at some point.
     1543   // TODO: This actually underestimates the radius. Might need to be fixed at some point.
     1544   // TODO: Does not take into account any scaling in the model matrix
    15381545   obj.bounding_radius = radius_x;
    15391546   if (obj.bounding_radius < radius_y)
     
    18571864
    18581865void translateLaser(SceneObject& laser, const vec3& translation, GLuint ubo) {
    1859    if (laser.deleted) return;
    1860 
    1861    // TODO: A lot of the values I calculate here can be calculated once and saved when the laser is created,
     1866   // TODO: A lot of the values calculated here can be calculated once and saved when the laser is created,
    18621867   // and then re-used here
    18631868
     
    18651870
    18661871   vec3 start = vec3(laser.model_transform * vec4(0.0f, 0.0f, 0.0f, 1.0f));
    1867    vec3 end = vec3(laser.model_transform * vec4(0.0f, 0.0f, laser.points[2] + laser.points[20], 1.0f));
     1872   vec3 end = vec3(laser.model_transform * vec4(0.0f, 0.0f, laser.points[38], 1.0f));
    18681873
    18691874   vec3 ray = end - start;
     
    18871892
    18881893   transformObject(laser, translate(mat4(1.0f), translation), ubo);
     1894}
     1895
     1896void updateLaserTarget(SceneObject& laser, vector<SceneObject>& objects, GLuint points_vbo) {
     1897   // TODO: A lot of the values calculated here can be calculated once and saved when the laser is created,
     1898   // and then re-used here
     1899
     1900   vec3 start = vec3(laser.model_transform * vec4(0.0f, 0.0f, 0.0f, 1.0f));
     1901   vec3 end = vec3(laser.model_transform * vec4(0.0f, 0.0f, laser.points[2] + laser.points[20], 1.0f));
     1902
     1903   vec3 intersection(0.0f), closestIntersection(0.0f);
     1904   SceneObject* closestAsteroid = NULL;
     1905
     1906   for (vector<SceneObject>::iterator it = objects.begin(); it != objects.end(); it++) {
     1907      if (it->type == TYPE_ASTEROID && !it->deleted && getLaserAndAsteroidIntersection(start, end, *it, intersection)) {
     1908         // TODO: Implement a more generic algorithm for testing the closest object by getting the distance between the points
     1909         if (closestAsteroid == NULL || intersection.z > closestIntersection.z) {
     1910            // TODO: At this point, find the real intersection of the laser with one of the asteroid's sides
     1911            closestAsteroid = &*it;
     1912            closestIntersection = intersection;
     1913         }
     1914      }
     1915   }
     1916
     1917   float width = laser.points[0] - laser.points[2];
     1918
     1919   float length = 5.24f;
     1920   if (closestAsteroid != NULL) {
     1921      length = glm::length(closestIntersection - start);
     1922   }
     1923
     1924   laser.points[20] = -length + width / 2;
     1925   laser.points[23] = -length + width / 2;
     1926   laser.points[29] = -length + width / 2;
     1927   laser.points[38] = -length;
     1928   laser.points[41] = -length;
     1929   laser.points[44] = -length + width / 2;
     1930   laser.points[47] = -length;
     1931   laser.points[50] = -length + width / 2;
     1932   laser.points[53] = -length + width / 2;
     1933
     1934   glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
     1935   glBufferSubData(GL_ARRAY_BUFFER, laser.vertex_vbo_offset * sizeof(GLfloat) * 3, laser.points.size() * sizeof(GLfloat), &laser.points[0]);
     1936}
     1937
     1938bool getLaserAndAsteroidIntersection(vec3& start, vec3& end, SceneObject& asteroid, vec3& intersection) {
     1939   /*
     1940   ### LINE EQUATIONS ###
     1941   x = x1 + u * (x2 - x1)
     1942   y = y1 + u * (y2 - y1)
     1943   z = z1 + u * (z2 - z1)
     1944
     1945   ### SPHERE EQUATION ###
     1946   (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2
     1947
     1948   ### QUADRATIC EQUATION TO SOLVE ###
     1949   a*u^2 + b*u + c = 0
     1950   WHERE THE CONSTANTS ARE
     1951   a = (x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2
     1952   b = 2*( (x2 - x1)*(x1 - x3) + (y2 - y1)*(y1 - y3) + (z2 - z1)*(z1 - z3) )
     1953   c = x3^2 + y3^2 + z3^2 + x1^2 + y1^2 + z1^2 - 2(x3*x1 + y3*y1 + z3*z1) - r^2
     1954
     1955   u = (-b +- sqrt(b^2 - 4*a*c)) / 2a
     1956
     1957   If the value under the root is >= 0, we got an intersection
     1958   If the value > 0, there are two solutions. Take the one closer to 0, since that's the
     1959   one closer to the laser start point
     1960   */
     1961
     1962   vec3& center = asteroid.bounding_center;
     1963
     1964   float a = pow(end.x-start.x, 2) + pow(end.y-start.y, 2) + pow(end.z-start.z, 2);
     1965   float b = 2*((start.x-end.x)*(start.x-center.x) + (end.y-start.y)*(start.y-center.y) + (end.z-start.z)*(start.z-center.z));
     1966   float c = pow(center.x, 2) + pow(center.y, 2) + pow(center.z, 2) + pow(start.x, 2) + pow(start.y, 2) + pow(start.z, 2) - 2*(center.x*start.x + center.y*start.y + center.z*start.z) - pow(asteroid.bounding_radius, 2);
     1967   float discriminant = pow(b, 2) - 4*a*c;
     1968
     1969   if (discriminant >= 0.0f) {
     1970      // In this case, the negative root will always give the point closer to the laser start point
     1971      float u = (-b - sqrt(discriminant)) / (2 * a);
     1972
     1973      // Check that the intersection is within the line segment corresponding to the laser
     1974      if (0.0f <= u && u <= 1.0f) {
     1975         intersection = start + u * (end - start);
     1976         return true;
     1977      }
     1978   }
     1979
     1980   return false;
    18891981}
    18901982
     
    21372229
    21382230   initObject(obj);
     2231   // This accounts for the scaling in model_base.
     2232   // Dividing by 8 instead of 10 since the bounding radius algorithm
     2233   // under-calculates the true value.
     2234   // TODO: Once the intersection check with the sides of the asteroid is done,
     2235   // this can be removed.
     2236   obj.bounding_radius /= 8.0f;
     2237
    21392238   addObjectToScene(obj, shaderBufferInfo,
    21402239                  points_vbo,
Note: See TracChangeset for help on using the changeset viewer.