Blender V5.0
radial_tiling_shared.hh
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
117static ccl_device float4
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
320static ccl_device float4
321calculate_out_variables_irregular_circular(bool calculate_r_gon_parameter_field,
322 bool calculate_max_unit_parameter,
323 bool normalize_r_gon_parameter,
324 float r_gon_sides,
325 float r_gon_roundness,
326 float2 coord,
327 float l_coord)
328{
329#ifdef ADAPT_TO_SVM
330 /* Silence compiler warnings. */
331 (void)calculate_r_gon_parameter_field;
332 (void)calculate_max_unit_parameter;
333#endif
334
335 float x_axis_A_coord = atan2f(coord.y, coord.x) + float(coord.y < float(0.0)) * M_2PI_F;
336 float segment_divider_A_angle_bisector = M_PI_F / r_gon_sides;
337 float segment_divider_A_next_segment_divider = float(2.0) * segment_divider_A_angle_bisector;
338 float segment_id = floorf(x_axis_A_coord / segment_divider_A_next_segment_divider);
339 float segment_divider_A_coord = x_axis_A_coord -
340 segment_id * segment_divider_A_next_segment_divider;
341 float segment_divider_A_bevel_start = segment_divider_A_angle_bisector -
342 atanf((float(1.0) - r_gon_roundness) *
343 tanf(segment_divider_A_angle_bisector));
344
345 float last_angle_bisector_A_x_axis = M_PI_F -
346 floorf(r_gon_sides) * segment_divider_A_angle_bisector;
347 float last_segment_divider_A_x_axis = float(2.0) * last_angle_bisector_A_x_axis;
348 float inner_last_bevel_start_A_x_axis = last_angle_bisector_A_x_axis -
349 atanf((float(1.0) - r_gon_roundness) *
350 tanf(last_angle_bisector_A_x_axis));
351 float l_last_circle_radius = r_gon_roundness * tanf(last_angle_bisector_A_x_axis) /
352 tanf(float(0.5) * (segment_divider_A_angle_bisector +
353 last_angle_bisector_A_x_axis));
354 float2 last_circle_center = make_float2(
355 (cosf(inner_last_bevel_start_A_x_axis) /
356 cosf(last_angle_bisector_A_x_axis - inner_last_bevel_start_A_x_axis)) -
357 l_last_circle_radius * cosf(last_angle_bisector_A_x_axis),
358 l_last_circle_radius * sinf(last_angle_bisector_A_x_axis) -
359 (sinf(inner_last_bevel_start_A_x_axis) /
360 cosf(last_angle_bisector_A_x_axis - inner_last_bevel_start_A_x_axis)));
361 float2 outer_last_bevel_start = last_circle_center +
362 l_last_circle_radius *
363 make_float2(cosf(segment_divider_A_angle_bisector),
364 sinf(segment_divider_A_angle_bisector));
365 float x_axis_A_outer_last_bevel_start = atanf(outer_last_bevel_start.y /
366 outer_last_bevel_start.x);
367 float outer_last_bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
368 x_axis_A_outer_last_bevel_start;
369
370 if ((x_axis_A_coord >= x_axis_A_outer_last_bevel_start) &&
371 (x_axis_A_coord < M_2PI_F - last_segment_divider_A_x_axis - x_axis_A_outer_last_bevel_start))
372 {
373 float bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
374 segment_divider_A_bevel_start;
375
376 if (((segment_divider_A_coord >= segment_divider_A_bevel_start) &&
377 (segment_divider_A_coord <
378 segment_divider_A_next_segment_divider - segment_divider_A_bevel_start)) ||
379 (x_axis_A_coord >=
380 M_2PI_F - last_segment_divider_A_x_axis - segment_divider_A_bevel_start) ||
381 (x_axis_A_coord < segment_divider_A_bevel_start))
382 {
383 /* Regular straight part. */
384
385 float l_angle_bisector = float(0.0);
386 float r_gon_parameter = float(0.0);
387 float max_unit_parameter = float(0.0);
388
389 l_angle_bisector = l_coord *
390 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
391
392 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
393 segment_divider_A_bevel_start;
394
395 if ((x_axis_A_coord >=
396 M_2PI_F - last_segment_divider_A_x_axis - segment_divider_A_angle_bisector) ||
397 (x_axis_A_coord < segment_divider_A_angle_bisector))
398 {
399 /* Irregular rounded outer part. */
400
401 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
402 x_axis_A_outer_last_bevel_start) /
403 tanf(segment_divider_A_angle_bisector);
404 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
405 x_axis_A_outer_last_bevel_start;
406
407 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
408 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
409 segment_divider_A_coord));
410 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
411 r_gon_parameter *= -float(1.0);
412 }
413 if (normalize_r_gon_parameter) {
414 float normalize_based_on_l_angle_bisector =
415 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
416 spline_start_outer_last_bevel_start *
417 (float(0.5) * l_angle_bisector + float(0.5)) +
418 effective_roundness * x_axis_A_outer_last_bevel_start;
419
420 r_gon_parameter /= normalize_based_on_l_angle_bisector;
421 }
422 }
423 }
424 else {
425 /* Regular straight part. */
426
427 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
428 segment_divider_A_bevel_start;
429
430 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
431 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
432 segment_divider_A_coord));
433 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
434 r_gon_parameter *= -float(1.0);
435 }
436 if (normalize_r_gon_parameter) {
437 float normalize_based_on_l_angle_bisector =
438 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
439 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
440 r_gon_roundness * segment_divider_A_bevel_start;
441
442 r_gon_parameter /= normalize_based_on_l_angle_bisector;
443 }
444 }
445 }
446
447 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
448 r_gon_parameter = l_angle_bisector *
449 tanf(fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord));
450 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
451 r_gon_parameter *= -float(1.0);
452 }
453
454 if (normalize_r_gon_parameter) {
455 if ((x_axis_A_coord >=
456 M_2PI_F - last_segment_divider_A_x_axis - segment_divider_A_angle_bisector) ||
457 (x_axis_A_coord < segment_divider_A_angle_bisector))
458 {
459 /* Irregular rounded outer part. */
460
461 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
462 x_axis_A_outer_last_bevel_start) /
463 tanf(segment_divider_A_angle_bisector);
464 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
465 x_axis_A_outer_last_bevel_start;
466
467 float normalize_based_on_l_angle_bisector =
468 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
469 spline_start_outer_last_bevel_start *
470 (float(0.5) * l_angle_bisector + float(0.5)) +
471 effective_roundness * x_axis_A_outer_last_bevel_start;
472
473 r_gon_parameter /= normalize_based_on_l_angle_bisector;
474 }
475 else {
476 /* Regular straight part. */
477
478 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
479 segment_divider_A_bevel_start;
480
481 float normalize_based_on_l_angle_bisector =
482 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
483 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
484 r_gon_roundness * segment_divider_A_bevel_start;
485
486 r_gon_parameter /= normalize_based_on_l_angle_bisector;
487 }
488 }
489 }
490 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
491 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
492 r_gon_roundness * segment_divider_A_bevel_start;
493 }
494 return make_float4(l_angle_bisector,
495 r_gon_parameter,
496 max_unit_parameter,
497 segment_id * segment_divider_A_next_segment_divider +
498 segment_divider_A_angle_bisector);
499 }
500 else {
501 /* Regular rounded part. */
502
503 /* SA == Signed Angle in [-M_PI, M_PI]. Counterclockwise angles are positive, clockwise
504 * angles are negative.*/
505 float nearest_segment_divider_SA_coord = segment_divider_A_coord -
506 float(segment_divider_A_coord >
507 segment_divider_A_angle_bisector) *
508 segment_divider_A_next_segment_divider;
509 float l_angle_bisector = float(0.0);
510 float r_gon_parameter = float(0.0);
511 float max_unit_parameter = float(0.0);
512
513 float l_circle_center = (float(1.0) - r_gon_roundness) /
514 cosf(segment_divider_A_angle_bisector);
515 float l_coord_R_l_bevel_start = cosf(nearest_segment_divider_SA_coord) * l_circle_center +
516 sqrtf(sqr(cosf(nearest_segment_divider_SA_coord) *
517 l_circle_center) +
518 sqr(r_gon_roundness) - sqr(l_circle_center));
519
520 l_angle_bisector = l_coord / l_coord_R_l_bevel_start;
521
522 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
523 segment_divider_A_bevel_start;
524
525 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
526 float coord_A_bevel_start = segment_divider_A_bevel_start -
527 fabsf(nearest_segment_divider_SA_coord);
528 r_gon_parameter = l_coord * sinf(bevel_start_A_angle_bisector);
529
530 if (coord_A_bevel_start < spline_start_A_bevel_start) {
531 r_gon_parameter += l_coord * cosf(bevel_start_A_angle_bisector) * coord_A_bevel_start +
532 float(0.5) *
533 (float(1.0) - l_coord * cosf(bevel_start_A_angle_bisector)) *
534 sqr(coord_A_bevel_start) / spline_start_A_bevel_start;
535 }
536 else {
537 r_gon_parameter += spline_start_A_bevel_start *
538 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) -
539 float(0.5)) +
540 coord_A_bevel_start;
541 }
542 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
543 r_gon_parameter *= -float(1.0);
544 }
545 if (normalize_r_gon_parameter) {
546 float normalize_based_on_l_angle_bisector =
547 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
548 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
549 r_gon_roundness * segment_divider_A_bevel_start;
550 float normalize_based_on_l_coord =
551 l_coord * sinf(bevel_start_A_angle_bisector) +
552 spline_start_A_bevel_start *
553 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) + float(0.5)) +
554 r_gon_roundness * segment_divider_A_bevel_start;
555
556 /* For r_gon_roundness -> 1.0 the normalize_based_on_l_angle_bisector field and
557 * normalize_based_on_l_coord field converge against the same scalar field. */
558 r_gon_parameter /= mix(normalize_based_on_l_angle_bisector,
559 normalize_based_on_l_coord,
560 coord_A_bevel_start / segment_divider_A_bevel_start);
561 }
562 }
563 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
564 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
565 r_gon_roundness * segment_divider_A_bevel_start;
566 }
567 return make_float4(l_angle_bisector,
568 r_gon_parameter,
569 max_unit_parameter,
570 segment_id * segment_divider_A_next_segment_divider +
571 segment_divider_A_angle_bisector);
572 }
573 }
574 else {
575 float inner_last_bevel_start_A_last_angle_bisector = last_angle_bisector_A_x_axis -
576 inner_last_bevel_start_A_x_axis;
577
578 if ((x_axis_A_coord >=
579 M_2PI_F - last_segment_divider_A_x_axis + inner_last_bevel_start_A_x_axis) &&
580 (x_axis_A_coord < M_2PI_F - inner_last_bevel_start_A_x_axis))
581 {
582 /* Irregular straight part. */
583
584 float l_angle_bisector = float(0.0);
585 float r_gon_parameter = float(0.0);
586 float max_unit_parameter = float(0.0);
587
588 float l_angle_bisector_R_l_last_angle_bisector = cosf(segment_divider_A_angle_bisector) /
589 cosf(last_angle_bisector_A_x_axis);
590 float l_last_angle_bisector = l_coord *
591 cosf(last_angle_bisector_A_x_axis - segment_divider_A_coord);
592
593 l_angle_bisector = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector;
594
595 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
596 inner_last_bevel_start_A_x_axis;
597
598 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
599 r_gon_parameter = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector *
600 tanf(fabsf(last_angle_bisector_A_x_axis - segment_divider_A_coord));
601 if (segment_divider_A_coord < last_angle_bisector_A_x_axis) {
602 r_gon_parameter *= -float(1.0);
603 }
604 if (normalize_r_gon_parameter) {
605 float normalize_based_on_l_l_angle_bisector =
606 l_angle_bisector_R_l_last_angle_bisector *
607 (l_last_angle_bisector * tanf(inner_last_bevel_start_A_last_angle_bisector) +
608 spline_start_A_bevel_start * (float(0.5) * l_last_angle_bisector + float(0.5)) +
609 r_gon_roundness * inner_last_bevel_start_A_x_axis);
610
611 r_gon_parameter /= normalize_based_on_l_l_angle_bisector;
612 }
613 }
614 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
615 max_unit_parameter = tanf(inner_last_bevel_start_A_last_angle_bisector) +
616 l_angle_bisector_R_l_last_angle_bisector *
617 (spline_start_A_bevel_start *
618 ((float(0.5) / l_angle_bisector_R_l_last_angle_bisector) +
619 float(0.5)) +
620 r_gon_roundness * inner_last_bevel_start_A_x_axis);
621 }
622 return make_float4(l_angle_bisector,
623 r_gon_parameter,
624 max_unit_parameter,
625 segment_id * segment_divider_A_next_segment_divider +
626 last_angle_bisector_A_x_axis);
627 }
628 else {
629 /* Irregular rounded part. */
630
631 /* MSA == Mirrored Signed Angle. The values are mirrored around the last angle bisector
632 * to avoid a case distinction. */
633 float nearest_segment_divider_MSA_coord = atan2f(coord.y, coord.x);
634 if ((x_axis_A_coord >=
635 M_2PI_F - last_segment_divider_A_x_axis - x_axis_A_outer_last_bevel_start) &&
636 (x_axis_A_coord < M_2PI_F - last_angle_bisector_A_x_axis))
637 {
638 nearest_segment_divider_MSA_coord += last_segment_divider_A_x_axis;
639 nearest_segment_divider_MSA_coord *= -float(1.0);
640 }
641 float l_angle_bisector = float(0.0);
642 float r_gon_parameter = float(0.0);
643 float max_unit_parameter = float(0.0);
644 float x_axis_A_angle_bisector = float(0.0);
645
646 float l_coord_R_l_last_angle_bisector =
647 sinf(nearest_segment_divider_MSA_coord) * last_circle_center.y +
648 cosf(nearest_segment_divider_MSA_coord) * last_circle_center.x +
649 sqrtf(sqr(sinf(nearest_segment_divider_MSA_coord) * last_circle_center.y +
650 cosf(nearest_segment_divider_MSA_coord) * last_circle_center.x) +
651 sqr(l_last_circle_radius) - sqr(last_circle_center.x) - sqr(last_circle_center.y));
652 float l_angle_bisector_R_l_last_angle_bisector = cosf(segment_divider_A_angle_bisector) /
653 cosf(last_angle_bisector_A_x_axis);
654 float l_last_angle_bisector = l_coord / l_coord_R_l_last_angle_bisector;
655
656 l_angle_bisector = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector;
657
658 if (nearest_segment_divider_MSA_coord < float(0.0)) {
659 /* Irregular rounded inner part. */
660
661 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
662 inner_last_bevel_start_A_x_axis;
663
664 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
665 float coord_A_bevel_start = inner_last_bevel_start_A_x_axis -
666 fabsf(nearest_segment_divider_MSA_coord);
667 r_gon_parameter = l_angle_bisector_R_l_last_angle_bisector * l_coord *
668 sinf(inner_last_bevel_start_A_last_angle_bisector);
669
670 if (coord_A_bevel_start < spline_start_A_bevel_start) {
671 r_gon_parameter +=
672 l_angle_bisector_R_l_last_angle_bisector *
673 (l_coord * cosf(inner_last_bevel_start_A_last_angle_bisector) *
674 coord_A_bevel_start +
675 float(0.5) *
676 (float(1.0) - l_coord * cosf(inner_last_bevel_start_A_last_angle_bisector)) *
677 sqr(coord_A_bevel_start) / spline_start_A_bevel_start);
678 }
679 else {
680 r_gon_parameter += l_angle_bisector_R_l_last_angle_bisector *
681 (spline_start_A_bevel_start *
682 (float(0.5) * l_coord *
683 cosf(inner_last_bevel_start_A_last_angle_bisector) -
684 float(0.5)) +
685 coord_A_bevel_start);
686 }
687 if (segment_divider_A_coord < last_angle_bisector_A_x_axis) {
688 r_gon_parameter *= -float(1.0);
689 }
690 if (normalize_r_gon_parameter) {
691 float normalize_based_on_l_l_angle_bisector =
692 l_last_angle_bisector * tanf(inner_last_bevel_start_A_last_angle_bisector) +
693 spline_start_A_bevel_start * (float(0.5) * l_last_angle_bisector + float(0.5)) +
694 r_gon_roundness * inner_last_bevel_start_A_x_axis;
695 float normalize_based_on_l_coord =
696 l_coord * sinf(inner_last_bevel_start_A_last_angle_bisector) +
697 spline_start_A_bevel_start *
698 (float(0.5) * l_coord * cosf(inner_last_bevel_start_A_last_angle_bisector) +
699 float(0.5)) +
700 r_gon_roundness * inner_last_bevel_start_A_x_axis;
701
702 /* For r_gon_roundness -> 1.0 the normalize_based_on_l_l_angle_bisector field and
703 * normalize_based_on_l_coord field converge against the same scalar field. */
704 r_gon_parameter /= l_angle_bisector_R_l_last_angle_bisector *
705 mix(normalize_based_on_l_l_angle_bisector,
706 normalize_based_on_l_coord,
707 coord_A_bevel_start / inner_last_bevel_start_A_x_axis);
708 }
709 }
710 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
711 max_unit_parameter = tanf(inner_last_bevel_start_A_last_angle_bisector) +
712 l_angle_bisector_R_l_last_angle_bisector *
713 (spline_start_A_bevel_start *
714 ((float(0.5) / l_angle_bisector_R_l_last_angle_bisector) +
715 float(0.5)) +
716 r_gon_roundness * inner_last_bevel_start_A_x_axis);
717 }
718 x_axis_A_angle_bisector = segment_id * segment_divider_A_next_segment_divider +
719 last_angle_bisector_A_x_axis;
720 }
721 else {
722 /* Irregular rounded outer part. */
723
724 float effective_roundness = float(1.0) - tanf(segment_divider_A_angle_bisector -
725 x_axis_A_outer_last_bevel_start) /
726 tanf(segment_divider_A_angle_bisector);
727 float spline_start_outer_last_bevel_start = (float(1.0) - effective_roundness) *
728 x_axis_A_outer_last_bevel_start;
729
730 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
731 float coord_A_bevel_start = x_axis_A_outer_last_bevel_start -
732 fabsf(nearest_segment_divider_MSA_coord);
733 r_gon_parameter = l_coord * sinf(outer_last_bevel_start_A_angle_bisector);
734
735 if (coord_A_bevel_start < spline_start_outer_last_bevel_start) {
736 r_gon_parameter += l_coord * cosf(outer_last_bevel_start_A_angle_bisector) *
737 coord_A_bevel_start +
738 float(0.5) *
739 (float(1.0) -
740 l_coord * cosf(outer_last_bevel_start_A_angle_bisector)) *
741 sqr(coord_A_bevel_start) / spline_start_outer_last_bevel_start;
742 }
743 else {
744 r_gon_parameter += spline_start_outer_last_bevel_start *
745 (float(0.5) * l_coord *
746 cosf(outer_last_bevel_start_A_angle_bisector) -
747 float(0.5)) +
748 coord_A_bevel_start;
749 }
750 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
751 r_gon_parameter *= -float(1.0);
752 }
753 if (normalize_r_gon_parameter) {
754 float normalize_based_on_l_angle_bisector =
755 l_angle_bisector * tanf(outer_last_bevel_start_A_angle_bisector) +
756 spline_start_outer_last_bevel_start *
757 (float(0.5) * l_angle_bisector + float(0.5)) +
758 effective_roundness * x_axis_A_outer_last_bevel_start;
759 float normalize_based_on_l_coord =
760 l_coord * sinf(outer_last_bevel_start_A_angle_bisector) +
761 spline_start_outer_last_bevel_start *
762 (float(0.5) * l_coord * cosf(outer_last_bevel_start_A_angle_bisector) +
763 float(0.5)) +
764 effective_roundness * x_axis_A_outer_last_bevel_start;
765
766 /* For effective_roundness -> 1.0 the normalize_based_on_l_angle_bisector field and
767 * normalize_based_on_l_coord field converge against the same scalar field. */
768 r_gon_parameter /= mix(normalize_based_on_l_angle_bisector,
769 normalize_based_on_l_coord,
770 coord_A_bevel_start / x_axis_A_outer_last_bevel_start);
771 }
772 }
773 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
774 float bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
775 segment_divider_A_bevel_start;
776 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
777 segment_divider_A_bevel_start;
778
779 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
780 r_gon_roundness * segment_divider_A_bevel_start;
781 }
782 x_axis_A_angle_bisector = segment_id * segment_divider_A_next_segment_divider +
783 segment_divider_A_angle_bisector;
784 }
785 return make_float4(
786 l_angle_bisector, r_gon_parameter, max_unit_parameter, x_axis_A_angle_bisector);
787 }
788 }
789}
790
791ccl_device float4 calculate_out_variables(bool calculate_r_gon_parameter_field,
792 bool calculate_max_unit_parameter,
793 bool normalize_r_gon_parameter,
794 float r_gon_sides,
795 float r_gon_roundness,
796 float2 coord)
797{
798#ifdef ADAPT_TO_SVM
799 /* Silence compiler warnings. */
800 (void)calculate_r_gon_parameter_field;
801 (void)calculate_max_unit_parameter;
802#endif
803
804 float l_coord = sqrtf(sqr(coord.x) + sqr(coord.y));
805 float4 out_variables;
806
807 if (fractf(r_gon_sides) == float(0.0)) {
808 float x_axis_A_coord = atan2f(coord.y, coord.x) + float(coord.y < float(0.0)) * M_2PI_F;
809 float segment_divider_A_angle_bisector = M_PI_F / r_gon_sides;
810 float segment_divider_A_next_segment_divider = float(2.0) * segment_divider_A_angle_bisector;
811 float segment_id = floorf(x_axis_A_coord / segment_divider_A_next_segment_divider);
812 float segment_divider_A_coord = x_axis_A_coord -
813 segment_id * segment_divider_A_next_segment_divider;
814
815 if (r_gon_roundness == float(0.0)) {
816 /* Regular straight part. */
817
818 float l_angle_bisector = float(0.0);
819 float r_gon_parameter = float(0.0);
820 float max_unit_parameter = float(0.0);
821
822 l_angle_bisector = l_coord *
823 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
824
825 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
826 r_gon_parameter = l_angle_bisector *
827 tanf(fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord));
828 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
829 r_gon_parameter *= -float(1.0);
830 }
831 if (normalize_r_gon_parameter && (r_gon_sides != float(2.0))) {
832 r_gon_parameter /= l_angle_bisector * tanf(segment_divider_A_angle_bisector);
833 }
834 }
835 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
836 max_unit_parameter = (r_gon_sides != float(2.0)) ? tanf(segment_divider_A_angle_bisector) :
837 float(0.0);
838 }
839 out_variables = make_float4(l_angle_bisector,
840 r_gon_parameter,
841 max_unit_parameter,
842 segment_id * segment_divider_A_next_segment_divider +
843 segment_divider_A_angle_bisector);
844 }
845 else if (r_gon_roundness == float(1.0)) {
846 /* Regular rounded part. */
847
848 float r_gon_parameter = float(0.0);
849 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
850 r_gon_parameter = fabsf(segment_divider_A_angle_bisector - segment_divider_A_coord);
851 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
852 r_gon_parameter *= -float(1.0);
853 }
854 if (normalize_r_gon_parameter) {
855 r_gon_parameter /= segment_divider_A_angle_bisector;
856 }
857 }
858 out_variables = make_float4(l_coord,
859 r_gon_parameter,
860 segment_divider_A_angle_bisector,
861 segment_id * segment_divider_A_next_segment_divider +
862 segment_divider_A_angle_bisector);
863 }
864 else {
865 float segment_divider_A_bevel_start = segment_divider_A_angle_bisector -
866 atanf((float(1.0) - r_gon_roundness) *
867 tanf(segment_divider_A_angle_bisector));
868 float bevel_start_A_angle_bisector = segment_divider_A_angle_bisector -
869 segment_divider_A_bevel_start;
870
871 if ((segment_divider_A_coord >=
872 segment_divider_A_next_segment_divider - segment_divider_A_bevel_start) ||
873 (segment_divider_A_coord < segment_divider_A_bevel_start))
874 {
875 /* Regular rounded part. */
876
877 /* SA == Signed Angle in [-M_PI, M_PI]. Counterclockwise angles are positive, clockwise
878 * angles are negative.*/
879 float nearest_segment_divider_SA_coord = segment_divider_A_coord -
880 float(segment_divider_A_coord >
881 segment_divider_A_angle_bisector) *
882 segment_divider_A_next_segment_divider;
883 float l_angle_bisector = float(0.0);
884 float r_gon_parameter = float(0.0);
885 float max_unit_parameter = float(0.0);
886
887 float l_circle_center = (float(1.0) - r_gon_roundness) /
888 cosf(segment_divider_A_angle_bisector);
889 float l_coord_R_l_bevel_start = cosf(nearest_segment_divider_SA_coord) * l_circle_center +
890 sqrtf(sqr(cosf(nearest_segment_divider_SA_coord) *
891 l_circle_center) +
892 sqr(r_gon_roundness) - sqr(l_circle_center));
893
894 l_angle_bisector = l_coord / l_coord_R_l_bevel_start;
895
896 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
897 segment_divider_A_bevel_start;
898
899 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
900 float coord_A_bevel_start = segment_divider_A_bevel_start -
901 fabsf(nearest_segment_divider_SA_coord);
902 r_gon_parameter = l_coord * sinf(bevel_start_A_angle_bisector);
903
904 if (coord_A_bevel_start < spline_start_A_bevel_start) {
905 r_gon_parameter += l_coord * cosf(bevel_start_A_angle_bisector) * coord_A_bevel_start +
906 float(0.5) *
907 (float(1.0) - l_coord * cosf(bevel_start_A_angle_bisector)) *
908 sqr(coord_A_bevel_start) / spline_start_A_bevel_start;
909 }
910 else {
911 r_gon_parameter += spline_start_A_bevel_start *
912 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) -
913 float(0.5)) +
914 coord_A_bevel_start;
915 }
916 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
917 r_gon_parameter *= -float(1.0);
918 }
919 if (normalize_r_gon_parameter) {
920 float normalize_based_on_l_angle_bisector =
921 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
922 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
923 r_gon_roundness * segment_divider_A_bevel_start;
924 float normalize_based_on_l_coord =
925 l_coord * sinf(bevel_start_A_angle_bisector) +
926 spline_start_A_bevel_start *
927 (float(0.5) * l_coord * cosf(bevel_start_A_angle_bisector) + float(0.5)) +
928 r_gon_roundness * segment_divider_A_bevel_start;
929
930 /* For r_gon_roundness -> 1.0 the normalize_based_on_l_angle_bisector field and
931 * normalize_based_on_l_coord field converge against the same scalar field. */
932 r_gon_parameter /= mix(normalize_based_on_l_angle_bisector,
933 normalize_based_on_l_coord,
934 coord_A_bevel_start / segment_divider_A_bevel_start);
935 }
936 }
937 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
938 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
939 r_gon_roundness * segment_divider_A_bevel_start;
940 }
941 out_variables = make_float4(l_angle_bisector,
942 r_gon_parameter,
943 max_unit_parameter,
944 segment_id * segment_divider_A_next_segment_divider +
945 segment_divider_A_angle_bisector);
946 }
947 else {
948 /* Regular straight part. */
949
950 float l_angle_bisector = float(0.0);
951 float r_gon_parameter = float(0.0);
952 float max_unit_parameter = float(0.0);
953
954 l_angle_bisector = l_coord *
955 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
956
957 float spline_start_A_bevel_start = (float(1.0) - r_gon_roundness) *
958 segment_divider_A_bevel_start;
959
960 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
961 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
962 segment_divider_A_coord));
963 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
964 r_gon_parameter *= -float(1.0);
965 }
966 if (normalize_r_gon_parameter) {
967 float normalize_based_on_l_angle_bisector =
968 l_angle_bisector * tanf(bevel_start_A_angle_bisector) +
969 spline_start_A_bevel_start * (float(0.5) * l_angle_bisector + float(0.5)) +
970 r_gon_roundness * segment_divider_A_bevel_start;
971
972 r_gon_parameter /= normalize_based_on_l_angle_bisector;
973 }
974 }
975 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
976 max_unit_parameter = tanf(bevel_start_A_angle_bisector) + spline_start_A_bevel_start +
977 r_gon_roundness * segment_divider_A_bevel_start;
978 }
979 out_variables = make_float4(l_angle_bisector,
980 r_gon_parameter,
981 max_unit_parameter,
982 segment_id * segment_divider_A_next_segment_divider +
983 segment_divider_A_angle_bisector);
984 }
985 }
986 }
987 else {
988 if (r_gon_roundness == float(0.0)) {
989 float x_axis_A_coord = atan2f(coord.y, coord.x) + float(coord.y < float(0.0)) * M_2PI_F;
990 float segment_divider_A_angle_bisector = M_PI_F / r_gon_sides;
991 float segment_divider_A_next_segment_divider = float(2.0) * segment_divider_A_angle_bisector;
992 float segment_id = floorf(x_axis_A_coord / segment_divider_A_next_segment_divider);
993 float segment_divider_A_coord = x_axis_A_coord -
994 segment_id * segment_divider_A_next_segment_divider;
995
996 float last_angle_bisector_A_x_axis = M_PI_F -
997 floorf(r_gon_sides) * segment_divider_A_angle_bisector;
998 float last_segment_divider_A_x_axis = float(2.0) * last_angle_bisector_A_x_axis;
999
1000 if (x_axis_A_coord < M_2PI_F - last_segment_divider_A_x_axis) {
1001 /* Regular straight part. */
1002
1003 float l_angle_bisector = float(0.0);
1004 float r_gon_parameter = float(0.0);
1005 float max_unit_parameter = float(0.0);
1006
1007 l_angle_bisector = l_coord *
1008 cosf(segment_divider_A_angle_bisector - segment_divider_A_coord);
1009 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
1010 r_gon_parameter = l_angle_bisector * tanf(fabsf(segment_divider_A_angle_bisector -
1011 segment_divider_A_coord));
1012 if (segment_divider_A_coord < segment_divider_A_angle_bisector) {
1013 r_gon_parameter *= -float(1.0);
1014 }
1015 if (normalize_r_gon_parameter) {
1016 r_gon_parameter /= l_angle_bisector * tanf(segment_divider_A_angle_bisector);
1017 }
1018 }
1019 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
1020 max_unit_parameter = tanf(segment_divider_A_angle_bisector);
1021 }
1022 out_variables = make_float4(l_angle_bisector,
1023 r_gon_parameter,
1024 max_unit_parameter,
1025 segment_id * segment_divider_A_next_segment_divider +
1026 segment_divider_A_angle_bisector);
1027 }
1028 else {
1029 /* Irregular straight part. */
1030
1031 float l_angle_bisector = float(0.0);
1032 float r_gon_parameter = float(0.0);
1033 float max_unit_parameter = float(0.0);
1034
1035 float l_angle_bisector_R_l_last_angle_bisector = cosf(segment_divider_A_angle_bisector) /
1036 cosf(last_angle_bisector_A_x_axis);
1037 float l_last_angle_bisector = l_coord *
1038 cosf(last_angle_bisector_A_x_axis - segment_divider_A_coord);
1039
1040 l_angle_bisector = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector;
1041
1042 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_r_gon_parameter_field)) {
1043 r_gon_parameter = l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector *
1044 tanf(fabsf(last_angle_bisector_A_x_axis - segment_divider_A_coord));
1045 if (segment_divider_A_coord < last_angle_bisector_A_x_axis) {
1046 r_gon_parameter *= -float(1.0);
1047 }
1048 if (normalize_r_gon_parameter) {
1049 r_gon_parameter /= l_angle_bisector_R_l_last_angle_bisector * l_last_angle_bisector *
1050 tanf(last_angle_bisector_A_x_axis);
1051 }
1052 }
1053 if (ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(calculate_max_unit_parameter)) {
1054 max_unit_parameter = tanf(last_angle_bisector_A_x_axis);
1055 }
1056 out_variables = make_float4(l_angle_bisector,
1057 r_gon_parameter,
1058 max_unit_parameter,
1059 segment_id * segment_divider_A_next_segment_divider +
1060 last_angle_bisector_A_x_axis);
1061 }
1062 }
1063#ifdef ADAPT_TO_GEOMETRY_NODES
1064 else if (r_gon_roundness == float(1.0)) {
1065 out_variables = calculate_out_variables_full_roundness_irregular_circular(
1066 calculate_r_gon_parameter_field, normalize_r_gon_parameter, r_gon_sides, coord, l_coord);
1067 }
1068#endif
1069 else {
1070 out_variables = calculate_out_variables_irregular_circular(calculate_r_gon_parameter_field,
1071 calculate_max_unit_parameter,
1072 normalize_r_gon_parameter,
1073 r_gon_sides,
1074 r_gon_roundness,
1075 coord,
1076 l_coord);
1077 }
1078 }
1079
1080 if ((coord.x == float(0.0)) && (coord.y == float(0.0))) {
1081 /* The r_gon_parameter is defined to 0 when it is not normalized and the input coordinate is
1082 * the zero vector. */
1083 out_variables.y = float(0.0);
1084 }
1085
1086 if (normalize_r_gon_parameter) {
1087 /* Normalize r_gon_parameter from a [-1, 1] interval to a [0, 1] interval. */
1088 out_variables.y = float(0.5) * out_variables.y + float(0.5);
1089 }
1090 else {
1091 out_variables.x -= float(1.0);
1092 }
1093
1094 return out_variables;
1095}
1096
1097ccl_device float calculate_out_segment_id(float r_gon_sides, float2 coord)
1098{
1099 return floorf(r_gon_sides *
1100 ((atan2f(coord.y, coord.x) / M_2PI_F) + float(coord.y < float(0.0))));
1101}
1102
1103/* Undefine macros used for code adaption. */
1104#ifdef ADAPT_TO_GEOMETRY_NODES
1105# undef atanf
1106# undef atan2f
1107# undef ceilf
1108# undef cosf
1109# undef fabsf
1110# undef floorf
1111# undef fmaxf
1112# undef fminf
1113# undef fractf
1114# undef mix
1115# undef sinf
1116# undef sqrtf
1117# undef sqr
1118# undef tanf
1119
1120# undef make_float2
1121# undef make_float4
1122# undef ccl_device
1123#else
1124# ifdef ADAPT_TO_OSL
1125# undef atanf
1126# undef atan2f
1127# undef ceilf
1128# undef cosf
1129# undef fabsf
1130# undef floorf
1131# undef fmaxf
1132# undef fminf
1133# undef fractf
1134# undef mix
1135# undef sinf
1136# undef sqrtf
1137# undef sqr
1138# undef tanf
1139
1140# undef bool
1141# undef float2
1142# undef float4
1143# undef make_float2
1144# undef make_float4
1145# undef M_PI_F
1146# undef M_2PI_F
1147# undef ccl_device
1148
1149# undef false
1150# undef true
1151# else
1152# ifdef ADAPT_TO_SVM
1153/* No code adaption necessary for the SVM implementation as it is the base shared version. */
1154# else
1155/* Adapt code to GLSL by default. */
1156# undef atanf
1157# undef atan2f
1158# undef ceilf
1159# undef cosf
1160# undef fabsf
1161# undef floorf
1162# undef fmaxf
1163# undef fminf
1164# undef fractf
1165# undef mix
1166# undef sinf
1167# undef sqrtf
1168# undef sqr
1169# undef tanf
1170
1171# undef make_float2
1172# undef make_float4
1173# undef M_PI_F
1174# undef M_2PI_F
1175# undef ccl_device
1176# endif
1177# endif
1178#endif
1179
1180#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
static 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 ONLY_CHECK_IN_GEOMETRY_NODES_IMPLEMENTATION(X)
#define floorf
#define fabsf
#define sqrtf
#define atanf
#define sinf
#define make_float2
#define tanf
#define fractf
#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