+
+// taken from http://www.songho.ca/opengl/gl_sphere.html
+#define SECTOR_COUNT 16
+#define STACK_COUNT 16
+inline std::vector<glm::vec3> sphere(float radius = 1) {
+ float sectorStep = 2 * M_PI / SECTOR_COUNT;
+ float stackStep = M_PI / STACK_COUNT;
+
+ std::vector<glm::vec3> vertices;
+
+ for(int i = 0; i <= STACK_COUNT; i++) {
+ float stackAngle = M_PI / 2 - i * stackStep; // starting from pi/2 to -pi/2
+ float xy = radius * cosf(stackAngle); // r * cos(u)
+ float z = radius * sinf(stackAngle); // r * sin(u)
+
+ // add (sectorCount+1) vertices per stack
+ // the first and last vertices have same position and normal, but different tex coords
+ for(int j = 0; j <= SECTOR_COUNT; j++)
+ {
+ float sectorAngle = j * sectorStep; // starting from 0 to 2pi
+
+ // vertex position (x, y, z)
+ float x = xy * cosf(sectorAngle); // r * cos(u) * cos(v)
+ float y = xy * sinf(sectorAngle); // r * cos(u) * sin(v)
+ vertices.push_back({x, y, z});
+
+ // normalized vertex normal (nx, ny, nz)
+ /* nx = x * lengthInv; */
+ /* ny = y * lengthInv; */
+ /* nz = z * lengthInv; */
+ /* normals.push_back(nx); */
+ /* normals.push_back(ny); */
+ /* normals.push_back(nz); */
+
+ }
+ }
+ return vertices;
+}
+
+inline std::vector<unsigned int> sphereIndices() {
+ // generate CCW index list of sphere triangles
+ vector<unsigned int> indices;
+ int k1, k2;
+ for(int i = 0; i < STACK_COUNT; ++i)
+ {
+ k1 = i * (SECTOR_COUNT + 1); // beginning of current stack
+ k2 = k1 + SECTOR_COUNT + 1; // beginning of next stack
+
+ for(int j = 0; j < SECTOR_COUNT; ++j, ++k1, ++k2)
+ {
+ // 2 triangles per sector excluding first and last stacks
+ // k1 => k2 => k1+1
+ if(i != 0)
+ {
+ indices.push_back(k1);
+ indices.push_back(k2);
+ indices.push_back(k1 + 1);
+ }
+
+ // k1+1 => k2 => k2+1
+ if(i != (STACK_COUNT-1))
+ {
+ indices.push_back(k1 + 1);
+ indices.push_back(k2);
+ indices.push_back(k2 + 1);
+ }
+ }
+ }
+ return indices;
+}