Index: new-game.cpp
===================================================================
--- new-game.cpp	(revision dba67b2d6019f09a5a292b3b36444eaeae9dcb3c)
+++ new-game.cpp	(revision 58088c00e2fc669fc169827e50bc2b90b26bd88d)
@@ -47,4 +47,6 @@
    vector<GLfloat> selected_colors;
    bool deleted;
+   vec3 bounding_center;
+   GLfloat bounding_radius;
 };
 
@@ -94,4 +96,6 @@
                   GLuint model_mat_idx_vbo);
 void removeObjectFromScene(int objectId, GLuint ubo);
+
+void calculateObjectBoundingBox(SceneObject& obj);
 
 void initializeBuffers(
@@ -420,198 +424,198 @@
    obj.points = {
       //back
-      -0.5f,  0.3f,  0.0f,
-      -0.5f,  0.0f,  0.0f,
-       0.5f,  0.0f,  0.0f,
-      -0.5f,  0.3f,  0.0f,
-       0.5f,  0.0f,  0.0f,
-       0.5f,  0.3f,  0.0f,
+      -0.5f,    0.3f,    0.0f,
+      -0.5f,    0.0f,    0.0f,
+       0.5f,    0.0f,    0.0f,
+      -0.5f,    0.3f,    0.0f,
+       0.5f,    0.0f,    0.0f,
+       0.5f,    0.3f,    0.0f,
 
       // left back
-      -0.5f,  0.3f, -2.0f,
-      -0.5f,  0.0f, -2.0f,
-      -0.5f,  0.0f,  0.0f,
-      -0.5f,  0.3f, -2.0f,
-      -0.5f,  0.0f,  0.0f,
-      -0.5f,  0.3f,  0.0f,
+      -0.5f,    0.3f,   -2.0f,
+      -0.5f,    0.0f,   -2.0f,
+      -0.5f,    0.0f,    0.0f,
+      -0.5f,    0.3f,   -2.0f,
+      -0.5f,    0.0f,    0.0f,
+      -0.5f,    0.3f,    0.0f,
 
       // right back
-       0.5f,  0.3f,  0.0f,
-       0.5f,  0.0f,  0.0f,
-       0.5f,  0.0f, -2.0f,
-       0.5f,  0.3f,  0.0f,
-       0.5f,  0.0f, -2.0f,
-       0.5f,  0.3f, -2.0f,
+       0.5f,    0.3f,    0.0f,
+       0.5f,    0.0f,    0.0f,
+       0.5f,    0.0f,   -2.0f,
+       0.5f,    0.3f,    0.0f,
+       0.5f,    0.0f,   -2.0f,
+       0.5f,    0.3f,   -2.0f,
 
       // left mid
-      -0.25f,  0.3f, -3.0f,
-      -0.25f,  0.0f, -3.0f,
-      -0.5f,  0.0f, -2.0f,
-      -0.25f,  0.3f, -3.0f,
-      -0.5f,  0.0f, -2.0f,
-      -0.5f,  0.3f, -2.0f,
+      -0.25f,   0.3f,   -3.0f,
+      -0.25f,   0.0f,   -3.0f,
+      -0.5f,    0.0f,   -2.0f,
+      -0.25f,   0.3f,   -3.0f,
+      -0.5f,    0.0f,   -2.0f,
+      -0.5f,    0.3f,   -2.0f,
 
       // right mid
-       0.5f,  0.3f, -2.0f,
-       0.5f,  0.0f, -2.0f,
-       0.25f,  0.0f, -3.0f,
-       0.5f,  0.3f, -2.0f,
-       0.25f,  0.0f, -3.0f,
-       0.25f,  0.3f, -3.0f,
+       0.5f,    0.3f,   -2.0f,
+       0.5f,    0.0f,   -2.0f,
+       0.25f,   0.0f,   -3.0f,
+       0.5f,    0.3f,   -2.0f,
+       0.25f,   0.0f,   -3.0f,
+       0.25f,   0.3f,   -3.0f,
 
       // left front
-       0.0f,  0.0f, -3.5f,
-      -0.25f,  0.0f, -3.0f,
-      -0.25f,  0.3f, -3.0f,
+       0.0f,    0.0f,   -3.5f,
+      -0.25f,   0.0f,   -3.0f,
+      -0.25f,   0.3f,   -3.0f,
 
       // right front
-       0.25f,  0.3f, -3.0f,
-       0.25f,  0.0f, -3.0f,
-       0.0f,  0.0f, -3.5f,
+       0.25f,   0.3f,   -3.0f,
+       0.25f,   0.0f,   -3.0f,
+       0.0f,    0.0f,   -3.5f,
 
       // top back
-      -0.5f,  0.3f, -2.0f,
-      -0.5f,  0.3f,  0.0f,
-       0.5f,  0.3f,  0.0f,
-      -0.5f,  0.3f, -2.0f,
-       0.5f,  0.3f,  0.0f,
-       0.5f,  0.3f, -2.0f,
+      -0.5f,    0.3f,   -2.0f,
+      -0.5f,    0.3f,    0.0f,
+       0.5f,    0.3f,    0.0f,
+      -0.5f,    0.3f,   -2.0f,
+       0.5f,    0.3f,    0.0f,
+       0.5f,    0.3f,   -2.0f,
 
       // bottom back
-      -0.5f,  0.0f,  0.0f,
-      -0.5f,  0.0f, -2.0f,
-       0.5f,  0.0f,  0.0f,
-       0.5f,  0.0f,  0.0f,
-      -0.5f,  0.0f, -2.0f,
-       0.5f,  0.0f, -2.0f,
+      -0.5f,    0.0f,    0.0f,
+      -0.5f,    0.0f,   -2.0f,
+       0.5f,    0.0f,    0.0f,
+       0.5f,    0.0f,    0.0f,
+      -0.5f,    0.0f,   -2.0f,
+       0.5f,    0.0f,   -2.0f,
 
       // top mid
-      -0.25f,  0.3f, -3.0f,
-      -0.5f,  0.3f, -2.0f,
-       0.5f,  0.3f, -2.0f,
-      -0.25f,  0.3f, -3.0f,
-       0.5f,  0.3f, -2.0f,
-       0.25f,  0.3f, -3.0f,
+      -0.25f,   0.3f,   -3.0f,
+      -0.5f,    0.3f,   -2.0f,
+       0.5f,    0.3f,   -2.0f,
+      -0.25f,   0.3f,   -3.0f,
+       0.5f,    0.3f,   -2.0f,
+       0.25f,   0.3f,   -3.0f,
 
       // bottom mid
-      -0.5f,  0.0f, -2.0f,
-      -0.25f,  0.0f, -3.0f,
-       0.5f,  0.0f, -2.0f,
-       0.5f,  0.0f, -2.0f,
-      -0.25f,  0.0f, -3.0f,
-       0.25f,  0.0f, -3.0f,
+      -0.5f,    0.0f,   -2.0f,
+      -0.25f,   0.0f,   -3.0f,
+       0.5f,    0.0f,   -2.0f,
+       0.5f,    0.0f,   -2.0f,
+      -0.25f,   0.0f,   -3.0f,
+       0.25f,   0.0f,   -3.0f,
 
       // top front
-      -0.25f,  0.3f, -3.0f,
-       0.25f,  0.3f, -3.0f,
-       0.0f,  0.0f, -3.5f,
+      -0.25f,   0.3f,   -3.0f,
+       0.25f,   0.3f,   -3.0f,
+       0.0f,    0.0f,   -3.5f,
 
       // bottom front
-       0.25f,  0.0f, -3.0f,
-      -0.25f,  0.0f, -3.0f,
-       0.0f,  0.0f, -3.5f,
+       0.25f,   0.0f,   -3.0f,
+      -0.25f,   0.0f,   -3.0f,
+       0.0f,    0.0f,   -3.5f,
 
       // left wing start back
-      -1.5f,  0.3f,  0.0f,
-      -1.5f,  0.0f,  0.0f,
-      -0.5f,  0.0f,  0.0f,
-      -1.5f,  0.3f,  0.0f,
-      -0.5f,  0.0f,  0.0f,
-      -0.5f,  0.3f,  0.0f,
+      -1.5f,    0.3f,    0.0f,
+      -1.5f,    0.0f,    0.0f,
+      -0.5f,    0.0f,    0.0f,
+      -1.5f,    0.3f,    0.0f,
+      -0.5f,    0.0f,    0.0f,
+      -0.5f,    0.3f,    0.0f,
 
       // left wing start top
-      -0.5f,  0.3f, -0.3f,
-      -1.3f,  0.3f, -0.3f,
-      -1.5f,  0.3f,  0.0f,
-      -0.5f,  0.3f, -0.3f,
-      -1.5f,  0.3f,  0.0f,
-      -0.5f,  0.3f,  0.0f,
+      -0.5f,    0.3f,   -0.3f,
+      -1.3f,    0.3f,   -0.3f,
+      -1.5f,    0.3f,    0.0f,
+      -0.5f,    0.3f,   -0.3f,
+      -1.5f,    0.3f,    0.0f,
+      -0.5f,    0.3f,    0.0f,
 
       // left wing start front
-      -0.5f,  0.3f, -0.3f,
-      -0.5f,  0.0f, -0.3f,
-      -1.3f,  0.0f, -0.3f,
-      -0.5f,  0.3f, -0.3f,
-      -1.3f,  0.0f, -0.3f,
-      -1.3f,  0.3f, -0.3f,
+      -0.5f,    0.3f,   -0.3f,
+      -0.5f,    0.0f,   -0.3f,
+      -1.3f,    0.0f,   -0.3f,
+      -0.5f,    0.3f,   -0.3f,
+      -1.3f,    0.0f,   -0.3f,
+      -1.3f,    0.3f,   -0.3f,
 
       // left wing start bottom
-      -0.5f, 0.0f, 0.0f,
-      -1.5f, 0.0f, 0.0f,
-      -1.3f, 0.0f, -0.3f,
-      -0.5f, 0.0f, 0.0f,
-      -1.3f, 0.0f, -0.3f,
-      -0.5f, 0.0f, -0.3f,
+      -0.5f,    0.0f,    0.0f,
+      -1.5f,    0.0f,    0.0f,
+      -1.3f,    0.0f,   -0.3f,
+      -0.5f,    0.0f,    0.0f,
+      -1.3f,    0.0f,   -0.3f,
+      -0.5f,    0.0f,   -0.3f,
 
       // left wing end outside
-      -1.5f,  0.3f,  0.0f,
-      -2.2f,  0.15f, -0.8f,
-      -1.5f,  0.0f,  0.0f,
+      -1.5f,    0.3f,    0.0f,
+      -2.2f,    0.15f,  -0.8f,
+      -1.5f,    0.0f,    0.0f,
 
       // left wing end top
-      -1.3f,  0.3f, -0.3f,
-      -2.2f,  0.15f, -0.8f,
-      -1.5f,  0.3f,  0.0f,
+      -1.3f,    0.3f,   -0.3f,
+      -2.2f,    0.15f,  -0.8f,
+      -1.5f,    0.3f,    0.0f,
 
       // left wing end front
-      -1.3f, 0.0f, -0.3f,
-      -2.2f, 0.15f, -0.8f,
-      -1.3f, 0.3f, -0.3f,
+      -1.3f,    0.0f,   -0.3f,
+      -2.2f,    0.15f,  -0.8f,
+      -1.3f,    0.3f,   -0.3f,
 
       // left wing end bottom
-      -1.5f, 0.0f, 0.0f,
-      -2.2f,  0.15f, -0.8f,
-      -1.3f, 0.0f, -0.3f,
+      -1.5f,    0.0f,    0.0f,
+      -2.2f,    0.15f,  -0.8f,
+      -1.3f,    0.0f,   -0.3f,
 
       // right wing start back
-       1.5f, 0.0f, 0.0f,
-       1.5f, 0.3f, 0.0f,
-       0.5f, 0.0f, 0.0f,
-       0.5f, 0.0f, 0.0f,
-       1.5f, 0.3f, 0.0f,
-       0.5f, 0.3f, 0.0f,
+       1.5f,    0.0f,    0.0f,
+       1.5f,    0.3f,    0.0f,
+       0.5f,    0.0f,    0.0f,
+       0.5f,    0.0f,    0.0f,
+       1.5f,    0.3f,    0.0f,
+       0.5f,    0.3f,    0.0f,
 
       // right wing start top
-       1.3f, 0.3f, -0.3f,
-       0.5f, 0.3f, -0.3f,
-       1.5f, 0.3f, 0.0f,
-       1.5f, 0.3f, 0.0f,
-       0.5f, 0.3f, -0.3f,
-       0.5f, 0.3f, 0.0f,
+       1.3f,    0.3f,   -0.3f,
+       0.5f,    0.3f,   -0.3f,
+       1.5f,    0.3f,    0.0f,
+       1.5f,    0.3f,    0.0f,
+       0.5f,    0.3f,   -0.3f,
+       0.5f,    0.3f,    0.0f,
 
       // right wing start front
-       0.5f,  0.0f, -0.3f,
-       0.5f,  0.3f, -0.3f,
-       1.3f,  0.0f, -0.3f,
-       1.3f,  0.0f, -0.3f,
-       0.5f,  0.3f, -0.3f,
-       1.3f,  0.3f, -0.3f,
+       0.5f,    0.0f,   -0.3f,
+       0.5f,    0.3f,   -0.3f,
+       1.3f,    0.0f,   -0.3f,
+       1.3f,    0.0f,   -0.3f,
+       0.5f,    0.3f,   -0.3f,
+       1.3f,    0.3f,   -0.3f,
 
       // right wing start bottom
-       1.5f, 0.0f, 0.0f,
-       0.5f, 0.0f, 0.0f,
-       1.3f, 0.0f, -0.3f,
-       1.3f, 0.0f, -0.3f,
-       0.5f, 0.0f, 0.0f,
-       0.5f, 0.0f, -0.3f,
+       1.5f,    0.0f,    0.0f,
+       0.5f,    0.0f,    0.0f,
+       1.3f,    0.0f,   -0.3f,
+       1.3f,    0.0f,   -0.3f,
+       0.5f,    0.0f,    0.0f,
+       0.5f,    0.0f,   -0.3f,
 
       // right wing end outside
-       2.2f,  0.15f, -0.8f,
-       1.5f,  0.3f,  0.0f,
-       1.5f,  0.0f,  0.0f,
+       2.2f,    0.15f,  -0.8f,
+       1.5f,    0.3f,    0.0f,
+       1.5f,    0.0f,    0.0f,
 
       // right wing end top
-       2.2f,  0.15f, -0.8f,
-       1.3f,  0.3f, -0.3f,
-       1.5f,  0.3f,  0.0f,
+       2.2f,    0.15f,  -0.8f,
+       1.3f,    0.3f,   -0.3f,
+       1.5f,    0.3f,    0.0f,
 
       // right wing end front
-       2.2f, 0.15f, -0.8f,
-       1.3f, 0.0f, -0.3f,
-       1.3f, 0.3f, -0.3f,
+       2.2f,    0.15f,  -0.8f,
+       1.3f,    0.0f,   -0.3f,
+       1.3f,    0.3f,   -0.3f,
 
       // right wing end bottom
-       2.2f,  0.15f, -0.8f,
-       1.5f, 0.0f, 0.0f,
-       1.3f, 0.0f, -0.3f,
+       2.2f,    0.15f,  -0.8f,
+       1.5f,    0.0f,    0.0f,
+       1.3f,    0.0f,   -0.3f,
    };
    obj.colors = {
@@ -816,52 +820,4 @@
       ubo,
       model_mat_idx_vbo);
-
-   /*
-   spawnAsteroid(vec3(0.0f, -1.2f, -21.5f), color_sp,
-      shaderBufferInfo,
-      points_vbo,
-      colors_vbo,
-      selected_colors_vbo,
-      texcoords_vbo,
-      normals_vbo,
-      ubo,
-      model_mat_idx_vbo);
-   spawnAsteroid(vec3(1.0f, -1.2f, -21.5f), color_sp,
-      shaderBufferInfo,
-      points_vbo,
-      colors_vbo,
-      selected_colors_vbo,
-      texcoords_vbo,
-      normals_vbo,
-      ubo,
-      model_mat_idx_vbo);
-   spawnAsteroid(vec3(-0.5f, -1.2f, -20.8f), color_sp,
-      shaderBufferInfo,
-      points_vbo,
-      colors_vbo,
-      selected_colors_vbo,
-      texcoords_vbo,
-      normals_vbo,
-      ubo,
-      model_mat_idx_vbo);
-   spawnAsteroid(vec3(-0.3f, -1.2f, -20.8f), color_sp,
-      shaderBufferInfo,
-      points_vbo,
-      colors_vbo,
-      selected_colors_vbo,
-      texcoords_vbo,
-      normals_vbo,
-      ubo,
-      model_mat_idx_vbo);
-   spawnAsteroid(vec3(-0.1f, -1.2f, -20.8f), color_sp,
-      shaderBufferInfo,
-      points_vbo,
-      colors_vbo,
-      selected_colors_vbo,
-      texcoords_vbo,
-      normals_vbo,
-      ubo,
-      model_mat_idx_vbo);
-   */
 
    GLuint vao = 0;
@@ -1373,4 +1329,10 @@
 
 void addObjectToSceneDuringInit(SceneObject& obj) {
+   // Each objects must have at least 3 points, so the size of
+   // the points array must be a positive multiple of 9
+   if (obj.points.size() == 0 || (obj.points.size() % 9) != 0) {
+      return;
+   }
+
    obj.id = objects.size(); // currently unused
    obj.num_points = obj.points.size() / 3;
@@ -1393,4 +1355,6 @@
       }
    }
+
+   calculateObjectBoundingBox(obj);
 
    objects.push_back(obj);
@@ -1410,6 +1374,6 @@
    BufferInfo* bufferInfo = &shaderBufferInfo[obj.shader_program];
 
-   // Check if the buffers aren't large enough to fit the new object and, if so, print an error and quit.
-   // This is a temporary sanity check to make sure things are working as expected
+   // Check if the buffers aren't large enough to fit the new object and, if so, call
+   // populateBuffers() to resize and repopupulate them
    if (bufferInfo->vbo_capacity < (bufferInfo->ubo_offset + obj.num_points) ||
       bufferInfo->ubo_capacity < (bufferInfo->ubo_offset + 1)) {
@@ -1445,4 +1409,57 @@
 }
 
+void calculateObjectBoundingBox(SceneObject& obj) {
+   GLfloat min_x = obj.points[0];
+   GLfloat max_x = obj.points[0];
+   GLfloat min_y = obj.points[1];
+   GLfloat max_y = obj.points[1];
+   GLfloat min_z = obj.points[2];
+   GLfloat max_z = obj.points[2];
+
+   // start from the second point
+   for (int i = 3; i < obj.points.size(); i += 3) {
+      if (min_x > obj.points[i]) {
+         min_x = obj.points[i];
+      }
+      else if (max_x < obj.points[i]) {
+         max_x = obj.points[i];
+      }
+
+      if (min_y > obj.points[i + 1]) {
+         min_y = obj.points[i + 1];
+      }
+      else if (max_y < obj.points[i + 1]) {
+         max_y = obj.points[i + 1];
+      }
+
+      if (min_z > obj.points[i + 2]) {
+         min_z = obj.points[i + 2];
+      }
+      else if (max_z < obj.points[i + 2]) {
+         max_z = obj.points[i + 2];
+      }
+   }
+
+   obj.bounding_center = vec3((min_x + max_x) / 2.0f, (min_y + max_y) / 2.0f, (min_z + max_z) / 2.0f);
+
+   GLfloat radius_x = max_x - obj.bounding_center.x;
+   GLfloat radius_y = max_y - obj.bounding_center.y;
+   GLfloat radius_z = max_z - obj.bounding_center.z;
+
+   obj.bounding_radius = radius_x;
+   if (obj.bounding_radius < radius_y)
+      obj.bounding_radius = radius_y;
+   if (obj.bounding_radius < radius_z)
+      obj.bounding_radius = radius_z;
+
+   for (int i = 0; i < obj.points.size(); i += 3) {
+      obj.points[i] -= obj.bounding_center.x;
+      obj.points[i + 1] -= obj.bounding_center.y;
+      obj.points[i + 2] -= obj.bounding_center.z;
+   }
+
+   obj.bounding_center = vec3(0.0f, 0.0f, 0.0f);
+}
+
 void initializeBuffers(
                   GLuint* points_vbo,
@@ -1626,5 +1643,5 @@
    }
 
-   obj.model_mat = obj.model_base * obj.model_transform;
+   obj.model_mat = obj.model_transform * obj.model_base;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
    glBufferSubData(GL_UNIFORM_BUFFER, obj.ubo_offset * sizeof(mat4), sizeof(mat4), value_ptr(obj.model_mat));
@@ -1635,5 +1652,5 @@
 
 void transformObject(SceneObject& obj, const mat4& transform, GLuint ubo) {
-   obj.model_transform = obj.model_transform * transform;
+   obj.model_transform = transform * obj.model_transform;
    obj.model_mat = obj.model_transform * obj.model_base;
 
