Skip to content

Instantly share code, notes, and snippets.

@Pikachuxxxx
Last active July 24, 2024 19:12
Show Gist options
  • Save Pikachuxxxx/5c4c490a7d7679824e0e18af42918efc to your computer and use it in GitHub Desktop.
Save Pikachuxxxx/5c4c490a7d7679824e0e18af42918efc to your computer and use it in GitHub Desktop.
A script to generate an UV Sphere vertices, normals, texture coordinates and Indices.
std::vector<glm::vec3> sphereVertices;
std::vector<glm::vec3> sphereNormals;
std::vector<glm::vec2> sphereUVs;
std::vector<unsigned int> sphereIndices;
void GenerateSphereSmooth(int radius, int latitudes, int longitudes)
{
if(longitudes < 3)
longitudes = 3;
if(latitudes < 2)
latitudes = 2;
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> uv;
std::vector<unsigned int> indices;
float nx, ny, nz, lengthInv = 1.0f / radius; // normal
// Temporary vertex
struct Vertex
{
float x, y, z, s, t; // Postion and Texcoords
};
float deltaLatitude = M_PI / latitudes;
float deltaLongitude = 2 * M_PI / longitudes;
float latitudeAngle;
float longitudeAngle;
// Compute all vertices first except normals
for (int i = 0; i <= latitudes; ++i)
{
latitudeAngle = M_PI / 2 - i * deltaLatitude; /* Starting -pi/2 to pi/2 */
float xy = radius * cosf(latitudeAngle); /* r * cos(phi) */
float z = radius * sinf(latitudeAngle); /* r * sin(phi )*/
/*
* We add (latitudes + 1) vertices per longitude because of equator,
* the North pole and South pole are not counted here, as they overlap.
* The first and last vertices have same position and normal, but
* different tex coords.
*/
for (int j = 0; j <= longitudes; ++j)
{
longitudeAngle = j * deltaLongitude;
Vertex vertex;
vertex.x = xy * cosf(longitudeAngle); /* x = r * cos(phi) * cos(theta) */
vertex.y = xy * sinf(longitudeAngle); /* y = r * cos(phi) * sin(theta) */
vertex.z = z; /* z = r * sin(phi) */
vertex.s = (float)j/longitudes; /* s */
vertex.t = (float)i/latitudes; /* t */
vertices.push_back(glm::vec3(vertex.x, vertex.y, vertex.z));
uv.push_back(glm::vec2(vertex.s, vertex.t));
// normalized vertex normal
nx = vertex.x * lengthInv;
ny = vertex.y * lengthInv;
nz = vertex.z * lengthInv;
normals.push_back(glm::vec3(nx, ny, nz));
}
}
/*
* Indices
* k1--k1+1
* | / |
* | / |
* k2--k2+1
*/
unsigned int k1, k2;
for(int i = 0; i < latitudes; ++i)
{
k1 = i * (longitudes + 1);
k2 = k1 + longitudes + 1;
// 2 Triangles per latitude block excluding the first and last longitudes blocks
for(int j = 0; j < longitudes; ++j, ++k1, ++k2)
{
if (i != 0)
{
indices.push_back(k1);
indices.push_back(k2);
indices.push_back(k1 + 1);
}
if (i != (latitudes - 1))
{
indices.push_back(k1 + 1);
indices.push_back(k2);
indices.push_back(k2 + 1);
}
}
}
sphereVertices = vertices;
sphereNormals = normals;
sphereUVs = uv;
sphereIndices = indices;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment