Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 1f81eccc69412a326f3861662b1688ee540440b2)
+++ vulkan-game.cpp	(revision 3950236c3448866af72c329d4983aa407e1d1646)
@@ -779,4 +779,11 @@
    }
 
+   if (leftLaserIdx != -1) {
+      updateLaserTarget(leftLaserIdx);
+   }
+   if (rightLaserIdx != -1) {
+      updateLaserTarget(rightLaserIdx);
+   }
+
    for (SceneObject<AsteroidVertex, SSBO_Asteroid>& asteroid : this->asteroidObjects) {
       if (!asteroid.ssbo.deleted) {
@@ -1552,5 +1559,5 @@
          {{-width / 2, 0.0f, 0.0f               }, {0.0f, 0.0f }},
          {{ width / 2, 0.0f, 0.0f               }, {1.0f, 0.0f }},
-        {{ width / 2, 0.0f, -length + width / 2}, {1.0f, 0.51f}},
+         {{ width / 2, 0.0f, -length + width / 2}, {1.0f, 0.51f}},
          {{-width / 2, 0.0f, -length + width / 2}, {0.0f, 0.51f}},
          {{ width / 2, 0.0f, -length,           }, {1.0f, 1.0f }},
@@ -1580,4 +1587,6 @@
    float zAxisRotation = -atan2(glm::dot(glm::cross(normal, laserToCam), glm::normalize(ray)), glm::dot(normal, laserToCam));
 
+   laser.targetAsteroid = nullptr;
+
    laser.model_base =
       rotate(mat4(1.0f), zAxisRotation, vec3(0.0f, 0.0f, 1.0f));
@@ -1621,4 +1630,101 @@
 
    laser.modified = true;
+}
+
+void VulkanGame::updateLaserTarget(size_t index) {
+   SceneObject<LaserVertex, SSBO_Laser>& laser = this->laserObjects[index];
+
+   // TODO: A lot of the values calculated here can be calculated once and saved when the laser is created,
+   // and then re-used here
+
+   vec3 start = vec3(laser.model_transform * vec4(0.0f, 0.0f, 0.0f, 1.0f));
+   vec3 end = vec3(laser.model_transform * vec4(0.0f, 0.0f, laser.vertices[6].pos.z, 1.0f));
+
+   vec3 intersection(0.0f), closestIntersection(0.0f);
+   SceneObject<AsteroidVertex, SSBO_Asteroid>* closestAsteroid = nullptr;
+   unsigned int closestAsteroidIndex = -1;
+
+   for (int i = 0; i < this->asteroidObjects.size(); i++) {
+      if (!this->asteroidObjects[i].ssbo.deleted &&
+            this->getLaserAndAsteroidIntersection(this->asteroidObjects[i], start, end, intersection)) {
+         // TODO: Implement a more generic algorithm for testing the closest object by getting the distance between the points
+         // TODO: Also check which intersection is close to the start of the laser. This would make the algorithm work
+         // regardless of which way -Z is pointing
+         if (closestAsteroid == nullptr || intersection.z > closestIntersection.z) {
+            // TODO: At this point, find the real intersection of the laser with one of the asteroid's sides
+            closestAsteroid = &asteroidObjects[i];
+            closestIntersection = intersection;
+            closestAsteroidIndex = i;
+         }
+      }
+   }
+
+   float width = laser.vertices[0].pos.x - laser.vertices[1].pos.x;
+
+   if (laser.targetAsteroid != closestAsteroid) {
+      laser.targetAsteroid = closestAsteroid;
+   }
+
+   // Make the laser go past the end of the screen if it doesn't hit anything
+   float length = closestAsteroid == nullptr ? 5.24f : glm::length(closestIntersection - start);
+
+   laser.vertices[4].pos.z = -length + width / 2;
+   laser.vertices[5].pos.z = -length + width / 2;
+   laser.vertices[6].pos.z = -length;
+   laser.vertices[7].pos.z = -length;
+
+   // TODO: Consider if I want to set a flag and do this update in in updateScene() instead
+   updateObjectVertices(this->laserPipeline, laser, index);
+}
+
+// TODO: Determine if I should pass start and end by reference or value since they don't get changed
+// Probably use const reference
+bool VulkanGame::getLaserAndAsteroidIntersection(SceneObject<AsteroidVertex, SSBO_Asteroid>& asteroid,
+      vec3& start, vec3& end, vec3& intersection) {
+   /*
+   ### LINE EQUATIONS ###
+   x = x1 + u * (x2 - x1)
+   y = y1 + u * (y2 - y1)
+   z = z1 + u * (z2 - z1)
+
+   ### SPHERE EQUATION ###
+   (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2
+
+   ### QUADRATIC EQUATION TO SOLVE ###
+   a*u^2 + b*u + c = 0
+   WHERE THE CONSTANTS ARE
+   a = (x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2
+   b = 2*( (x2 - x1)*(x1 - x3) + (y2 - y1)*(y1 - y3) + (z2 - z1)*(z1 - z3) )
+   c = x3^2 + y3^2 + z3^2 + x1^2 + y1^2 + z1^2 - 2(x3*x1 + y3*y1 + z3*z1) - r^2
+
+   u = (-b +- sqrt(b^2 - 4*a*c)) / 2a
+
+   If the value under the root is >= 0, we got an intersection
+   If the value > 0, there are two solutions. Take the one closer to 0, since that's the
+   one closer to the laser start point
+   */
+
+   vec3& center = asteroid.center;
+
+   float a = pow(end.x - start.x, 2) + pow(end.y - start.y, 2) + pow(end.z - start.z, 2);
+   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));
+   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.radius, 2);
+   float discriminant = pow(b, 2) - 4 * a * c;
+
+   if (discriminant >= 0.0f) {
+      // In this case, the negative root will always give the point closer to the laser start point
+      float u = (-b - sqrt(discriminant)) / (2 * a);
+
+      // Check that the intersection is within the line segment corresponding to the laser
+      if (0.0f <= u && u <= 1.0f) {
+         intersection = start + u * (end - start);
+         return true;
+      }
+   }
+
+   return false;
 }
 
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 1f81eccc69412a326f3861662b1688ee540440b2)
+++ vulkan-game.hpp	(revision 3950236c3448866af72c329d4983aa407e1d1646)
@@ -96,4 +96,5 @@
    vec3 center; // currently only matters for asteroids
    float radius; // currently only matters for asteroids
+   SceneObject<AsteroidVertex, SSBO_Asteroid>* targetAsteroid; // currently only used for lasers
 };
 
@@ -271,4 +272,7 @@
       void addLaser(vec3 start, vec3 end, vec3 color, float width);
       void translateLaser(size_t index, const vec3& translation);
+      void updateLaserTarget(size_t index);
+      bool getLaserAndAsteroidIntersection(SceneObject<AsteroidVertex, SSBO_Asteroid>& asteroid,
+            vec3& start, vec3& end, vec3& intersection);
 
       // TODO: Since addObject() returns a reference to the new object now,
