docs: public static void generateCapsule(TFloatList positions, TFloatList normals, TIntList indices, float radius, float height) {
  
          // Start with the top hemisphere
          final float halfHeight = height / 2;
          final Vector3f top = new Vector3f(0, halfHeight + radius, 0);
          // Add the point for the top of the hemisphere
          addVector(positions, top);
          addVector(normals, top.normalize());
          // Next use spherical coordinates to separate the surface of the hemisphere into a grid
          final int thetaSections = 30, phiSections = 10;
          final int thetaIncrement = 360 / thetaSections, phiIncrement = 90 / phiSections;
          // For every point on that grid
          for (int phi = phiIncrement; phi <= 90; phi += phiIncrement) {
              for (int theta = thetaIncrement / 2; theta <= 360; theta += thetaIncrement) {
                  // Compute the point in cartesian coordinates
                  final double radPhi = Math.toRadians(phi);
                  final double radTheta = Math.toRadians(theta);
                  final float sinPhi = TrigMath.sin(radPhi);
                  final Vector3f p = new Vector3f(
                          radius * sinPhi * TrigMath.sin(radTheta),
                          radius * TrigMath.cos(radPhi),
                          radius * sinPhi * TrigMath.cos(radTheta));
                  // Add it to the positions
                  addVector(positions, p.add(0, halfHeight, 0));
                  addVector(normals, p.normalize());
                  // Add the indices
                  final int i0 = computeIndex(phiIncrement, phi, thetaSections, thetaIncrement, theta);
                  final int i1 = computeIndex(phiIncrement, phi, thetaSections, thetaIncrement, theta + thetaIncrement);
                  final int i2 = computeIndex(phiIncrement, phi - phiIncrement, thetaSections, thetaIncrement, theta);
                  final int i3 = computeIndex(phiIncrement, phi - phiIncrement, thetaSections, thetaIncrement, theta + thetaIncrement);
                  // Special case for the top apex vertex
                  if (i2 == i3) {
                      addAll(indices, i0, i1, i3);
                  } else {
                      addAll(indices, i0, i1, i3, i0, i3, i2);
                  }
              }
          }
          // Next do the bottom hemisphere
          final Vector3f bottom = top.negate();
          // Get the offset in the positions of the bottom hemisphere
          final int bottomIndexOffset = positions.size() / 3;
          // Add the point for the top of the hemisphere
          addVector(positions, bottom);
          addVector(normals, bottom.normalize());
          // For every point on the grid
          for (int phi = phiIncrement; phi <= 90; phi += phiIncrement) {
              for (int theta = thetaIncrement / 2; theta <= 360; theta += thetaIncrement) {
                  // Compute the point in cartesian coordinates
                  final double radPhi = Math.toRadians(phi);
                  final double radTheta = Math.toRadians(theta);
                  final float sinPhi = TrigMath.sin(radPhi);
                  final Vector3f p = new Vector3f(
                          radius * sinPhi * TrigMath.sin(radTheta),
                          -radius * TrigMath.cos(radPhi),
                          radius * sinPhi * TrigMath.cos(radTheta));
                  // Add it to the positions
                  addVector(positions, p.sub(0, halfHeight, 0));
                  addVector(normals, p.normalize());
                  // Add the indices
                  final int i0 = computeIndex(phiIncrement, phi, thetaSections, thetaIncrement, theta) + bottomIndexOffset;
                  final int i1 = computeIndex(phiIncrement, phi, thetaSections, thetaIncrement, theta + thetaIncrement) + bottomIndexOffset;
                  final int i2 = computeIndex(phiIncrement, phi - phiIncrement, thetaSections, thetaIncrement, theta) + bottomIndexOffset;
                  final int i3 = computeIndex(phiIncrement, phi - phiIncrement, thetaSections, thetaIncrement, theta + thetaIncrement) + bottomIndexOffset;
                  // Special case for the bottom apex vertex
                  if (i2 == i3) {
                      addAll(indices, i0, i3, i1);
                  } else {
                      addAll(indices, i0, i3, i1, i0, i2, i3);
                  }
              }
          }
          // Finally join both hemispheres
          for (int theta = thetaIncrement / 2, i = 0; theta <= 360; theta += thetaIncrement, i += 2) {
              // Add the indices
              final int i0 = computeIndex(phiIncrement, 90, thetaSections, thetaIncrement, theta);
              final int i1 = computeIndex(phiIncrement, 90, thetaSections, thetaIncrement, theta + thetaIncrement);
              final int i2 = computeIndex(phiIncrement, 90, thetaSections, thetaIncrement, theta) + bottomIndexOffset;
              final int i3 = computeIndex(phiIncrement, 90, thetaSections, thetaIncrement, theta + thetaIncrement) + bottomIndexOffset;
              addAll(indices, i1, i0, i2, i1, i2, i3);
          }
      }