Blender V5.0
radial_tiling_shared.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024-2025 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5/* The following files are always to be kept as exact copies of each other:
6 * radial_tiling_shared.hh
7 * node_radial_tiling_shared.h
8 * radial_tiling_shared.h
9 * gpu_shader_material_radial_tiling_shared.glsl */
10
11/* The SVM implementation is used as the base shared version because multiple math function
12 * identifiers are already used as macros in the SVM code, making a code adaption into an SVM
13 * implementation using macros impossible. */
14
15/* Define macros for code adaption. */
16#ifdef ADAPT_TO_GEOMETRY_NODES
17# define atanf math::atan
18# define atan2f math::atan2
19# define ceilf math::ceil
20# define cosf math::cos
21# define fabsf math::abs
22# define floorf math::floor
23# define fmaxf math::max
24# define fminf math::min
25# define fractf math::fract
26# define mix math::interpolate
27# define sinf math::sin
28# define sqrtf math::sqrt
29# define sqr math::square
30# define tanf math::tan
31
32# define make_float2 float2
33# define make_float4 float4
34# define M_PI_F M_PI
35# define M_2PI_F M_TAU
36# define ccl_device
37#else
38# ifdef ADAPT_TO_OSL
39# define atanf atan
40# define atan2f atan2
41# define ceilf ceil
42# define cosf cos
43# define fabsf abs
44# define floorf floor
45# define fmaxf max
46# define fminf min
47# define fractf fract
48# define mix mix
49# define sinf sin
50# define sqrtf sqrt
51# define sqr sqr
52# define tanf tan
53
54# define bool int
55# define float2 vector2
56# define float4 vector4
57# define make_float2 vector2
58# define make_float4 vector4
59# define M_PI_F M_PI
60# define M_2PI_F M_2PI
61# define ccl_device
62
63# define false 0
64# define true 1
65# else
66# ifdef ADAPT_TO_SVM
67/* No code adaption necessary for the SVM implementation as it is the base shared version. */
68# else
69/* Adapt code to GLSL by default. */
70# define atanf atan
71# define atan2f atan2
72# define ceilf ceil
73# define cosf cos
74# define fabsf abs
75# define floorf floor
76# define fmaxf max
77# define fminf min
78# define fractf fract
79# define mix mix
80# define sinf sin
81# define sqrtf sqrt
82# define sqr square
83# define tanf tan
84
85# define make_float2 float2
86# define make_float4 float4
87# define M_PI_F M_PI
88# define M_2PI_F M_TAU
89# define ccl_device
90# endif
91# endif
92#endif
93
94/* The geometry nodes has optional specialized functions for certain combinations of input values.
95 * These specialized functions output the same values as the general functions, but are faster when
96 * they can be used. To reduce the complexity on the GPU kernel while also keeping all rendering
97 * implementations the same, they are only enabled in the geometry nodes implementation. */
98#ifdef ADAPT_TO_GEOMETRY_NODES
99# define ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(X) (X)
100#else
101# define ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(X) true
102#endif
103
104/* Naming convention for the Radial Tiling node code:
105 * Let x and y be 2D vectors.
106 * The length of X is expressed as l_x, which is an abbreviation of length_x.
107 * The counterclockwise unsinged angle in [0.0, M_TAU] from X to Y is expressed as x_A_y, which
108 * is an abbreviation of x_Angle_y. The singed angle in [-M_PI, M_PI] from x to y is expressed
109 * as x_SA_y, which is an abbreviation of x_SingedAngle_y. Counterclockwise angles are positive,
110 * clockwise angles are negative. A signed angle from x to y of which the output is mirrored along
111 * a certain vector is expressed as x_MSA_y, which is an abbreviation of x_MirroredSingedAngle_y.
112 *
113 * Let z and w be scalars.
114 * The ratio z/w is expressed as z_R_w, which is an abbreviation of z_Ratio_y. */
115
116#ifdef ADAPT_TO_GEOMETRY_NODES
118calculate_out_variables_full_roundness_irregular_circular(bool calculate_r_gon_parameter_field,
119 bool normalize_r_gon_parameter,
120 float r_gon_sides,
121 float2 coord,
122 float l_coord)
123{
124 float x_axis_A_coord = atan2f(coord.y, coord.x) + float(coord.y < float(0.0)) * M_2PI_F;
125 float segment_divider_A_angle_bisector = M_PI_F / r_gon_sides;
126 float segment_divider_A_next_segment_divider = float(2.0) * segment_divider_A_angle_bisector;
127 float segment_id = floorf(x_axis_A_coord / segment_divider_A_next_segment_divider);
128 float segment_divider_A_coord = x_axis_A_coord -
129 segment_id * segment_divider_A_next_segment_divider;
130
131 float last_angle_bisector_A_x_axis = M_PI_F -
132 floorf(r_gon_sides) * segment_divider_A_angle_bisector;
133 float last_segment_divider_A_x_axis = float(2.0) * last_angle_bisector_A_x_axis;
134 float l_last_circle_radius = tanf(last_angle_bisector_A_x_axis) /
135 tanf(float(0.5) * (segment_divider_A_angle_bisector +
136 last_angle_bisector_A_x_axis));
137 float2 last_circle_center = make_float2(
138 cosf(last_angle_bisector_A_x_axis) -
139 l_last_circle_radius * cosf(last_angle_bisector_A_x_axis),
140 l_last_circle_radius * sinf(last_angle_bisector_A_x_axis) -
141 sinf(last_angle_bisector_A_x_axis));
142 float2 outer_last_bevel_start = last_circle_center +
143 l_last_circle_radius *
144 make_float2(cosf(segment_divider_A_angle_bisector),
145 sinf(segment_divider_A_angle_bisector));
146 float x_axis_A_outer_last_bevel_start = atanf(outer_last_bevel_start.y /
147 outer_last_bevel_start.x);
148 float outer_last_bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
149 x_axis_A_outer_last_bevel_start;
150
151 if ((x_axis_A_coord >= x_axis_A_outer_last_bevel_start) &&
152 (x_axis_A_coord < M_2PI_F - last_segment_divider_A_x_axis - x_axis_A_outer_last_bevel_start))
153 {
154 if ((x_axis_A_coord >=
155 M_2PI_F - last_segment_divider_A_x_axis - segment_divider_A_angle_bisector) ||
156 (x_axis_A_coord < segment_divider_A_angle_bisector))
157 {
158 /* Regular straight part. */
159
160 float l_angle_bisector = float(0.0);
161 float r_gon_parameter = float(0.0);
162
163 l_angle_bisector = l_coord *
164 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
165
166 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
167 x_axis_A_outer_last_bevel_start) /
168 tanf(segment_divider_A_angle_bisector);
169 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
170 x_axis_A_outer_last_bevel_start;
171
172 if (calculate_r_gon_parameter_field) {
173 r_gon_parameter = l_angle_bisector *
174 tanf(fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord));
175 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
176 r_gon_parameter *= -float(1.0);
177 }
178 if (normalize_r_gon_parameter) {
179 float normalize_based_on_l_angle_bisector =
180 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
181 spline_start_outer_last_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
182 effective_roundness * x_axis_A_outer_last_bevel_start;
183
184 r_gon_parameter /= normalize_based_on_l_angle_bisector;
185 }
186 }
187 return make_float4(l_angle_bisector,
188 r_gon_parameter,
189 segment_divider_A_angle_bisector,
190 segment_id * segment_divider_A_next_segment_divider +
191 segment_divider_A_angle_bisector);
192 }
193 else {
194 /* Regular rounded part. */
195
196 float r_gon_parameter = float(0.0);
197 if (calculate_r_gon_parameter_field) {
198 r_gon_parameter = fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord);
199 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
200 r_gon_parameter *= -float(1.0);
201 }
202 if (normalize_r_gon_parameter) {
203 r_gon_parameter /= segment_divider_A_angle_bisector;
204 }
205 }
206 return make_float4(l_coord,
207 r_gon_parameter,
208 segment_divider_A_angle_bisector,
209 segment_id * segment_divider_A_next_segment_divider +
210 segment_divider_A_angle_bisector);
211 }
212 }
213 else {
214 /* Irregular rounded part. */
215
216 /* MSA == Mirrored Signed Angle. The values are mirrored around the last angle bisector
217 * to avoid a case distinction. */
218 float nearest_segment_divider_MSA_coord = atan2f(coord.y, coord.x);
219 if ((x_axis_A_coord >=
220 M_2PI_F - last_segment_divider_A_x_axis - x_axis_A_outer_last_bevel_start) &&
221 (x_axis_A_coord < M_2PI_F - last_angle_bisector_A_x_axis))
222 {
223 nearest_segment_divider_MSA_coord += last_segment_divider_A_x_axis;
224 nearest_segment_divider_MSA_coord *= -float(1.0);
225 }
226 float l_angle_bisector = float(0.0);
227 float r_gon_parameter = float(0.0);
228 float max_unit_parameter = float(0.0);
229 float x_axis_A_angle_bisector = float(0.0);
230
231 float l_coord_R_l_last_angle_bisector =
232 sinf(nearest_segment_divider_MSA_coord) * last_circle_center.y +
233 cosf(nearest_segment_divider_MSA_coord) * last_circle_center.x +
234 sqrtf(sqr(sinf(nearest_segment_divider_MSA_coord) * last_circle_center.y +
235 cosf(nearest_segment_divider_MSA_coord) * last_circle_center.x) +
236 sqr(l_last_circle_radius) - sqr(last_circle_center.x) - sqr(last_circle_center.y));
237 float l_angle_bisector_R_l_last_angle_bisector = cosf(segment_divider_A_angle_bisector) /
238 cosf(last_angle_bisector_A_x_axis);
239
240 l_angle_bisector = l_angle_bisector_R_l_last_angle_bisector * l_coord /
241 l_coord_R_l_last_angle_bisector;
242
243 if (nearest_segment_divider_MSA_coord < float(0.0)) {
244 /* Irregular rounded inner part. */
245
246 if (calculate_r_gon_parameter_field) {
247 r_gon_parameter = l_angle_bisector_R_l_last_angle_bisector *
248 (last_angle_bisector_A_x_axis + nearest_segment_divider_MSA_coord);
249 if (segment_divider_A_coord < last_angle_bisector_A_x_axis) {
250 r_gon_parameter *= -float(1.0);
251 }
252 if (normalize_r_gon_parameter) {
253 r_gon_parameter /= l_angle_bisector_R_l_last_angle_bisector *
254 last_angle_bisector_A_x_axis;
255 }
256 }
257 max_unit_parameter = l_angle_bisector_R_l_last_angle_bisector * last_angle_bisector_A_x_axis;
258 x_axis_A_angle_bisector = segment_id * segment_divider_A_next_segment_divider +
259 last_angle_bisector_A_x_axis;
260 }
261 else {
262 /* Irregular rounded outer part. */
263
264 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
265 x_axis_A_outer_last_bevel_start) /
266 tanf(segment_divider_A_angle_bisector);
267 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
268 x_axis_A_outer_last_bevel_start;
269
270 if (calculate_r_gon_parameter_field) {
271 float coord_A_bevel_start = x_axis_A_outer_last_bevel_start -
272 fabsf(nearest_segment_divider_MSA_coord);
273 r_gon_parameter = l_coord * sinf(outer_last_bevel_start_A_angle_bisector);
274
275 if (coord_A_bevel_start < spline_start_outer_last_bevel_start) {
276 r_gon_parameter +=
277 l_coord * cosf(outer_last_bevel_start_A_angle_bisector) * coord_A_bevel_start +
278 float(0.5) * (float(1.0) - l_coord * cosf(outer_last_bevel_start_A_angle_bisector)) *
279 sqr(coord_A_bevel_start) / spline_start_outer_last_bevel_start;
280 }
281 else {
282 r_gon_parameter += spline_start_outer_last_bevel_start *
283 (float(0.5) * l_coord *
284 cosf(outer_last_bevel_start_A_angle_bisector) -
285 float(0.5)) +
286 coord_A_bevel_start;
287 }
288 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
289 r_gon_parameter *= -float(1.0);
290 }
291 if (normalize_r_gon_parameter) {
292 float normalize_based_on_l_angle_bisector =
293 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
294 spline_start_outer_last_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
295 effective_roundness * x_axis_A_outer_last_bevel_start;
296 float normalize_based_on_l_coord =
297 l_coord * sinf(outer_last_bevel_start_A_angle_bisector) +
298 spline_start_outer_last_bevel_start *
299 (float(0.5) * l_coord * cosf(outer_last_bevel_start_A_angle_bisector) +
300 float(0.5)) +
301 effective_roundness * x_axis_A_outer_last_bevel_start;
302
303 /* For effective_roundness -> 1.0 the normalize_based_on_l_angle_bisector field and
304 * normalize_based_on_l_coord field converge against the same scalar field. */
305 r_gon_parameter /= mix(normalize_based_on_l_angle_bisector,
306 normalize_based_on_l_coord,
307 coord_A_bevel_start / x_axis_A_outer_last_bevel_start);
308 }
309 }
310 max_unit_parameter = segment_divider_A_angle_bisector;
311 x_axis_A_angle_bisector = segment_id * segment_divider_A_next_segment_divider +
312 segment_divider_A_angle_bisector;
313 }
314 return make_float4(
315 l_angle_bisector, r_gon_parameter, max_unit_parameter, x_axis_A_angle_bisector);
316 }
317}
318#endif
319
321 bool calculate_max_unit_parameter,
322 bool normalize_r_gon_parameter,
323 float r_gon_sides,
324 float r_gon_roundness,
325 float2 coord,
326 float l_coord)
327{
328#ifdef ADAPT_TO_SVM
329 /* Silence compiler warnings. */
330 (void)calculate_r_gon_parameter_field;
331 (void)calculate_max_unit_parameter;
332#endif
333
334 float x_axis_A_coord = atan2f(coord.y, coord.x) + float(coord.y < float(0.0)) * M_2PI_F;
335 float segment_divider_A_angle_bisector = M_PI_F / r_gon_sides;
336 float segment_divider_A_next_segment_divider = float(2.0) * segment_divider_A_angle_bisector;
337 float segment_id = floorf(x_axis_A_coord / segment_divider_A_next_segment_divider);
338 float segment_divider_A_coord = x_axis_A_coord -
339 segment_id * segment_divider_A_next_segment_divider;
340 float segment_divider_A_bevel_start = segment_divider_A_angle_bisector -
341 atanf((float(1.0) - r_gon_roundness) *
342 tanf(segment_divider_A_angle_bisector));
343
344 float last_angle_bisector_A_x_axis = M_PI_F -
345 floorf(r_gon_sides) * segment_divider_A_angle_bisector;
346 float last_segment_divider_A_x_axis = float(2.0) * last_angle_bisector_A_x_axis;
347 float inner_last_bevel_start_A_x_axis = last_angle_bisector_A_x_axis -
348 atanf((float(1.0) - r_gon_roundness) *
349 tanf(last_angle_bisector_A_x_axis));
350 float l_last_circle_radius = r_gon_roundness * tanf(last_angle_bisector_A_x_axis) /
351 tanf(float(0.5) * (segment_divider_A_angle_bisector +
352 last_angle_bisector_A_x_axis));
353 float2 last_circle_center = make_float2(
354 (cosf(inner_last_bevel_start_A_x_axis) /
355 cosf(last_angle_bisector_A_x_axis - inner_last_bevel_start_A_x_axis)) -
356 l_last_circle_radius * cosf(last_angle_bisector_A_x_axis),
357 l_last_circle_radius * sinf(last_angle_bisector_A_x_axis) -
358 (sinf(inner_last_bevel_start_A_x_axis) /
359 cosf(last_angle_bisector_A_x_axis - inner_last_bevel_start_A_x_axis)));
360 float2 outer_last_bevel_start = last_circle_center +
361 l_last_circle_radius *
362 make_float2(cosf(segment_divider_A_angle_bisector),
363 sinf(segment_divider_A_angle_bisector));
364 float x_axis_A_outer_last_bevel_start = atanf(outer_last_bevel_start.y /
365 outer_last_bevel_start.x);
366 float outer_last_bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
367 x_axis_A_outer_last_bevel_start;
368
369 if ((x_axis_A_coord >= x_axis_A_outer_last_bevel_start) &&
370 (x_axis_A_coord < M_2PI_F - last_segment_divider_A_x_axis - x_axis_A_outer_last_bevel_start))
371 {
372 float bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
373 segment_divider_A_bevel_start;
374
375 if (((segment_divider_A_coord >= segment_divider_A_bevel_start) &&
376 (segment_divider_A_coord <
377 segment_divider_A_next_segment_divider - segment_divider_A_bevel_start)) ||
378 (x_axis_A_coord >=
379 M_2PI_F - last_segment_divider_A_x_axis - segment_divider_A_bevel_start) ||
380 (x_axis_A_coord < segment_divider_A_bevel_start))
381 {
382 /* Regular straight part. */
383
384 float l_angle_bisector = float(0.0);
385 float r_gon_parameter = float(0.0);
386 float max_unit_parameter = float(0.0);
387
388 l_angle_bisector = l_coord *
389 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
390
391 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
392 segment_divider_A_bevel_start;
393
394 if ((x_axis_A_coord >=
395 M_2PI_F - last_segment_divider_A_x_axis - segment_divider_A_angle_bisector) ||
396 (x_axis_A_coord < segment_divider_A_angle_bisector))
397 {
398 /* Irregular rounded outer part. */
399
400 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
401 x_axis_A_outer_last_bevel_start) /
402 tanf(segment_divider_A_angle_bisector);
403 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
404 x_axis_A_outer_last_bevel_start;
405
406 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
407 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
408 segment_divider_A_coord));
409 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
410 r_gon_parameter *= -float(1.0);
411 }
412 if (normalize_r_gon_parameter) {
413 float normalize_based_on_l_angle_bisector =
414 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
415 spline_start_outer_last_bevel_start *
416 (float(0.5) * l_angle_bisector + float(0.5)) +
417 effective_roundness * x_axis_A_outer_last_bevel_start;
418
419 r_gon_parameter /= normalize_based_on_l_angle_bisector;
420 }
421 }
422 }
423 else {
424 /* Regular straight part. */
425
426 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
427 segment_divider_A_bevel_start;
428
429 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
430 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
431 segment_divider_A_coord));
432 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
433 r_gon_parameter *= -float(1.0);
434 }
435 if (normalize_r_gon_parameter) {
436 float normalize_based_on_l_angle_bisector =
437 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
438 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
439 r_gon_roundness * segment_divider_A_bevel_start;
440
441 r_gon_parameter /= normalize_based_on_l_angle_bisector;
442 }
443 }
444 }
445
446 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
447 r_gon_parameter = l_angle_bisector *
448 tanf(fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord));
449 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
450 r_gon_parameter *= -float(1.0);
451 }
452
453 if (normalize_r_gon_parameter) {
454 if ((x_axis_A_coord >=
455 M_2PI_F - last_segment_divider_A_x_axis - segment_divider_A_angle_bisector) ||
456 (x_axis_A_coord < segment_divider_A_angle_bisector))
457 {
458 /* Irregular rounded outer part. */
459
460 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
461 x_axis_A_outer_last_bevel_start) /
462 tanf(segment_divider_A_angle_bisector);
463 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
464 x_axis_A_outer_last_bevel_start;
465
466 float normalize_based_on_l_angle_bisector =
467 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
468 spline_start_outer_last_bevel_start *
469 (float(0.5) * l_angle_bisector + float(0.5)) +
470 effective_roundness * x_axis_A_outer_last_bevel_start;
471
472 r_gon_parameter /= normalize_based_on_l_angle_bisector;
473 }
474 else {
475 /* Regular straight part. */
476
477 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
478 segment_divider_A_bevel_start;
479
480 float normalize_based_on_l_angle_bisector =
481 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
482 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
483 r_gon_roundness * segment_divider_A_bevel_start;
484
485 r_gon_parameter /= normalize_based_on_l_angle_bisector;
486 }
487 }
488 }
489 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
490 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
491 r_gon_roundness * segment_divider_A_bevel_start;
492 }
493 return make_float4(l_angle_bisector,
494 r_gon_parameter,
495 max_unit_parameter,
496 segment_id * segment_divider_A_next_segment_divider +
497 segment_divider_A_angle_bisector);
498 }
499 else {
500 /* Regular rounded part. */
501
502 /* SA == Signed Angle in [-M_PI, M_PI]. Counterclockwise angles are positive, clockwise
503 * angles are negative.*/
504 float nearest_segment_divider_SA_coord = segment_divider_A_coord -
505 float(segment_divider_A_coord >
506 segment_divider_A_angle_bisector) *
507 segment_divider_A_next_segment_divider;
508 float l_angle_bisector = float(0.0);
509 float r_gon_parameter = float(0.0);
510 float max_unit_parameter = float(0.0);
511
512 float l_circle_center = (float(1.0) - r_gon_roundness) /
513 cosf(segment_divider_A_angle_bisector);
514 float l_coord_R_l_bevel_start = cosf(nearest_segment_divider_SA_coord) * l_circle_center +
515 sqrtf(sqr(cosf(nearest_segment_divider_SA_coord) *
516 l_circle_center) +
517 sqr(r_gon_roundness) - sqr(l_circle_center));
518
519 l_angle_bisector = l_coord / l_coord_R_l_bevel_start;
520
521 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
522 segment_divider_A_bevel_start;
523
524 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
525 float coord_A_bevel_start = segment_divider_A_bevel_start -
526 fabsf(nearest_segment_divider_SA_coord);
527 r_gon_parameter = l_coord * sinf(bevel_start_A_angle_bisector);
528
529 if (coord_A_bevel_start < spline_start_A_bevel_start) {
530 r_gon_parameter += l_coord * cosf(bevel_start_A_angle_bisector) * coord_A_bevel_start +
531 float(0.5) *
532 (float(1.0) - l_coord * cosf(bevel_start_A_angle_bisector)) *
533 sqr(coord_A_bevel_start) / spline_start_A_bevel_start;
534 }
535 else {
536 r_gon_parameter += spline_start_A_bevel_start *
537 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) -
538 float(0.5)) +
539 coord_A_bevel_start;
540 }
541 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
542 r_gon_parameter *= -float(1.0);
543 }
544 if (normalize_r_gon_parameter) {
545 float normalize_based_on_l_angle_bisector =
546 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
547 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
548 r_gon_roundness * segment_divider_A_bevel_start;
549 float normalize_based_on_l_coord =
550 l_coord * sinf(bevel_start_A_angle_bisector) +
551 spline_start_A_bevel_start *
552 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) + float(0.5)) +
553 r_gon_roundness * segment_divider_A_bevel_start;
554
555 /* For r_gon_roundness -> 1.0 the normalize_based_on_l_angle_bisector field and
556 * normalize_based_on_l_coord field converge against the same scalar field. */
557 r_gon_parameter /= mix(normalize_based_on_l_angle_bisector,
558 normalize_based_on_l_coord,
559 coord_A_bevel_start / segment_divider_A_bevel_start);
560 }
561 }
562 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
563 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
564 r_gon_roundness * segment_divider_A_bevel_start;
565 }
566 return make_float4(l_angle_bisector,
567 r_gon_parameter,
568 max_unit_parameter,
569 segment_id * segment_divider_A_next_segment_divider +
570 segment_divider_A_angle_bisector);
571 }
572 }
573 else {
574 float inner_last_bevel_start_A_last_angle_bisector = last_angle_bisector_A_x_axis -
575 inner_last_bevel_start_A_x_axis;
576
577 if ((x_axis_A_coord >=
578 M_2PI_F - last_segment_divider_A_x_axis + inner_last_bevel_start_A_x_axis) &&
579 (x_axis_A_coord < M_2PI_F - inner_last_bevel_start_A_x_axis))
580 {
581 /* Irregular straight part. */
582
583 float l_angle_bisector = float(0.0);
584 float r_gon_parameter = float(0.0);
585 float max_unit_parameter = float(0.0);
586
587 float l_angle_bisector_R_l_last_angle_bisector = cosf(segment_divider_A_angle_bisector) /
588 cosf(last_angle_bisector_A_x_axis);
589 float l_last_angle_bisector = l_coord *
590 cosf(last_angle_bisector_A_x_axis - segment_divider_A_coord);
591
592 l_angle_bisector = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector;
593
594 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
595 inner_last_bevel_start_A_x_axis;
596
597 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
598 r_gon_parameter = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector *
599 tanf(fabsf(last_angle_bisector_A_x_axis - segment_divider_A_coord));
600 if (segment_divider_A_coord < last_angle_bisector_A_x_axis) {
601 r_gon_parameter *= -float(1.0);
602 }
603 if (normalize_r_gon_parameter) {
604 float normalize_based_on_l_l_angle_bisector =
605 l_angle_bisector_R_l_last_angle_bisector *
606 (l_last_angle_bisector * tanf(inner_last_bevel_start_A_last_angle_bisector) +
607 spline_start_A_bevel_start * (float(0.5) * l_last_angle_bisector + float(0.5)) +
608 r_gon_roundness * inner_last_bevel_start_A_x_axis);
609
610 r_gon_parameter /= normalize_based_on_l_l_angle_bisector;
611 }
612 }
613 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
614 max_unit_parameter = tanf(inner_last_bevel_start_A_last_angle_bisector) +
615 l_angle_bisector_R_l_last_angle_bisector *
616 (spline_start_A_bevel_start *
617 ((float(0.5) / l_angle_bisector_R_l_last_angle_bisector) +
618 float(0.5)) +
619 r_gon_roundness * inner_last_bevel_start_A_x_axis);
620 }
621 return make_float4(l_angle_bisector,
622 r_gon_parameter,
623 max_unit_parameter,
624 segment_id * segment_divider_A_next_segment_divider +
625 last_angle_bisector_A_x_axis);
626 }
627 else {
628 /* Irregular rounded part. */
629
630 /* MSA == Mirrored Signed Angle. The values are mirrored around the last angle bisector
631 * to avoid a case distinction. */
632 float nearest_segment_divider_MSA_coord = atan2f(coord.y, coord.x);
633 if ((x_axis_A_coord >=
634 M_2PI_F - last_segment_divider_A_x_axis - x_axis_A_outer_last_bevel_start) &&
635 (x_axis_A_coord < M_2PI_F - last_angle_bisector_A_x_axis))
636 {
637 nearest_segment_divider_MSA_coord += last_segment_divider_A_x_axis;
638 nearest_segment_divider_MSA_coord *= -float(1.0);
639 }
640 float l_angle_bisector = float(0.0);
641 float r_gon_parameter = float(0.0);
642 float max_unit_parameter = float(0.0);
643 float x_axis_A_angle_bisector = float(0.0);
644
645 float l_coord_R_l_last_angle_bisector =
646 sinf(nearest_segment_divider_MSA_coord) * last_circle_center.y +
647 cosf(nearest_segment_divider_MSA_coord) * last_circle_center.x +
648 sqrtf(sqr(sinf(nearest_segment_divider_MSA_coord) * last_circle_center.y +
649 cosf(nearest_segment_divider_MSA_coord) * last_circle_center.x) +
650 sqr(l_last_circle_radius) - sqr(last_circle_center.x) - sqr(last_circle_center.y));
651 float l_angle_bisector_R_l_last_angle_bisector = cosf(segment_divider_A_angle_bisector) /
652 cosf(last_angle_bisector_A_x_axis);
653 float l_last_angle_bisector = l_coord / l_coord_R_l_last_angle_bisector;
654
655 l_angle_bisector = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector;
656
657 if (nearest_segment_divider_MSA_coord < float(0.0)) {
658 /* Irregular rounded inner part. */
659
660 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
661 inner_last_bevel_start_A_x_axis;
662
663 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
664 float coord_A_bevel_start = inner_last_bevel_start_A_x_axis -
665 fabsf(nearest_segment_divider_MSA_coord);
666 r_gon_parameter = l_angle_bisector_R_l_last_angle_bisector * l_coord *
667 sinf(inner_last_bevel_start_A_last_angle_bisector);
668
669 if (coord_A_bevel_start < spline_start_A_bevel_start) {
670 r_gon_parameter +=
671 l_angle_bisector_R_l_last_angle_bisector *
672 (l_coord * cosf(inner_last_bevel_start_A_last_angle_bisector) *
673 coord_A_bevel_start +
674 float(0.5) *
675 (float(1.0) - l_coord * cosf(inner_last_bevel_start_A_last_angle_bisector)) *
676 sqr(coord_A_bevel_start) / spline_start_A_bevel_start);
677 }
678 else {
679 r_gon_parameter += l_angle_bisector_R_l_last_angle_bisector *
680 (spline_start_A_bevel_start *
681 (float(0.5) * l_coord *
682 cosf(inner_last_bevel_start_A_last_angle_bisector) -
683 float(0.5)) +
684 coord_A_bevel_start);
685 }
686 if (segment_divider_A_coord < last_angle_bisector_A_x_axis) {
687 r_gon_parameter *= -float(1.0);
688 }
689 if (normalize_r_gon_parameter) {
690 float normalize_based_on_l_l_angle_bisector =
691 l_last_angle_bisector * tanf(inner_last_bevel_start_A_last_angle_bisector) +
692 spline_start_A_bevel_start * (float(0.5) * l_last_angle_bisector + float(0.5)) +
693 r_gon_roundness * inner_last_bevel_start_A_x_axis;
694 float normalize_based_on_l_coord =
695 l_coord * sinf(inner_last_bevel_start_A_last_angle_bisector) +
696 spline_start_A_bevel_start *
697 (float(0.5) * l_coord * cosf(inner_last_bevel_start_A_last_angle_bisector) +
698 float(0.5)) +
699 r_gon_roundness * inner_last_bevel_start_A_x_axis;
700
701 /* For r_gon_roundness -> 1.0 the normalize_based_on_l_l_angle_bisector field and
702 * normalize_based_on_l_coord field converge against the same scalar field. */
703 r_gon_parameter /= l_angle_bisector_R_l_last_angle_bisector *
704 mix(normalize_based_on_l_l_angle_bisector,
705 normalize_based_on_l_coord,
706 coord_A_bevel_start / inner_last_bevel_start_A_x_axis);
707 }
708 }
709 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
710 max_unit_parameter = tanf(inner_last_bevel_start_A_last_angle_bisector) +
711 l_angle_bisector_R_l_last_angle_bisector *
712 (spline_start_A_bevel_start *
713 ((float(0.5) / l_angle_bisector_R_l_last_angle_bisector) +
714 float(0.5)) +
715 r_gon_roundness * inner_last_bevel_start_A_x_axis);
716 }
717 x_axis_A_angle_bisector = segment_id * segment_divider_A_next_segment_divider +
718 last_angle_bisector_A_x_axis;
719 }
720 else {
721 /* Irregular rounded outer part. */
722
723 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
724 x_axis_A_outer_last_bevel_start) /
725 tanf(segment_divider_A_angle_bisector);
726 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
727 x_axis_A_outer_last_bevel_start;
728
729 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
730 float coord_A_bevel_start = x_axis_A_outer_last_bevel_start -
731 fabsf(nearest_segment_divider_MSA_coord);
732 r_gon_parameter = l_coord * sinf(outer_last_bevel_start_A_angle_bisector);
733
734 if (coord_A_bevel_start < spline_start_outer_last_bevel_start) {
735 r_gon_parameter += l_coord * cosf(outer_last_bevel_start_A_angle_bisector) *
736 coord_A_bevel_start +
737 float(0.5) *
738 (float(1.0) -
739 l_coord * cosf(outer_last_bevel_start_A_angle_bisector)) *
740 sqr(coord_A_bevel_start) / spline_start_outer_last_bevel_start;
741 }
742 else {
743 r_gon_parameter += spline_start_outer_last_bevel_start *
744 (float(0.5) * l_coord *
745 cosf(outer_last_bevel_start_A_angle_bisector) -
746 float(0.5)) +
747 coord_A_bevel_start;
748 }
749 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
750 r_gon_parameter *= -float(1.0);
751 }
752 if (normalize_r_gon_parameter) {
753 float normalize_based_on_l_angle_bisector =
754 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
755 spline_start_outer_last_bevel_start *
756 (float(0.5) * l_angle_bisector + float(0.5)) +
757 effective_roundness * x_axis_A_outer_last_bevel_start;
758 float normalize_based_on_l_coord =
759 l_coord * sinf(outer_last_bevel_start_A_angle_bisector) +
760 spline_start_outer_last_bevel_start *
761 (float(0.5) * l_coord * cosf(outer_last_bevel_start_A_angle_bisector) +
762 float(0.5)) +
763 effective_roundness * x_axis_A_outer_last_bevel_start;
764
765 /* For effective_roundness -> 1.0 the normalize_based_on_l_angle_bisector field and
766 * normalize_based_on_l_coord field converge against the same scalar field. */
767 r_gon_parameter /= mix(normalize_based_on_l_angle_bisector,
768 normalize_based_on_l_coord,
769 coord_A_bevel_start / x_axis_A_outer_last_bevel_start);
770 }
771 }
772 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
773 float bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
774 segment_divider_A_bevel_start;
775 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
776 segment_divider_A_bevel_start;
777
778 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
779 r_gon_roundness * segment_divider_A_bevel_start;
780 }
781 x_axis_A_angle_bisector = segment_id * segment_divider_A_next_segment_divider +
782 segment_divider_A_angle_bisector;
783 }
784 return make_float4(
785 l_angle_bisector, r_gon_parameter, max_unit_parameter, x_axis_A_angle_bisector);
786 }
787 }
788}
789
790ccl_device float4 calculate_out_variables(bool calculate_r_gon_parameter_field,
791 bool calculate_max_unit_parameter,
792 bool normalize_r_gon_parameter,
793 float r_gon_sides,
794 float r_gon_roundness,
795 float2 coord)
796{
797#ifdef ADAPT_TO_SVM
798 /* Silence compiler warnings. */
799 (void)calculate_r_gon_parameter_field;
800 (void)calculate_max_unit_parameter;
801#endif
802
803 float l_coord = sqrtf(sqr(coord.x) + sqr(coord.y));
804 float4 out_variables;
805
806 if (fractf(r_gon_sides) == float(0.0)) {
807 float x_axis_A_coord = atan2f(coord.y, coord.x) + float(coord.y < float(0.0)) * M_2PI_F;
808 float segment_divider_A_angle_bisector = M_PI_F / r_gon_sides;
809 float segment_divider_A_next_segment_divider = float(2.0) * segment_divider_A_angle_bisector;
810 float segment_id = floorf(x_axis_A_coord / segment_divider_A_next_segment_divider);
811 float segment_divider_A_coord = x_axis_A_coord -
812 segment_id * segment_divider_A_next_segment_divider;
813
814 if (r_gon_roundness == float(0.0)) {
815 /* Regular straight part. */
816
817 float l_angle_bisector = float(0.0);
818 float r_gon_parameter = float(0.0);
819 float max_unit_parameter = float(0.0);
820
821 l_angle_bisector = l_coord *
822 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
823
824 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
825 r_gon_parameter = l_angle_bisector *
826 tanf(fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord));
827 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
828 r_gon_parameter *= -float(1.0);
829 }
830 if (normalize_r_gon_parameter && (r_gon_sides != float(2.0))) {
831 r_gon_parameter /= l_angle_bisector * tanf(segment_divider_A_angle_bisector);
832 }
833 }
834 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
835 max_unit_parameter = (r_gon_sides != float(2.0)) ? tanf(segment_divider_A_angle_bisector) :
836 float(0.0);
837 }
838 out_variables = make_float4(l_angle_bisector,
839 r_gon_parameter,
840 max_unit_parameter,
841 segment_id * segment_divider_A_next_segment_divider +
842 segment_divider_A_angle_bisector);
843 }
844 else if (r_gon_roundness == float(1.0)) {
845 /* Regular rounded part. */
846
847 float r_gon_parameter = float(0.0);
848 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
849 r_gon_parameter = fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord);
850 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
851 r_gon_parameter *= -float(1.0);
852 }
853 if (normalize_r_gon_parameter) {
854 r_gon_parameter /= segment_divider_A_angle_bisector;
855 }
856 }
857 out_variables = make_float4(l_coord,
858 r_gon_parameter,
859 segment_divider_A_angle_bisector,
860 segment_id * segment_divider_A_next_segment_divider +
861 segment_divider_A_angle_bisector);
862 }
863 else {
864 float segment_divider_A_bevel_start = segment_divider_A_angle_bisector -
865 atanf((float(1.0) - r_gon_roundness) *
866 tanf(segment_divider_A_angle_bisector));
867 float bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
868 segment_divider_A_bevel_start;
869
870 if ((segment_divider_A_coord >=
871 segment_divider_A_next_segment_divider - segment_divider_A_bevel_start) ||
872 (segment_divider_A_coord < segment_divider_A_bevel_start))
873 {
874 /* Regular rounded part. */
875
876 /* SA == Signed Angle in [-M_PI, M_PI]. Counterclockwise angles are positive, clockwise
877 * angles are negative.*/
878 float nearest_segment_divider_SA_coord = segment_divider_A_coord -
879 float(segment_divider_A_coord >
880 segment_divider_A_angle_bisector) *
881 segment_divider_A_next_segment_divider;
882 float l_angle_bisector = float(0.0);
883 float r_gon_parameter = float(0.0);
884 float max_unit_parameter = float(0.0);
885
886 float l_circle_center = (float(1.0) - r_gon_roundness) /
887 cosf(segment_divider_A_angle_bisector);
888 float l_coord_R_l_bevel_start = cosf(nearest_segment_divider_SA_coord) * l_circle_center +
889 sqrtf(sqr(cosf(nearest_segment_divider_SA_coord) *
890 l_circle_center) +
891 sqr(r_gon_roundness) - sqr(l_circle_center));
892
893 l_angle_bisector = l_coord / l_coord_R_l_bevel_start;
894
895 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
896 segment_divider_A_bevel_start;
897
898 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
899 float coord_A_bevel_start = segment_divider_A_bevel_start -
900 fabsf(nearest_segment_divider_SA_coord);
901 r_gon_parameter = l_coord * sinf(bevel_start_A_angle_bisector);
902
903 if (coord_A_bevel_start < spline_start_A_bevel_start) {
904 r_gon_parameter += l_coord * cosf(bevel_start_A_angle_bisector) * coord_A_bevel_start +
905 float(0.5) *
906 (float(1.0) - l_coord * cosf(bevel_start_A_angle_bisector)) *
907 sqr(coord_A_bevel_start) / spline_start_A_bevel_start;
908 }
909 else {
910 r_gon_parameter += spline_start_A_bevel_start *
911 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) -
912 float(0.5)) +
913 coord_A_bevel_start;
914 }
915 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
916 r_gon_parameter *= -float(1.0);
917 }
918 if (normalize_r_gon_parameter) {
919 float normalize_based_on_l_angle_bisector =
920 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
921 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
922 r_gon_roundness * segment_divider_A_bevel_start;
923 float normalize_based_on_l_coord =
924 l_coord * sinf(bevel_start_A_angle_bisector) +
925 spline_start_A_bevel_start *
926 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) + float(0.5)) +
927 r_gon_roundness * segment_divider_A_bevel_start;
928
929 /* For r_gon_roundness -> 1.0 the normalize_based_on_l_angle_bisector field and
930 * normalize_based_on_l_coord field converge against the same scalar field. */
931 r_gon_parameter /= mix(normalize_based_on_l_angle_bisector,
932 normalize_based_on_l_coord,
933 coord_A_bevel_start / segment_divider_A_bevel_start);
934 }
935 }
936 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
937 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
938 r_gon_roundness * segment_divider_A_bevel_start;
939 }
940 out_variables = make_float4(l_angle_bisector,
941 r_gon_parameter,
942 max_unit_parameter,
943 segment_id * segment_divider_A_next_segment_divider +
944 segment_divider_A_angle_bisector);
945 }
946 else {
947 /* Regular straight part. */
948
949 float l_angle_bisector = float(0.0);
950 float r_gon_parameter = float(0.0);
951 float max_unit_parameter = float(0.0);
952
953 l_angle_bisector = l_coord *
954 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
955
956 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
957 segment_divider_A_bevel_start;
958
959 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
960 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
961 segment_divider_A_coord));
962 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
963 r_gon_parameter *= -float(1.0);
964 }
965 if (normalize_r_gon_parameter) {
966 float normalize_based_on_l_angle_bisector =
967 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
968 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
969 r_gon_roundness * segment_divider_A_bevel_start;
970
971 r_gon_parameter /= normalize_based_on_l_angle_bisector;
972 }
973 }
974 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
975 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
976 r_gon_roundness * segment_divider_A_bevel_start;
977 }
978 out_variables = make_float4(l_angle_bisector,
979 r_gon_parameter,
980 max_unit_parameter,
981 segment_id * segment_divider_A_next_segment_divider +
982 segment_divider_A_angle_bisector);
983 }
984 }
985 }
986 else {
987 if (r_gon_roundness == float(0.0)) {
988 float x_axis_A_coord = atan2f(coord.y, coord.x) + float(coord.y < float(0.0)) * M_2PI_F;
989 float segment_divider_A_angle_bisector = M_PI_F / r_gon_sides;
990 float segment_divider_A_next_segment_divider = float(2.0) * segment_divider_A_angle_bisector;
991 float segment_id = floorf(x_axis_A_coord / segment_divider_A_next_segment_divider);
992 float segment_divider_A_coord = x_axis_A_coord -
993 segment_id * segment_divider_A_next_segment_divider;
994
995 float last_angle_bisector_A_x_axis = M_PI_F -
996 floorf(r_gon_sides) * segment_divider_A_angle_bisector;
997 float last_segment_divider_A_x_axis = float(2.0) * last_angle_bisector_A_x_axis;
998
999 if (x_axis_A_coord < M_2PI_F - last_segment_divider_A_x_axis) {
1000 /* Regular straight part. */
1001
1002 float l_angle_bisector = float(0.0);
1003 float r_gon_parameter = float(0.0);
1004 float max_unit_parameter = float(0.0);
1005
1006 l_angle_bisector = l_coord *
1007 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
1008 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
1009 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
1010 segment_divider_A_coord));
1011 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
1012 r_gon_parameter *= -float(1.0);
1013 }
1014 if (normalize_r_gon_parameter) {
1015 r_gon_parameter /= l_angle_bisector * tanf(segment_divider_A_angle_bisector);
1016 }
1017 }
1018 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
1019 max_unit_parameter = tanf(segment_divider_A_angle_bisector);
1020 }
1021 out_variables = make_float4(l_angle_bisector,
1022 r_gon_parameter,
1023 max_unit_parameter,
1024 segment_id * segment_divider_A_next_segment_divider +
1025 segment_divider_A_angle_bisector);
1026 }
1027 else {
1028 /* Irregular straight part. */
1029
1030 float l_angle_bisector = float(0.0);
1031 float r_gon_parameter = float(0.0);
1032 float max_unit_parameter = float(0.0);
1033
1034 float l_angle_bisector_R_l_last_angle_bisector = cosf(segment_divider_A_angle_bisector) /
1035 cosf(last_angle_bisector_A_x_axis);
1036 float l_last_angle_bisector = l_coord *
1037 cosf(last_angle_bisector_A_x_axis - segment_divider_A_coord);
1038
1039 l_angle_bisector = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector;
1040
1041 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
1042 r_gon_parameter = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector *
1043 tanf(fabsf(last_angle_bisector_A_x_axis - segment_divider_A_coord));
1044 if (segment_divider_A_coord < last_angle_bisector_A_x_axis) {
1045 r_gon_parameter *= -float(1.0);
1046 }
1047 if (normalize_r_gon_parameter) {
1048 r_gon_parameter /= l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector *
1049 tanf(last_angle_bisector_A_x_axis);
1050 }
1051 }
1052 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
1053 max_unit_parameter = tanf(last_angle_bisector_A_x_axis);
1054 }
1055 out_variables = make_float4(l_angle_bisector,
1056 r_gon_parameter,
1057 max_unit_parameter,
1058 segment_id * segment_divider_A_next_segment_divider +
1059 last_angle_bisector_A_x_axis);
1060 }
1061 }
1062#ifdef ADAPT_TO_GEOMETRY_NODES
1063 else if (r_gon_roundness == float(1.0)) {
1064 out_variables = calculate_out_variables_full_roundness_irregular_circular(
1065 calculate_r_gon_parameter_field, normalize_r_gon_parameter, r_gon_sides, coord, l_coord);
1066 }
1067#endif
1068 else {
1069 out_variables = calculate_out_variables_irregular_circular(calculate_r_gon_parameter_field,
1070 calculate_max_unit_parameter,
1071 normalize_r_gon_parameter,
1072 r_gon_sides,
1073 r_gon_roundness,
1074 coord,
1075 l_coord);
1076 }
1077 }
1078
1079 if ((coord.x == float(0.0)) && (coord.y == float(0.0))) {
1080 /* The r_gon_parameter is defined to 0 when it is not normalized and the input coordinate is
1081 * the zero vector. */
1082 out_variables.y = float(0.0);
1083 }
1084
1085 if (normalize_r_gon_parameter) {
1086 /* Normalize r_gon_parameter from a [-1, 1] interval to a [0, 1] interval. */
1087 out_variables.y = float(0.5) * out_variables.y + float(0.5);
1088 }
1089 else {
1090 out_variables.x -= float(1.0);
1091 }
1092
1093 return out_variables;
1094}
1095
1096ccl_device float calculate_out_segment_id(float r_gon_sides, float2 coord)
1097{
1098 return floorf(r_gon_sides *
1099 ((atan2f(coord.y, coord.x) / M_2PI_F) + float(coord.y < float(0.0))));
1100}
1101
1102/* Undefine macros used for code adaption. */
1103#ifdef ADAPT_TO_GEOMETRY_NODES
1104# undef atanf
1105# undef atan2f
1106# undef ceilf
1107# undef cosf
1108# undef fabsf
1109# undef floorf
1110# undef fmaxf
1111# undef fminf
1112# undef fractf
1113# undef mix
1114# undef sinf
1115# undef sqrtf
1116# undef sqr
1117# undef tanf
1118
1119# undef make_float2
1120# undef make_float4
1121# undef ccl_device
1122#else
1123# ifdef ADAPT_TO_OSL
1124# undef atanf
1125# undef atan2f
1126# undef ceilf
1127# undef cosf
1128# undef fabsf
1129# undef floorf
1130# undef fmaxf
1131# undef fminf
1132# undef fractf
1133# undef mix
1134# undef sinf
1135# undef sqrtf
1136# undef sqr
1137# undef tanf
1138
1139# undef bool
1140# undef float2
1141# undef float4
1142# undef make_float2
1143# undef make_float4
1144# undef M_PI_F
1145# undef M_2PI_F
1146# undef ccl_device
1147
1148# undef false
1149# undef true
1150# else
1151# ifdef ADAPT_TO_SVM
1152/* No code adaption necessary for the SVM implementation as it is the base shared version. */
1153# else
1154/* Adapt code to GLSL by default. */
1155# undef atanf
1156# undef atan2f
1157# undef ceilf
1158# undef cosf
1159# undef fabsf
1160# undef floorf
1161# undef fmaxf
1162# undef fminf
1163# undef fractf
1164# undef mix
1165# undef sinf
1166# undef sqrtf
1167# undef sqr
1168# undef tanf
1169
1170# undef make_float2
1171# undef make_float4
1172# undef M_PI_F
1173# undef M_2PI_F
1174# undef ccl_device
1175# endif
1176# endif
1177#endif
1178
1179#undef ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION
nullptr float
#define sqr
#define ccl_device
#define M_2PI_F
#define M_PI_F
#define cosf
#define mix
#define sqr
#define ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(X)
#define floorf
#define fabsf
#define sqrtf
#define atanf
#define sinf
#define make_float2
#define tanf
#define fractf
ccl_device float4 calculate_out_variables_irregular_circular(bool calculate_r_gon_parameter_field, bool calculate_max_unit_parameter, bool normalize_r_gon_parameter, float r_gon_sides, float r_gon_roundness, float2 coord, float l_coord)
#define make_float4
#define cosf
ccl_device float4 calculate_out_variables(bool calculate_r_gon_parameter_field, bool calculate_max_unit_parameter, bool normalize_r_gon_parameter, float r_gon_sides, float r_gon_roundness, float2 coord)
#define atan2f
ccl_device float calculate_out_segment_id(float r_gon_sides, float2 coord)
float x
float y
float y
Definition sky_math.h:225
float x
Definition sky_math.h:225