Viraax

Untitled

Mar 26th, 2023
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.10 KB | None | 0 0
  1. Capsule::Capsule(int subdivisions, int tesselation, float height, float radius, int cap_subdivisions) :
  2.     subdivisions(subdivisions),
  3.     tesselation(tesselation),
  4.     height(height),
  5.     radius(radius),
  6.     cap_subdivisions(cap_subdivisions)
  7. {
  8.     auto radialSegments = tesselation;
  9.     auto heightSegments = subdivisions;
  10.  
  11.     auto radiusTop = radius;
  12.     auto radiusBottom = radius;
  13.  
  14.     auto heightMinusCaps = height - (radiusTop + radiusBottom);
  15.  
  16.     auto thetaStart = 0.0f;
  17.     constexpr auto thetaLength = 2.0f * glm::pi<float>();
  18.  
  19.     auto capsTopSegments = cap_subdivisions;
  20.     auto capsBottomSegments = cap_subdivisions;
  21.  
  22.     auto alpha = glm::acos((radiusBottom - radiusTop) / height);
  23.  
  24.     std::vector<std::vector<unsigned int>> index_array;
  25.     int index = 0;
  26.  
  27.     auto halfHeight = heightMinusCaps * 0.5f;
  28.  
  29.     constexpr auto pi2 = glm::pi<float>() * 0.5f;
  30.  
  31.     int x = 0;
  32.     int y = 0;
  33.     auto normal = glm::vec3(0.0f);
  34.     auto vertex = glm::vec3(0.0f);
  35.  
  36.     auto cosAlpha = glm::cos(alpha);
  37.     auto sinAlpha = glm::sin(alpha);
  38.  
  39.     auto cone_a = glm::vec2(radiusTop * sinAlpha, halfHeight + radiusTop * cosAlpha);
  40.     auto cone_b = glm::vec2(radiusBottom * sinAlpha, -halfHeight + radiusBottom * cosAlpha);
  41.     auto coneLength = glm::length(cone_a - cone_b);
  42.  
  43.     auto vl = radiusTop * alpha + coneLength + radiusBottom * (pi2 - alpha);
  44.  
  45.     float v = 0.0f;
  46.  
  47.     for (y = 0; y <= capsTopSegments; y++) {
  48.         std::vector<unsigned int> index_row;
  49.  
  50.         auto a = pi2 - alpha * ((float)y / capsTopSegments);
  51.  
  52.         v += (radiusTop * alpha) / capsTopSegments;
  53.  
  54.         auto cosA = glm::cos(a);
  55.         auto sinA = glm::sin(a);
  56.  
  57.         auto _radius = cosA * radiusTop;
  58.  
  59.         for (x = 0; x <= radialSegments; ++x) {
  60.             auto u = (float)x / radialSegments;
  61.             auto theta = u * thetaLength + thetaStart;
  62.             auto sinTheta = glm::sin(theta);
  63.             auto cosTheta = glm::cos(theta);
  64.  
  65.             vertex.x = _radius * sinTheta;
  66.             vertex.y = halfHeight + sinA * radiusTop;
  67.             vertex.z = _radius * cosTheta;
  68.             vertices.push_back(vertex.x);
  69.             vertices.push_back(vertex.y);
  70.             vertices.push_back(vertex.z);
  71.  
  72.             normal.x = cosA * sinTheta;
  73.             normal.y = sinA;
  74.             normal.z = cosA * cosTheta;
  75.             normals.push_back(normal.x);
  76.             normals.push_back(normal.y);
  77.             normals.push_back(normal.z);
  78.  
  79.             uvs.push_back(u);
  80.             uvs.push_back(v / vl);
  81.  
  82.             index_row.push_back(index);
  83.             index++;
  84.         }
  85.  
  86.         index_array.push_back(index_row);
  87.     }
  88.  
  89.     auto coneHeight = height - radiusTop - radiusBottom + cosAlpha * radiusTop - cosAlpha * radiusBottom;
  90.     auto slope = (sinAlpha * (radiusBottom - radiusTop)) / coneHeight;
  91.  
  92.     for (y = 1; y <= heightSegments; y++) {
  93.         std::vector<unsigned int> index_row;
  94.  
  95.         v += coneLength / (float)heightSegments;
  96.  
  97.         auto _radius = sinAlpha * (((float)y * (radiusBottom - radiusTop)) / (float)heightSegments + radiusTop);
  98.  
  99.         for (x = 0; x <= radialSegments; x++) {
  100.             auto u = (float)x / radialSegments;
  101.             auto theta = u * thetaLength + thetaStart;
  102.             auto sinTheta = glm::sin(theta);
  103.             auto cosTheta = glm::cos(theta);
  104.  
  105.             vertex.x = _radius * sinTheta;
  106.             vertex.y = halfHeight + cosAlpha * radiusTop - ((float)y * coneHeight) / (float)heightSegments;
  107.             vertex.z = _radius * cosTheta;
  108.             vertices.push_back(vertex.x);
  109.             vertices.push_back(vertex.y);
  110.             vertices.push_back(vertex.z);
  111.  
  112.             normal.x = sinTheta;
  113.             normal.y = slope;
  114.             normal.z = cosTheta;
  115.             normal = glm::normalize(normal);
  116.             normals.push_back(normal.x);
  117.             normals.push_back(normal.y);
  118.             normals.push_back(normal.z);
  119.  
  120.             uvs.push_back(u);
  121.             uvs.push_back(v / vl);
  122.  
  123.             index_row.push_back(index);
  124.  
  125.             index++;
  126.         }
  127.  
  128.         index_array.push_back(index_row);
  129.     }
  130.  
  131.     for (y = 1; y <= capsBottomSegments; y++) {
  132.         std::vector<unsigned int> index_row;
  133.  
  134.         auto a = pi2 - alpha - (glm::pi<float>() - alpha) * ((float)y / capsBottomSegments);
  135.         v += (radiusBottom * alpha) / capsBottomSegments;
  136.         auto cosA = glm::cos(a);
  137.         auto sinA = glm::sin(a);
  138.  
  139.         auto _radius = cosA * radiusBottom;
  140.  
  141.         for (x = 0; x <= radialSegments; ++x) {
  142.             auto u = (float)x / radialSegments;
  143.             auto theta = u * thetaLength + thetaStart;
  144.             auto sinTheta = glm::sin(theta);
  145.             auto cosTheta = glm::cos(theta);
  146.  
  147.             vertex.x = _radius * sinTheta;
  148.             vertex.y = -halfHeight + sinA * radiusBottom;
  149.             vertex.z = _radius * cosTheta;
  150.             vertices.push_back(vertex.x);
  151.             vertices.push_back(vertex.y);
  152.             vertices.push_back(vertex.z);
  153.  
  154.             normal.x = cosA * sinTheta;
  155.             normal.y = sinA;
  156.             normal.z = cosA * cosTheta;
  157.             normals.push_back(normal.x);
  158.             normals.push_back(normal.y);
  159.             normals.push_back(normal.z);
  160.  
  161.             uvs.push_back(u);
  162.             uvs.push_back(v / vl);
  163.             index_row.push_back(index);
  164.  
  165.             index++;
  166.         }
  167.  
  168.         index_array.push_back(index_row);
  169.     }
  170.  
  171.     for (x = 0; x < radialSegments; ++x) {
  172.         for (y = 0; y < capsTopSegments + heightSegments + capsBottomSegments; y++) {
  173.             auto i1 = index_array[y][x];
  174.             auto i2 = index_array[y + 1][x];
  175.             auto i3 = index_array[y + 1][x + 1];
  176.             auto i4 = index_array[y][x + 1];
  177.  
  178.             indices.push_back(i1);
  179.             indices.push_back(i2);
  180.             indices.push_back(i4);
  181.  
  182.             indices.push_back(i2);
  183.             indices.push_back(i3);
  184.             indices.push_back(i4);
  185.         }
  186.     }
  187.  
  188.     std::reverse(indices.begin(), indices.end());
  189. }
Add Comment
Please, Sign In to add comment