Index: graphics-pipeline_vulkan.hpp
===================================================================
--- graphics-pipeline_vulkan.hpp	(revision 860a0da7bda4763e3a1be95cfde80564e1cc9319)
+++ graphics-pipeline_vulkan.hpp	(revision 2da64efeed527c21b6906cf773dcf113bbe77951)
@@ -74,8 +74,8 @@
          VkQueue graphicsQueue);
 
+      void updateObject(size_t objIndex, SSBOType& ssbo);
+
       void cleanup();
       void cleanupBuffers();
-
-      StorageBufferSet storageBufferSet;
    
    private:
@@ -108,4 +108,6 @@
       size_t numObjects;
       size_t objectCapacity;
+
+      StorageBufferSet storageBufferSet;
 
       VkShaderModule createShaderModule(const vector<char>& code);
@@ -491,4 +493,13 @@
 
 template<class VertexType, class SSBOType>
+void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateObject(size_t objIndex, SSBOType& ssbo) {
+   if (!is_same_v<SSBOType, void*>) {
+      for (size_t i = 0; i < storageBufferSet.memory.size(); i++) {
+         VulkanUtils::copyDataToMemory(device, storageBufferSet.memory[i], objIndex, ssbo);
+      }
+   }
+}
+
+template<class VertexType, class SSBOType>
 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanup() {
    vkDestroyPipeline(device, pipeline, nullptr);
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 860a0da7bda4763e3a1be95cfde80564e1cc9319)
+++ vulkan-game.cpp	(revision 2da64efeed527c21b6906cf773dcf113bbe77951)
@@ -524,69 +524,4 @@
    asteroidPipeline.addStorageDescriptor();
 
-   addObject(asteroidObjects, asteroidPipeline,
-      centerObject<AsteroidVertex>(
-      addObjectIndex<AsteroidVertex>(asteroidObjects.size(),
-      addVertexNormals<AsteroidVertex>({
-
-         // front
-         {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-
-         // top
-         {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-
-         // bottom
-         {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f, -1.0f, -1.0}, {0.4f, 0.4f, 0.4f}},
-
-         // back
-         {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-
-         // right
-         {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{ 1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-
-         // left
-         {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
-         {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
-      }))), {
-          0,  1,  2,  3,  4,  5,
-          6,  7,  8,  9, 10, 11,
-         12, 13, 14, 15, 16, 17,
-         18, 19, 20, 21, 22, 23,
-         24, 25, 26, 27, 28, 29,
-         30, 31, 32, 33, 34, 35,
-      }, {
-         mat4(1.0f),
-         10.0f,
-         0
-      });
-
    asteroidPipeline.createDescriptorSetLayout();
    asteroidPipeline.createPipeline("shaders/asteroid-vert.spv", "shaders/asteroid-frag.spv");
@@ -604,17 +539,5 @@
       scale(mat4(1.0f), vec3(0.1f, 0.1f, 0.1f));
 
-   // vec3 pos = vec3(getRandomNum(-1.3f, 1.3f), -1.2f, getRandomNum(-5.5f, -4.5f));
-   // vec3 pos = vec3(getRandomNum(-1.3f, 1.3f), -1.2f, -2.0f);
-   // vec3 pos = vec3(1.0f, -1.2f, -1.0f);
-   vec3 pos = vec3(0.0504826f, -1.2f, 1.0f);
-
-   asteroidObjects[0].model_base =
-      translate(mat4(1.0f), pos) *
-      rotate(mat4(1.0f), radians(60.0f), vec3(1.0f, 1.0f, -1.0f)) *
-      scale(mat4(1.0f), vec3(0.1f, 0.1f, 0.1f));
-   asteroidObjects[0].model_transform = mat4(1.0); // Might not be needed
-
-   so_Asteroid.hp = 10.0f;
-   so_Asteroid.deleted = 0;
+   updateObject(shipObjects, shipPipeline, 0);
 }
 
@@ -713,6 +636,79 @@
                   createCommandBuffers();
                } else if (e.key.keycode == SDL_SCANCODE_Z) {
-                  cout << "Deleting asteroid..." << endl;
-                  so_Asteroid.deleted = so_Asteroid.deleted == 0 ? 1 : 0;
+                  vkDeviceWaitIdle(device);
+                  vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
+
+                  addObject(asteroidObjects, asteroidPipeline,
+                     addObjectIndex<AsteroidVertex>(asteroidObjects.size(),
+                     addVertexNormals<AsteroidVertex>({
+
+                        // front
+                        {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+
+                        // top
+                        {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+
+                        // bottom
+                        {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f, -1.0f, -1.0}, {0.4f, 0.4f, 0.4f}},
+
+                        // back
+                        {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+
+                        // right
+                        {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{ 1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+
+                        // left
+                        {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f,  1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f,  1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f, -1.0f}, {0.4f, 0.4f, 0.4f}},
+                        {{-1.0f, -1.0f,  1.0f}, {0.4f, 0.4f, 0.4f}},
+                     })), {
+                        0,  1,  2,  3,  4,  5,
+                        6,  7,  8,  9, 10, 11,
+                        12, 13, 14, 15, 16, 17,
+                        18, 19, 20, 21, 22, 23,
+                        24, 25, 26, 27, 28, 29,
+                        30, 31, 32, 33, 34, 35,
+                     }, {
+                        mat4(1.0f),
+                        10.0f,
+                        0
+                     });
+
+                  // translate(mat4(1.0f), vec3(getRandomNum(-1.3f, 1.3f), -1.2f, getRandomNum(-5.5f, -4.5f))) *
+                  asteroidObjects.back().model_base =
+                     translate(mat4(1.0f), vec3(getRandomNum(-1.3f, 1.3f), -1.2f, -2.0f)) *
+                     rotate(mat4(1.0f), radians(60.0f), vec3(1.0f, 1.0f, -1.0f)) *
+                     scale(mat4(1.0f), vec3(0.1f, 0.1f, 0.1f));
+
+                  updateObject(asteroidObjects, asteroidPipeline, asteroidObjects.size() - 1);
+                  createCommandBuffers();
                } else {
                   cout << "Key event detected" << endl;
@@ -743,11 +739,13 @@
 
       if (gui->keyPressed(SDL_SCANCODE_LEFT)) {
-         transformObject(shipObjects[0], translate(mat4(1.0f), vec3(-shipSpeed * elapsedTime, 0.0f, 0.0f)));
+         shipObjects[0].model_transform = translate(mat4(1.0f), vec3(-shipSpeed * elapsedTime, 0.0f, 0.0f))
+            * shipObjects[0].model_transform;
+
+         updateObject(shipObjects, shipPipeline, 0);
       } else if (gui->keyPressed(SDL_SCANCODE_RIGHT)) {
-         transformObject(shipObjects[0], translate(mat4(1.0f), vec3(shipSpeed * elapsedTime, 0.0f, 0.0f)));
-      }
-
-      if (gui->keyPressed(SDL_SCANCODE_DOWN)) {
-         transformObject(asteroidObjects[0], translate(mat4(1.0f), vec3(0.0f, 0.0f, asteroidSpeed * elapsedTime)));
+         shipObjects[0].model_transform = translate(mat4(1.0f), vec3(shipSpeed * elapsedTime, 0.0f, 0.0f))
+            * shipObjects[0].model_transform;
+
+         updateObject(shipObjects, shipPipeline, 0);
       }
 
@@ -759,6 +757,7 @@
 }
 
-// TODO: The view and projection mats only need to be updated once.
-// Create a separate function that can do this once per Vulkan image at the beginning
+// TODO: The only updates that need to happen once per Vulkan image are the SSBO ones,
+// which are already handled by updateObject(). Move this code to a different place,
+// where it will run just once per frame
 void VulkanGame::updateScene(uint32_t currentImage) {
    static auto startTime = chrono::high_resolution_clock::now();
@@ -767,28 +766,17 @@
    float time = chrono::duration<float, chrono::seconds::period>(currentTime - startTime).count();
 
-   // TODO: Will need to change this to go through all objects of all pipelines and update their model mats
-
-   so_Object.model =
-      translate(mat4(1.0f), vec3(0.0f, -2.0f, -0.0f)) *
-      rotate(mat4(1.0f), time * radians(90.0f), vec3(0.0f, 0.0f, 1.0f));
-
-   so_Ship.model = shipObjects[0].model_transform * shipObjects[0].model_base;
-
-   so_Asteroid.model = asteroidObjects[0].model_transform * asteroidObjects[0].model_base;
+   for (int i = 0; i < modelObjects.size(); i++) {
+      modelObjects[i].model_transform =
+         translate(mat4(1.0f), vec3(0.0f, -2.0f, -0.0f)) *
+         rotate(mat4(1.0f), time * radians(90.0f), vec3(0.0f, 0.0f, 1.0f));
+
+      updateObject(modelObjects, modelPipeline, i);
+   }
 
    VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_modelPipeline[currentImage], 0, object_VP_mats);
 
-   for (size_t i = 0; i < modelObjects.size(); i++) {
-      VulkanUtils::copyDataToMemory(device, modelPipeline.storageBufferSet.memory[currentImage],
-         i, so_Object);
-   }
-
    VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_shipPipeline[currentImage], 0, ship_VP_mats);
 
-   VulkanUtils::copyDataToMemory(device, shipPipeline.storageBufferSet.memory[currentImage], 0, so_Ship);
-
    VulkanUtils::copyDataToMemory(device, uniformBuffersMemory_asteroidPipeline[currentImage], 0, asteroid_VP_mats);
-
-   VulkanUtils::copyDataToMemory(device, asteroidPipeline.storageBufferSet.memory[currentImage], 0, so_Asteroid);
 }
 
@@ -1449,4 +1437,6 @@
    createFramebuffers();
 
+   // TODO: Move UBO creation/management into GraphicsPipeline_Vulkan, like I did with SSBOs
+
    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
       uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 860a0da7bda4763e3a1be95cfde80564e1cc9319)
+++ vulkan-game.hpp	(revision 2da64efeed527c21b6906cf773dcf113bbe77951)
@@ -75,4 +75,7 @@
 };
 
+// Have to figure out how to include an optional ssbo parameter for each object
+// Could probably use the same approach to make indices optional
+
 class VulkanGame {
    public:
@@ -158,5 +161,4 @@
 
       UBO_VP_mats object_VP_mats;
-      SSBO_ModelObject so_Object;
 
       GraphicsPipeline_Vulkan<ShipVertex, SSBO_ModelObject> shipPipeline;
@@ -168,5 +170,4 @@
 
       UBO_VP_mats ship_VP_mats;
-      SSBO_ModelObject so_Ship;
 
       GraphicsPipeline_Vulkan<AsteroidVertex, SSBO_Asteroid> asteroidPipeline;
@@ -178,5 +179,4 @@
 
       UBO_VP_mats asteroid_VP_mats;
-      SSBO_Asteroid so_Asteroid;
 
       Uint64 curTime, prevTime;
@@ -219,4 +219,8 @@
          const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo);
 
+      template<class VertexType, class SSBOType>
+      void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects,
+         GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index);
+
       template<class VertexType>
       vector<VertexType> addVertexNormals(vector<VertexType> vertices);
@@ -227,7 +231,4 @@
       template<class VertexType>
       vector<VertexType> centerObject(vector<VertexType> vertices);
-
-      template<class VertexType, class SSBOType>
-      void transformObject(SceneObject<VertexType, SSBOType>& obj, mat4 mat);
 
       void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
@@ -258,4 +259,18 @@
 
    pipeline.addVertices(vertices, indices, commandPool, graphicsQueue);
+}
+
+template<class VertexType, class SSBOType>
+void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects,
+      GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index) {
+   SceneObject<VertexType, SSBOType>& obj = objects[index];
+
+   obj.ssbo.model = obj.model_transform * obj.model_base;
+
+   // could probably re-calculate the object center here based on model
+   // I think the center should be calculated by using model * vec3(0, 0, 0)
+   // model_base is currently only used to set the original location of the ship and asteroids
+
+   pipeline.updateObject(index, obj.ssbo);
 }
 
@@ -326,8 +341,3 @@
 }
 
-template<class VertexType, class SSBOType>
-void VulkanGame::transformObject(SceneObject<VertexType, SSBOType>& obj, mat4 mat) {
-   obj.model_transform = mat * obj.model_transform;
-}
-
 #endif // _VULKAN_GAME_H
