Circular cursor + dragging
[opengl.git] / shapes.hpp
index 92cc8adb0882ecd6c3d3c54955bad6eb0a25d286..876ce3c550ebf97c3951850d4483f1ddaf6fe1ae 100644 (file)
@@ -1,4 +1,6 @@
 #include <array>
+#include <vector>
+#include <cmath>
 #define GLM_FORCE_PURE
 #include <glm/glm.hpp>
 
@@ -24,7 +26,70 @@ constexpr array<glm::vec3, 6> plane() {
        });
 }
 
-constexpr array<glm::vec3, 36> cube() {
+inline vector<glm::vec3> cube() {
+       int i = 0;
+       vector<glm::vec3> vertices(36);
+       
+       const array<glm::vec3, 4> front = {
+               glm::vec3(1, -1, -1),
+               glm::vec3(-1, -1, -1),
+               glm::vec3(-1, 1, -1),
+               glm::vec3(1, 1, -1)
+       };
+       
+       for (auto v: quadToTriangles(front))
+               vertices[i++] = v;
+
+       const array<glm::vec3, 4> back = {
+               glm::vec3(1, 1, 1),
+               glm::vec3(-1, 1, 1),
+               glm::vec3(-1, -1, 1),
+               glm::vec3(1, -1, 1)
+       };
+       for (auto v: quadToTriangles(back))
+               vertices[i++] = v;
+
+
+       const array<glm::vec3, 4> top = {
+               glm::vec3(1, 1, -1),
+               glm::vec3(-1, 1, -1),
+               glm::vec3(-1, 1, 1),
+               glm::vec3(1, 1, 1)
+       };
+       for (auto v: quadToTriangles(top))
+               vertices[i++] = v;
+
+       const array<glm::vec3, 4> bottom = {
+               glm::vec3(1, -1, 1),
+               glm::vec3(-1, -1, 1),
+               glm::vec3(-1, -1, -1),
+               glm::vec3(1, -1, -1)
+       };
+       for (auto v: quadToTriangles(bottom))
+               vertices[i++] = v;
+
+       const array<glm::vec3, 4> left = {
+               glm::vec3(-1, 1, 1),
+               glm::vec3(-1, 1, -1),
+               glm::vec3(-1, -1, -1),
+               glm::vec3(-1, -1, 1)
+       };
+       for (auto v: quadToTriangles(left))
+               vertices[i++] = v;
+
+       const array<glm::vec3, 4> right = {
+               glm::vec3(1, 1, -1),
+               glm::vec3(1, 1, 1),
+               glm::vec3(1, -1, 1),
+               glm::vec3(1, -1, -1)
+       };
+       for (auto v: quadToTriangles(right))
+               vertices[i++] = v;
+
+       return vertices;
+}
+
+constexpr array<glm::vec3, 36> cubeArray() {
        int i = 0;
        array<glm::vec3, 36> vertices;
        
@@ -112,7 +177,72 @@ constexpr glm::vec3 pyramid[18] = {
        glm::vec3(1, -1, 1)
 };
 
-// TODO: Add a sphere
-/* constexpr std::vector<glm::vec3> sphere() { */
+// 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;
+}