17 const float radius_bottom,
21 const float radius = std::max(radius_top, radius_bottom);
24 const float x_max = radius;
25 const float x_min = std::cos(std::round(0.5f * segments) *
delta_phi) * radius;
26 const float y_max = std::sin(std::round(0.25f * segments) *
delta_phi) * radius;
27 const float y_min = -y_max;
29 const float3 bounds_min(x_min, y_min, -height);
30 const float3 bounds_max(x_max, y_max, height);
32 return {bounds_min, bounds_max};
73 for (
const int segment :
IndexRange(1, segments)) {
75 segment_cosines[segment] = std::cos(phi);
78 for (
const int segment :
IndexRange(1, segments)) {
80 segment_sines[segment] = std::sin(phi);
83 positions[0] =
float3(0.0f, 0.0f, radius);
87 for (
const int ring :
IndexRange(1, rings - 1)) {
88 const float theta = ring * delta_theta;
90 const float z = std::cos(theta);
91 for (
const int segment :
IndexRange(1, segments)) {
92 const float x =
sin_theta * segment_cosines[segment];
93 const float y =
sin_theta * segment_sines[segment];
94 positions[vert_index] =
float3(
x,
y,
z) * radius;
95 vert_normals[vert_index] =
float3(
x,
y,
z);
100 positions.
last() =
float3(0.0f, 0.0f, -radius);
101 vert_normals.
last() =
float3(0.0f, 0.0f, -1.0f);
111 const int first_vert_ring_index_start = 1;
112 for (
const int segment :
IndexRange(segments)) {
113 int2 &edge = edges[edge_index++];
115 edge[1] = first_vert_ring_index_start + segment;
118 int ring_vert_index_start = 1;
119 for (
const int ring :
IndexRange(rings - 1)) {
120 const int next_ring_vert_index_start = ring_vert_index_start + segments;
123 for (
const int segment :
IndexRange(segments)) {
124 int2 &edge = edges[edge_index++];
125 edge[0] = ring_vert_index_start + segment;
126 edge[1] = ring_vert_index_start + ((segment + 1) % segments);
130 if (ring < rings - 2) {
131 for (
const int segment :
IndexRange(segments)) {
132 int2 &edge = edges[edge_index++];
133 edge[0] = ring_vert_index_start + segment;
134 edge[1] = next_ring_vert_index_start + segment;
137 ring_vert_index_start += segments;
142 const int last_vert_ring_start = last_vert_index - segments;
143 for (
const int segment :
IndexRange(segments)) {
144 int2 &edge = edges[edge_index++];
145 edge[0] = last_vert_index;
146 edge[1] = last_vert_ring_start + segment;
168 auto segment_next_or_first = [&](
const int segment) {
169 return segment == segments - 1 ? 0 : segment + 1;
173 const int first_vert_ring_start = 1;
174 for (
const int segment :
IndexRange(segments)) {
175 const int loop_start = segment * 3;
176 const int segment_next = segment_next_or_first(segment);
178 corner_verts[loop_start + 0] = 0;
179 corner_edges[loop_start + 0] = segment;
181 corner_verts[loop_start + 1] = first_vert_ring_start + segment;
182 corner_edges[loop_start + 1] = segments + segment;
184 corner_verts[loop_start + 2] = first_vert_ring_start + segment_next;
185 corner_edges[loop_start + 2] = segment_next;
188 const int rings_vert_start = 1;
189 const int rings_edge_start = segments;
190 const int rings_loop_start = segments * 3;
191 for (
const int ring :
IndexRange(1, rings - 2)) {
192 const int ring_vert_start = rings_vert_start + (ring - 1) * segments;
193 const int ring_edge_start = rings_edge_start + (ring - 1) * segments * 2;
194 const int ring_loop_start = rings_loop_start + (ring - 1) * segments * 4;
196 const int next_ring_vert_start = ring_vert_start + segments;
197 const int next_ring_edge_start = ring_edge_start + segments * 2;
198 const int ring_vertical_edge_start = ring_edge_start + segments;
200 for (
const int segment :
IndexRange(segments)) {
201 const int loop_start = ring_loop_start + segment * 4;
202 const int segment_next = segment_next_or_first(segment);
204 corner_verts[loop_start + 0] = ring_vert_start + segment;
205 corner_edges[loop_start + 0] = ring_vertical_edge_start + segment;
207 corner_verts[loop_start + 1] = next_ring_vert_start + segment;
208 corner_edges[loop_start + 1] = next_ring_edge_start + segment;
210 corner_verts[loop_start + 2] = next_ring_vert_start + segment_next;
211 corner_edges[loop_start + 2] = ring_vertical_edge_start + segment_next;
213 corner_verts[loop_start + 3] = ring_vert_start + segment_next;
214 corner_edges[loop_start + 3] = ring_edge_start + segment;
219 const int bottom_loop_start = rings_loop_start + segments * (rings - 2) * 4;
220 const int last_edge_ring_start = segments * (rings - 2) * 2 + segments;
221 const int bottom_edge_fan_start = last_edge_ring_start + segments;
223 const int last_vert_ring_start = last_vert_index - segments;
224 for (
const int segment :
IndexRange(segments)) {
225 const int loop_start = bottom_loop_start + segment * 3;
226 const int segment_next = segment_next_or_first(segment);
228 corner_verts[loop_start + 0] = last_vert_index;
229 corner_edges[loop_start + 0] = bottom_edge_fan_start + segment_next;
231 corner_verts[loop_start + 1] = last_vert_ring_start + segment_next;
232 corner_edges[loop_start + 1] = last_edge_ring_start + segment;
234 corner_verts[loop_start + 2] = last_vert_ring_start + segment;
235 corner_edges[loop_start + 2] = bottom_edge_fan_start + segment;
240 const float segments,
250 const float dy = 1.0f / rings;
252 const float segments_inv = 1.0f / segments;
254 for (
const int i_segment :
IndexRange(segments)) {
255 const int loop_start = i_segment * 3;
256 const float segment =
float(i_segment);
257 uvs[loop_start + 0] =
float2((segment + 0.5f) * segments_inv, 0.0f);
258 uvs[loop_start + 1] =
float2(segment * segments_inv, dy);
259 uvs[loop_start + 2] =
float2((segment + 1.0f) * segments_inv, dy);
262 const int rings_loop_start = segments * 3;
263 for (
const int i_ring :
IndexRange(1, rings - 2)) {
264 const int ring_loop_start = rings_loop_start + (i_ring - 1) * segments * 4;
265 const float ring =
float(i_ring);
266 for (
const int i_segment :
IndexRange(segments)) {
267 const int loop_start = ring_loop_start + i_segment * 4;
268 const float segment =
float(i_segment);
269 uvs[loop_start + 0] =
float2(segment * segments_inv, ring / rings);
270 uvs[loop_start + 1] =
float2(segment * segments_inv, (ring + 1.0f) / rings);
271 uvs[loop_start + 2] =
float2((segment + 1.0f) * segments_inv, (ring + 1.0f) / rings);
272 uvs[loop_start + 3] =
float2((segment + 1.0f) * segments_inv, ring / rings);
276 const int bottom_loop_start = rings_loop_start + segments * (rings - 2) * 4;
277 for (
const int i_segment :
IndexRange(segments)) {
278 const int loop_start = bottom_loop_start + i_segment * 3;
279 const float segment =
float(i_segment);
280 uvs[loop_start + 0] =
float2((segment + 0.5f) * segments_inv, 1.0f);
281 uvs[loop_start + 1] =
float2((segment + 1.0f) * segments_inv, 1.0f - dy);
282 uvs[loop_start + 2] =
float2(segment * segments_inv, 1.0f - dy);
301 const std::optional<StringRef> uv_map_id)
315 1024 < segments * rings,
330 mesh->tag_loose_verts_none();
331 mesh->tag_loose_edges_none();
332 mesh->tag_overlapping_none();