UV Sphere

Generates a UV sphere mesh.
mail@pastecode.io avatar
unknown
c_cpp
2 years ago
1.8 kB
7
Indexable
Never
// A (H + 1) x (W + 1) UV sphere mesh stored in row-major order.
// v(i, j) = i * (W + 1) + j
template<u32 H = 1, u32 W = 1>
struct b3SphereMesh
{
	u32 vertexCount;
	b3Vec3 vertices[(H + 1) * (W + 1)];
	u32 indexCount;
	u32 indices[3 * 2 * H * W];
	
	b3SphereMesh()
	{
		// Build vertices
		
		// Latitude increment in range [0, pi]
		scalar kThetaInc = B3_PI / scalar(H);
		
		// Longitude increment in range [0, 2*pi]
		scalar kPhiInc = 2.0f * B3_PI / scalar(W);
		
		vertexCount = 0;
		for (u32 i = 0; i < H + 1; ++i)
		{
			// Plane to spherical coordinates
			scalar theta = scalar(i) * kThetaInc;
			scalar cos_theta = cos(theta);
			scalar sin_theta = sin(theta);
				
			for (u32 j = 0; j < W + 1; ++j)
			{
				scalar phi = scalar(j) * kPhiInc;	
				scalar cos_phi = cos(phi);
				scalar sin_phi = sin(phi);
				
				// Spherical to Cartesian coordinates		
				b3Vec3 p;
				p.x = sin_theta * sin_phi;
				p.y = cos_theta;
				p.z = sin_theta * cos_phi;
				
				u32 vertex = GetVertex(i, j);
				vertices[vertex] = p;
				++vertexCount;
			}
		}
		
		B3_ASSERT(vertexCount == (H + 1) * (W + 1));
		
		// Build triangles
		indexCount = 0;
		for (u32 i = 0; i < H; ++i)
		{
			for (u32 j = 0; j < W; ++j)
			{
				u32 v1 = GetVertex(i, j);
				u32 v2 = GetVertex(i + 1, j);
				u32 v3 = GetVertex(i + 1, j + 1);
				u32 v4 = GetVertex(i, j + 1);

				indices[indexCount++] = v1;
				indices[indexCount++] = v2;
				indices[indexCount++] = v3;

				indices[indexCount++] = v3;
				indices[indexCount++] = v4;
				indices[indexCount++] = v1;
			}
		}

		B3_ASSERT(indexCount == 3 * 2 * H * W);
	}

	u32 GetVertex(u32 i, u32 j)
	{
		B3_ASSERT(i < H + 1);
		B3_ASSERT(j < W + 1);
		return i * (W + 1) + j;
	}
};