|
public static MeshDraft Capsule(float height, float radius, int segments = 32, int rings = 8) |
|
{ |
|
float cylinderHeight = height - radius*2; |
|
int vertexCount = 2*rings*segments + 2; |
|
int triangleCount = 4*rings*segments; |
|
float horizontalAngle = 360f/segments; |
|
float verticalAngle = 90f/rings; |
|
|
|
var vertices = new Vector3[vertexCount]; |
|
var normals = new Vector3[vertexCount]; |
|
var triangles = new int[3*triangleCount]; |
|
|
|
int vi = 2; |
|
int ti = 0; |
|
int topCapIndex = 0; |
|
int bottomCapIndex = 1; |
|
|
|
vertices[topCapIndex].Set(0, cylinderHeight/2 + radius, 0); |
|
normals[topCapIndex].Set(0, 1, 0); |
|
vertices[bottomCapIndex].Set(0, -cylinderHeight/2 - radius, 0); |
|
normals[bottomCapIndex].Set(0, -1, 0); |
|
|
|
for (int s = 0; s < segments; s++) |
|
{ |
|
for (int r = 1; r <= rings; r++) |
|
{ |
|
// Top cap vertex |
|
Vector3 normal = Geometry.PointOnSphere(1, s*horizontalAngle, 90 - r*verticalAngle); |
|
Vector3 vertex = new Vector3( |
|
x: radius*normal.x, |
|
y: radius*normal.y + cylinderHeight/2, |
|
z: radius*normal.z); |
|
vertices[vi] = vertex; |
|
normals[vi] = normal; |
|
vi++; |
|
|
|
// Bottom cap vertex |
|
vertices[vi].Set(vertex.x, -vertex.y, vertex.z); |
|
normals[vi].Set(normal.x, -normal.y, normal.z); |
|
vi++; |
|
|
|
int top_s1r1 = vi - 2; |
|
int top_s1r0 = vi - 4; |
|
int bot_s1r1 = vi - 1; |
|
int bot_s1r0 = vi - 3; |
|
int top_s0r1 = top_s1r1 - 2*rings; |
|
int top_s0r0 = top_s1r0 - 2*rings; |
|
int bot_s0r1 = bot_s1r1 - 2*rings; |
|
int bot_s0r0 = bot_s1r0 - 2*rings; |
|
if (s == 0) |
|
{ |
|
top_s0r1 += vertexCount - 2; |
|
top_s0r0 += vertexCount - 2; |
|
bot_s0r1 += vertexCount - 2; |
|
bot_s0r0 += vertexCount - 2; |
|
} |
|
|
|
// Create cap triangles |
|
if (r == 1) |
|
{ |
|
triangles[3*ti + 0] = topCapIndex; |
|
triangles[3*ti + 1] = top_s0r1; |
|
triangles[3*ti + 2] = top_s1r1; |
|
ti++; |
|
|
|
triangles[3*ti + 0] = bottomCapIndex; |
|
triangles[3*ti + 1] = bot_s1r1; |
|
triangles[3*ti + 2] = bot_s0r1; |
|
ti++; |
|
} |
|
else |
|
{ |
|
triangles[3*ti + 0] = top_s1r0; |
|
triangles[3*ti + 1] = top_s0r0; |
|
triangles[3*ti + 2] = top_s1r1; |
|
ti++; |
|
|
|
triangles[3*ti + 0] = top_s0r0; |
|
triangles[3*ti + 1] = top_s0r1; |
|
triangles[3*ti + 2] = top_s1r1; |
|
ti++; |
|
|
|
triangles[3*ti + 0] = bot_s0r1; |
|
triangles[3*ti + 1] = bot_s0r0; |
|
triangles[3*ti + 2] = bot_s1r1; |
|
ti++; |
|
|
|
triangles[3*ti + 0] = bot_s0r0; |
|
triangles[3*ti + 1] = bot_s1r0; |
|
triangles[3*ti + 2] = bot_s1r1; |
|
ti++; |
|
} |
|
} |
|
|
|
// Create side triangles |
|
int top_s1 = vi - 2; |
|
int top_s0 = top_s1 - 2*rings; |
|
int bot_s1 = vi - 1; |
|
int bot_s0 = bot_s1 - 2*rings; |
|
if (s == 0) |
|
{ |
|
top_s0 += vertexCount - 2; |
|
bot_s0 += vertexCount - 2; |
|
} |
|
|
|
triangles[3*ti + 0] = top_s0; |
|
triangles[3*ti + 1] = bot_s1; |
|
triangles[3*ti + 2] = top_s1; |
|
ti++; |
|
|
|
triangles[3*ti + 0] = bot_s0; |
|
triangles[3*ti + 1] = bot_s1; |
|
triangles[3*ti + 2] = top_s0; |
|
ti++; |
|
} |
It might be possible to replicate the uvmap from the Unity's capsule.
ProceduralToolkit/Scripts/MeshDraftPrimitives.cs
Lines 670 to 784 in 02e59f9