Skip to content

Instantly share code, notes, and snippets.

@Pikachuxxxx
Last active March 26, 2024 22:56
Show Gist options
  • Save Pikachuxxxx/a2454e98bb7723afd7251a891c18f194 to your computer and use it in GitHub Desktop.
Save Pikachuxxxx/a2454e98bb7723afd7251a891c18f194 to your computer and use it in GitHub Desktop.
A script to generate Cylinder/Cone vertices, indices, normals and uv coordinates
std::vector<glm::vec3> cylinderVertices;
std::vector<glm::vec3> cylinderNormals;
std::vector<glm::vec2> cylinderUVs;
std::vector<unsigned int> cylinderIndices;
void GenerateCylinder(int baseRadius, int topRadius, int height, int sectorCount)
{
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> uv;
std::vector<unsigned int> indices;
float x, y, z; // vertex position
float radius; // radius for each stack
const float PI = acos(-1);
float sectorStep = 2 * PI / sectorCount;
float sectorAngle; // radian
// compute the normal vector at 0 degree first
// tanA = (baseRadius-topRadius) / height
float zAngle = atan2(baseRadius - topRadius, height);
float x0 = cos(zAngle); // nx
float y0 = 0; // ny
float z0 = sin(zAngle); // nz
// rotate (x0,y0,z0) per sector angle
std::vector<float> sideNormals;
for(int i = 0; i <= sectorCount; ++i)
{
sectorAngle = i * sectorStep;
sideNormals.push_back(cos(sectorAngle)*x0 - sin(sectorAngle)*y0); // nx
sideNormals.push_back(sin(sectorAngle)*x0 + cos(sectorAngle)*y0); // ny
sideNormals.push_back(z0); // nz
}
std::vector<float> unitCircleVertices;
for(int i = 0; i <= sectorCount; ++i)
{
sectorAngle = i * sectorStep;
unitCircleVertices.push_back(cos(sectorAngle)); // x
unitCircleVertices.push_back(sin(sectorAngle)); // y
unitCircleVertices.push_back(0); // z
}
// remember where the base.top vertices start
unsigned int baseVertexIndex = (unsigned int)vertices.size();
// TODO: Convert this
// put vertices of base of cylinder
z = -height * 0.5f;
vertices.push_back(glm::vec3(0, 0, z));
normals.push_back(glm::vec3(0, 0, -1));
uv.push_back(glm::vec2(0.5f, 0.5f));
for(int i = 0, j = 0; i < sectorCount; ++i, j += 3)
{
x = unitCircleVertices[j];
y = unitCircleVertices[j+1];
vertices.push_back(glm::vec3(x * baseRadius, y * baseRadius, z));
normals.push_back(glm::vec3(0, 0, -1));
uv.push_back(glm::vec2(-x * 0.5f + 0.5f, -y * 0.5f + 0.5f));
}
// remember where the top vertices start
unsigned int topVertexIndex = (unsigned int)vertices.size();
// put vertices of top of cylinder
z = height * 0.5f;
vertices.push_back(glm::vec3(0, 0, z));
normals.push_back(glm::vec3(0, 0, 1));
uv.push_back(glm::vec2(0.5f, 0.5f));
for(int i = 0, j = 0; i < sectorCount; ++i, j += 3)
{
x = unitCircleVertices[j];
y = unitCircleVertices[j+1];
vertices.push_back(glm::vec3(x * topRadius, y * topRadius, z));
normals.push_back(glm::vec3(0, 0, 1));
uv.push_back(glm::vec2(x * 0.5f + 0.5f, -y * 0.5f + 0.5f));
}
int k1 = 0; // 1st vertex index at base
int k2 = sectorCount + 1; // 1st vertex index at top
for(int j = 0; j < sectorCount; ++j, ++k1, ++k2)
{
if(j == 0)
{
// 2 trianles per sector
indices.push_back(k1 + sectorCount);
indices.push_back(k1 + 1);
indices.push_back(k2 + sectorCount);
indices.push_back(k2 + sectorCount);
indices.push_back(k1 + 1);
indices.push_back(k2 + 1);
}
else
{
// 2 trianles per sector
indices.push_back(k1);
indices.push_back(k1 + 1);
indices.push_back(k2);
indices.push_back(k2);
indices.push_back(k1 + 1);
indices.push_back(k2 + 1);
}
}
// put indices for base
for(int i = 0, k = baseVertexIndex + 1; i < sectorCount; ++i, ++k)
{
if(i < (sectorCount - 1))
{
indices.push_back(baseVertexIndex);
indices.push_back(k + 1);
indices.push_back(k);
}
else // last triangle
{
indices.push_back(baseVertexIndex);
indices.push_back(baseVertexIndex + 1);
indices.push_back(k);
}
}
// put indices for top
for(int i = 0, k = topVertexIndex + 1; i < sectorCount; ++i, ++k)
{
if(i < (sectorCount - 1))
{
indices.push_back(topVertexIndex);
indices.push_back(k);
indices.push_back(k + 1);
}
else
{
indices.push_back(topVertexIndex);
indices.push_back(k);
indices.push_back(topVertexIndex + 1);
}
}
cylinderVertices = vertices;
cylinderNormals = normals;
cylinderUVs = uv;
cylinderIndices = indices;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment