Cylinder mesh generation

Generates the vertices and triangles for a cylinder mesh quickly.
 avatar
unknown
c_cpp
4 years ago
2.5 kB
32
Indexable
// A cylinder mesh.
template<u32 H = 1, u32 W = 1>
struct b3CylinderMesh
{
	u32 vertexCount;
	b3Vec3 vertices[(H + 1) * (W + 1)];
	u32 indexCount;
	u32 indices[3 * 2 * H * W + 3 * 2 * (((W + 1) - 1) - 1)];
	
	b3CylinderMesh()
	{
		// Build vertices
		
		// Angular increment in range [0, 2*pi]
		scalar kPhiInc = scalar(2) * B3_PI / scalar(W);
		
		// Longitude increment in range [0, 1]
		scalar kYInc = scalar(1) / scalar(H);
		
		vertexCount = 0;
		for (u32 i = 0; i < H + 1; ++i)
		{
			// Plane to cylindrical coordinates
			scalar y = scalar(i) * kYInc;
				
			for (u32 j = 0; j < W + 1; ++j)
			{
				// Plane to cylindrical coordinates
				scalar phi = scalar(j) * kPhiInc;	
				scalar cos_phi = cos(phi);
				scalar sin_phi = sin(phi);
				
				// Cylindrical to Cartesian coordinates		
				b3Vec3 p;
				p.x = cos_phi;
				p.y = y - scalar(0.5); // Centralize
				p.z = sin_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)
			{
				// 1*|----|*4
				//   |----|
				// 2*|----|*3
				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);
		
		// Lower circle
		u32 i1 = 0;
		for (u32 i2 = i1 + 1; i2 < (W + 1) - 1; ++i2)
		{
			u32 i3 = i2 + 1;
			
			u32 v1 = GetVertex(0, i1);
			u32 v2 = GetVertex(0, i2);
			u32 v3 = GetVertex(0, i3);
			
			indices[indexCount++] = v1;
			indices[indexCount++] = v2;
			indices[indexCount++] = v3;
		}
		
		// Upper circle
		i1 = 0;
		for (u32 i2 = i1 + 1; i2 < (W + 1) - 1; ++i2)
		{
			u32 i3 = i2 + 1;
			
			u32 v1 = GetVertex(H, i1);
			u32 v2 = GetVertex(H, i2);
			u32 v3 = GetVertex(H, i3);
			
			// Flip order to ensure CCW
			indices[indexCount++] = v3;
			indices[indexCount++] = v2;
			indices[indexCount++] = v1;
		}
		
		B3_ASSERT(indexCount == 3 * 2 * H * W + 3 * 2 * (((W + 1) - 1) - 1));
	}
	
	u32 GetVertex(u32 i, u32 j)
	{
		B3_ASSERT(i < H + 1);
		B3_ASSERT(j < W + 1);
		return i * (W + 1) + j;
	}
};
Editor is loading...