13 const float radius_bottom,
17 const float radius = std::max(radius_top, radius_bottom);
20 const float x_max = radius;
21 const float x_min = std::cos(std::round(0.5f * segments) *
delta_phi) * radius;
22 const float y_max = std::sin(std::round(0.25f * segments) *
delta_phi) * radius;
23 const float y_min = -y_max;
25 const float3 bounds_min(x_min, y_min, -height);
26 const float3 bounds_max(x_max, y_max, height);
28 return {bounds_min, bounds_max};
65 const float delta_theta =
M_PI / rings;
69 for (
const int segment :
IndexRange(1, segments)) {
71 segment_cosines[segment] = std::cos(phi);
74 for (
const int segment :
IndexRange(1, segments)) {
76 segment_sines[segment] = std::sin(phi);
79 positions[0] =
float3(0.0f, 0.0f, radius);
83 for (
const int ring :
IndexRange(1, rings - 1)) {
84 const float theta = ring * delta_theta;
86 const float z = std::cos(theta);
87 for (
const int segment :
IndexRange(1, segments)) {
88 const float x =
sin_theta * segment_cosines[segment];
89 const float y =
sin_theta * segment_sines[segment];
90 positions[vert_index] =
float3(x, y,
z) * radius;
91 vert_normals[vert_index] =
float3(x, y,
z);
96 positions.last() =
float3(0.0f, 0.0f, -radius);
97 vert_normals.
last() =
float3(0.0f, 0.0f, -1.0f);
107 const int first_vert_ring_index_start = 1;
108 for (
const int segment :
IndexRange(segments)) {
109 int2 &edge = edges[edge_index++];
111 edge[1] = first_vert_ring_index_start + segment;
114 int ring_vert_index_start = 1;
115 for (
const int ring :
IndexRange(rings - 1)) {
116 const int next_ring_vert_index_start = ring_vert_index_start + segments;
119 for (
const int segment :
IndexRange(segments)) {
120 int2 &edge = edges[edge_index++];
121 edge[0] = ring_vert_index_start + segment;
122 edge[1] = ring_vert_index_start + ((segment + 1) % segments);
126 if (ring < rings - 2) {
127 for (
const int segment :
IndexRange(segments)) {
128 int2 &edge = edges[edge_index++];
129 edge[0] = ring_vert_index_start + segment;
130 edge[1] = next_ring_vert_index_start + segment;
133 ring_vert_index_start += segments;
138 const int last_vert_ring_start = last_vert_index - segments;
139 for (
const int segment :
IndexRange(segments)) {
140 int2 &edge = edges[edge_index++];
141 edge[0] = last_vert_index;
142 edge[1] = last_vert_ring_start + segment;
164 auto segment_next_or_first = [&](
const int segment) {
165 return segment == segments - 1 ? 0 : segment + 1;
169 const int first_vert_ring_start = 1;
170 for (
const int segment :
IndexRange(segments)) {
171 const int loop_start = segment * 3;
172 const int segment_next = segment_next_or_first(segment);
174 corner_verts[loop_start + 0] = 0;
175 corner_edges[loop_start + 0] = segment;
177 corner_verts[loop_start + 1] = first_vert_ring_start + segment;
178 corner_edges[loop_start + 1] = segments + segment;
180 corner_verts[loop_start + 2] = first_vert_ring_start + segment_next;
181 corner_edges[loop_start + 2] = segment_next;
184 const int rings_vert_start = 1;
185 const int rings_edge_start = segments;
186 const int rings_loop_start = segments * 3;
187 for (
const int ring :
IndexRange(1, rings - 2)) {
188 const int ring_vert_start = rings_vert_start + (ring - 1) * segments;
189 const int ring_edge_start = rings_edge_start + (ring - 1) * segments * 2;
190 const int ring_loop_start = rings_loop_start + (ring - 1) * segments * 4;
192 const int next_ring_vert_start = ring_vert_start + segments;
193 const int next_ring_edge_start = ring_edge_start + segments * 2;
194 const int ring_vertical_edge_start = ring_edge_start + segments;
196 for (
const int segment :
IndexRange(segments)) {
197 const int loop_start = ring_loop_start + segment * 4;
198 const int segment_next = segment_next_or_first(segment);
200 corner_verts[loop_start + 0] = ring_vert_start + segment;
201 corner_edges[loop_start + 0] = ring_vertical_edge_start + segment;
203 corner_verts[loop_start + 1] = next_ring_vert_start + segment;
204 corner_edges[loop_start + 1] = next_ring_edge_start + segment;
206 corner_verts[loop_start + 2] = next_ring_vert_start + segment_next;
207 corner_edges[loop_start + 2] = ring_vertical_edge_start + segment_next;
209 corner_verts[loop_start + 3] = ring_vert_start + segment_next;
210 corner_edges[loop_start + 3] = ring_edge_start + segment;
215 const int bottom_loop_start = rings_loop_start + segments * (rings - 2) * 4;
216 const int last_edge_ring_start = segments * (rings - 2) * 2 + segments;
217 const int bottom_edge_fan_start = last_edge_ring_start + segments;
219 const int last_vert_ring_start = last_vert_index - segments;
220 for (
const int segment :
IndexRange(segments)) {
221 const int loop_start = bottom_loop_start + segment * 3;
222 const int segment_next = segment_next_or_first(segment);
224 corner_verts[loop_start + 0] = last_vert_index;
225 corner_edges[loop_start + 0] = bottom_edge_fan_start + segment_next;
227 corner_verts[loop_start + 1] = last_vert_ring_start + segment_next;
228 corner_edges[loop_start + 1] = last_edge_ring_start + segment;
230 corner_verts[loop_start + 2] = last_vert_ring_start + segment;
231 corner_edges[loop_start + 2] = bottom_edge_fan_start + segment;
236 const float segments,
246 const float dy = 1.0f / rings;
248 const float segments_inv = 1.0f / segments;
250 for (
const int i_segment :
IndexRange(segments)) {
251 const int loop_start = i_segment * 3;
252 const float segment =
float(i_segment);
253 uvs[loop_start + 0] =
float2((segment + 0.5f) * segments_inv, 0.0f);
254 uvs[loop_start + 1] =
float2(segment * segments_inv, dy);
255 uvs[loop_start + 2] =
float2((segment + 1.0f) * segments_inv, dy);
258 const int rings_loop_start = segments * 3;
259 for (
const int i_ring :
IndexRange(1, rings - 2)) {
260 const int ring_loop_start = rings_loop_start + (i_ring - 1) * segments * 4;
261 const float ring =
float(i_ring);
262 for (
const int i_segment :
IndexRange(segments)) {
263 const int loop_start = ring_loop_start + i_segment * 4;
264 const float segment =
float(i_segment);
265 uvs[loop_start + 0] =
float2(segment * segments_inv, ring / rings);
266 uvs[loop_start + 1] =
float2(segment * segments_inv, (ring + 1.0f) / rings);
267 uvs[loop_start + 2] =
float2((segment + 1.0f) * segments_inv, (ring + 1.0f) / rings);
268 uvs[loop_start + 3] =
float2((segment + 1.0f) * segments_inv, ring / rings);
272 const int bottom_loop_start = rings_loop_start + segments * (rings - 2) * 4;
273 for (
const int i_segment :
IndexRange(segments)) {
274 const int loop_start = bottom_loop_start + i_segment * 3;
275 const float segment =
float(i_segment);
276 uvs[loop_start + 0] =
float2((segment + 0.5f) * segments_inv, 1.0f);
277 uvs[loop_start + 1] =
float2((segment + 1.0f) * segments_inv, 1.0f - dy);
278 uvs[loop_start + 2] =
float2(segment * segments_inv, 1.0f - dy);
297 const std::optional<StringRef> &uv_map_id)
311 1024 < segments * rings,
326 mesh->tag_loose_verts_none();
327 mesh->tag_loose_edges_none();
328 mesh->tag_overlapping_none();