Blender  V2.93
geom_curve_intersect.h
Go to the documentation of this file.
1 /*
2  * Copyright 2009-2020 Intel Corporation. Adapted from Embree with
3  * with modifications.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
19 
20 /* Curve primitive intersection functions.
21  *
22  * The code here was adapted from curve_intersector_sweep.h in Embree, to get
23  * an exact match between Embree CPU ray-tracing and our GPU ray-tracing. */
24 
25 #define CURVE_NUM_BEZIER_SUBDIVISIONS 3
26 #define CURVE_NUM_BEZIER_SUBDIVISIONS_UNSTABLE (CURVE_NUM_BEZIER_SUBDIVISIONS + 1)
27 #define CURVE_NUM_BEZIER_STEPS 2
28 #define CURVE_NUM_JACOBIAN_ITERATIONS 5
29 
30 #ifdef __HAIR__
31 
32 /* Catmull-rom curve evaluation. */
33 
34 ccl_device_inline float4 catmull_rom_basis_eval(const float4 curve[4], float u)
35 {
36  const float t = u;
37  const float s = 1.0f - u;
38  const float n0 = -t * s * s;
39  const float n1 = 2.0f + t * t * (3.0f * t - 5.0f);
40  const float n2 = 2.0f + s * s * (3.0f * s - 5.0f);
41  const float n3 = -s * t * t;
42  return 0.5f * (curve[0] * n0 + curve[1] * n1 + curve[2] * n2 + curve[3] * n3);
43 }
44 
45 ccl_device_inline float4 catmull_rom_basis_derivative(const float4 curve[4], float u)
46 {
47  const float t = u;
48  const float s = 1.0f - u;
49  const float n0 = -s * s + 2.0f * s * t;
50  const float n1 = 2.0f * t * (3.0f * t - 5.0f) + 3.0f * t * t;
51  const float n2 = 2.0f * s * (3.0f * t + 2.0f) - 3.0f * s * s;
52  const float n3 = -2.0f * s * t + t * t;
53  return 0.5f * (curve[0] * n0 + curve[1] * n1 + curve[2] * n2 + curve[3] * n3);
54 }
55 
56 ccl_device_inline float4 catmull_rom_basis_derivative2(const float4 curve[4], float u)
57 {
58 
59  const float t = u;
60  const float n0 = -3.0f * t + 2.0f;
61  const float n1 = 9.0f * t - 5.0f;
62  const float n2 = -9.0f * t + 4.0f;
63  const float n3 = 3.0f * t - 1.0f;
64  return (curve[0] * n0 + curve[1] * n1 + curve[2] * n2 + curve[3] * n3);
65 }
66 
67 /* Thick Curve */
68 
69 ccl_device_inline float3 dnormalize(const float3 p, const float3 dp)
70 {
71  const float pp = dot(p, p);
72  const float pdp = dot(p, dp);
73  return (pp * dp - pdp * p) / (pp * sqrtf(pp));
74 }
75 
76 ccl_device_inline float sqr_point_to_line_distance(const float3 PmQ0, const float3 Q1mQ0)
77 {
78  const float3 N = cross(PmQ0, Q1mQ0);
79  const float3 D = Q1mQ0;
80  return dot(N, N) / dot(D, D);
81 }
82 
83 ccl_device_inline bool cylinder_intersect(const float3 cylinder_start,
84  const float3 cylinder_end,
85  const float cylinder_radius,
86  const float3 ray_dir,
87  float2 *t_o,
88  float *u0_o,
89  float3 *Ng0_o,
90  float *u1_o,
91  float3 *Ng1_o)
92 {
93  /* Calculate quadratic equation to solve. */
94  const float rl = 1.0f / len(cylinder_end - cylinder_start);
95  const float3 P0 = cylinder_start, dP = (cylinder_end - cylinder_start) * rl;
96  const float3 O = -P0, dO = ray_dir;
97 
98  const float dOdO = dot(dO, dO);
99  const float OdO = dot(dO, O);
100  const float OO = dot(O, O);
101  const float dOz = dot(dP, dO);
102  const float Oz = dot(dP, O);
103 
104  const float A = dOdO - sqr(dOz);
105  const float B = 2.0f * (OdO - dOz * Oz);
106  const float C = OO - sqr(Oz) - sqr(cylinder_radius);
107 
108  /* We miss the cylinder if determinant is smaller than zero. */
109  const float D = B * B - 4.0f * A * C;
110  if (!(D >= 0.0f)) {
111  *t_o = make_float2(FLT_MAX, -FLT_MAX);
112  return false;
113  }
114 
115  /* Special case for rays that are parallel to the cylinder. */
116  const float eps = 16.0f * FLT_EPSILON * max(fabsf(dOdO), fabsf(sqr(dOz)));
117  if (fabsf(A) < eps) {
118  if (C <= 0.0f) {
119  *t_o = make_float2(-FLT_MAX, FLT_MAX);
120  return true;
121  }
122  else {
123  *t_o = make_float2(-FLT_MAX, FLT_MAX);
124  return false;
125  }
126  }
127 
128  /* Standard case for rays that are not parallel to the cylinder. */
129  const float Q = sqrtf(D);
130  const float rcp_2A = 1.0f / (2.0f * A);
131  const float t0 = (-B - Q) * rcp_2A;
132  const float t1 = (-B + Q) * rcp_2A;
133 
134  /* Calculates u and Ng for near hit. */
135  {
136  *u0_o = (t0 * dOz + Oz) * rl;
137  const float3 Pr = t0 * ray_dir;
138  const float3 Pl = (*u0_o) * (cylinder_end - cylinder_start) + cylinder_start;
139  *Ng0_o = Pr - Pl;
140  }
141 
142  /* Calculates u and Ng for far hit. */
143  {
144  *u1_o = (t1 * dOz + Oz) * rl;
145  const float3 Pr = t1 * ray_dir;
146  const float3 Pl = (*u1_o) * (cylinder_end - cylinder_start) + cylinder_start;
147  *Ng1_o = Pr - Pl;
148  }
149 
150  *t_o = make_float2(t0, t1);
151 
152  return true;
153 }
154 
155 ccl_device_inline float2 half_plane_intersect(const float3 P, const float3 N, const float3 ray_dir)
156 {
157  const float3 O = -P;
158  const float3 D = ray_dir;
159  const float ON = dot(O, N);
160  const float DN = dot(D, N);
161  const float min_rcp_input = 1e-18f;
162  const bool eps = fabsf(DN) < min_rcp_input;
163  const float t = -ON / DN;
164  const float lower = (eps || DN < 0.0f) ? -FLT_MAX : t;
165  const float upper = (eps || DN > 0.0f) ? FLT_MAX : t;
166  return make_float2(lower, upper);
167 }
168 
169 ccl_device bool curve_intersect_iterative(const float3 ray_dir,
170  const float dt,
171  const float4 curve[4],
172  float u,
173  float t,
174  const bool use_backfacing,
175  Intersection *isect)
176 {
177  const float length_ray_dir = len(ray_dir);
178 
179  /* Error of curve evaluations is proportional to largest coordinate. */
180  const float4 box_min = min(min(curve[0], curve[1]), min(curve[2], curve[3]));
181  const float4 box_max = max(min(curve[0], curve[1]), max(curve[2], curve[3]));
182  const float4 box_abs = max(fabs(box_min), fabs(box_max));
183  const float P_err = 16.0f * FLT_EPSILON *
184  max(box_abs.x, max(box_abs.y, max(box_abs.z, box_abs.w)));
185  const float radius_max = box_max.w;
186 
187  for (int i = 0; i < CURVE_NUM_JACOBIAN_ITERATIONS; i++) {
188  const float3 Q = ray_dir * t;
189  const float3 dQdt = ray_dir;
190  const float Q_err = 16.0f * FLT_EPSILON * length_ray_dir * t;
191 
192  const float4 P4 = catmull_rom_basis_eval(curve, u);
193  const float4 dPdu4 = catmull_rom_basis_derivative(curve, u);
194 
195  const float3 P = float4_to_float3(P4);
196  const float3 dPdu = float4_to_float3(dPdu4);
197  const float radius = P4.w;
198  const float dradiusdu = dPdu4.w;
199 
200  const float3 ddPdu = float4_to_float3(catmull_rom_basis_derivative2(curve, u));
201 
202  const float3 R = Q - P;
203  const float len_R = len(R);
204  const float R_err = max(Q_err, P_err);
205  const float3 dRdu = -dPdu;
206  const float3 dRdt = dQdt;
207 
208  const float3 T = normalize(dPdu);
209  const float3 dTdu = dnormalize(dPdu, ddPdu);
210  const float cos_err = P_err / len(dPdu);
211 
212  const float f = dot(R, T);
213  const float f_err = len_R * P_err + R_err + cos_err * (1.0f + len_R);
214  const float dfdu = dot(dRdu, T) + dot(R, dTdu);
215  const float dfdt = dot(dRdt, T);
216 
217  const float K = dot(R, R) - sqr(f);
218  const float dKdu = (dot(R, dRdu) - f * dfdu);
219  const float dKdt = (dot(R, dRdt) - f * dfdt);
220  const float rsqrt_K = inversesqrtf(K);
221 
222  const float g = sqrtf(K) - radius;
223  const float g_err = R_err + f_err + 16.0f * FLT_EPSILON * radius_max;
224  const float dgdu = dKdu * rsqrt_K - dradiusdu;
225  const float dgdt = dKdt * rsqrt_K;
226 
227  const float invdet = 1.0f / (dfdu * dgdt - dgdu * dfdt);
228  u -= (dgdt * f - dfdt * g) * invdet;
229  t -= (-dgdu * f + dfdu * g) * invdet;
230 
231  if (fabsf(f) < f_err && fabsf(g) < g_err) {
232  t += dt;
233  if (!(0.0f <= t && t <= isect->t)) {
234  return false; /* Rejects NaNs */
235  }
236  if (!(u >= 0.0f && u <= 1.0f)) {
237  return false; /* Rejects NaNs */
238  }
239 
240  /* Backface culling. */
241  const float3 R = normalize(Q - P);
242  const float3 U = dradiusdu * R + dPdu;
243  const float3 V = cross(dPdu, R);
244  const float3 Ng = cross(V, U);
245  if (!use_backfacing && dot(ray_dir, Ng) > 0.0f) {
246  return false;
247  }
248 
249  /* Record intersection. */
250  isect->t = t;
251  isect->u = u;
252  isect->v = 0.0f;
253 
254  return true;
255  }
256  }
257  return false;
258 }
259 
260 ccl_device bool curve_intersect_recursive(const float3 ray_orig,
261  const float3 ray_dir,
262  float4 curve[4],
263  Intersection *isect)
264 {
265  /* Move ray closer to make intersection stable. */
266  const float3 center = float4_to_float3(0.25f * (curve[0] + curve[1] + curve[2] + curve[3]));
267  const float dt = dot(center - ray_orig, ray_dir) / dot(ray_dir, ray_dir);
268  const float3 ref = ray_orig + ray_dir * dt;
269  const float4 ref4 = make_float4(ref.x, ref.y, ref.z, 0.0f);
270  curve[0] -= ref4;
271  curve[1] -= ref4;
272  curve[2] -= ref4;
273  curve[3] -= ref4;
274 
275  const bool use_backfacing = false;
276  const float step_size = 1.0f / (float)(CURVE_NUM_BEZIER_STEPS);
277 
278  int depth = 0;
279 
280  /* todo: optimize stack for GPU somehow? Possibly some bitflags are enough, and
281  * u0/u1 can be derived from the depth. */
282  struct {
283  float u0, u1;
284  int i;
286 
287  bool found = false;
288 
289  float u0 = 0.0f;
290  float u1 = 1.0f;
291  int i = 0;
292 
293  while (1) {
294  for (; i < CURVE_NUM_BEZIER_STEPS; i++) {
295  const float step = i * step_size;
296 
297  /* Subdivide curve. */
298  const float dscale = (u1 - u0) * (1.0f / 3.0f) * step_size;
299  const float vu0 = mix(u0, u1, step);
300  const float vu1 = mix(u0, u1, step + step_size);
301 
302  const float4 P0 = catmull_rom_basis_eval(curve, vu0);
303  const float4 dP0du = dscale * catmull_rom_basis_derivative(curve, vu0);
304  const float4 P3 = catmull_rom_basis_eval(curve, vu1);
305  const float4 dP3du = dscale * catmull_rom_basis_derivative(curve, vu1);
306 
307  const float4 P1 = P0 + dP0du;
308  const float4 P2 = P3 - dP3du;
309 
310  /* Calculate bounding cylinders. */
311  const float rr1 = sqr_point_to_line_distance(float4_to_float3(dP0du),
312  float4_to_float3(P3 - P0));
313  const float rr2 = sqr_point_to_line_distance(float4_to_float3(dP3du),
314  float4_to_float3(P3 - P0));
315  const float maxr12 = sqrtf(max(rr1, rr2));
316  const float one_plus_ulp = 1.0f + 2.0f * FLT_EPSILON;
317  const float one_minus_ulp = 1.0f - 2.0f * FLT_EPSILON;
318  float r_outer = max(max(P0.w, P1.w), max(P2.w, P3.w)) + maxr12;
319  float r_inner = min(min(P0.w, P1.w), min(P2.w, P3.w)) - maxr12;
320  r_outer = one_plus_ulp * r_outer;
321  r_inner = max(0.0f, one_minus_ulp * r_inner);
322  bool valid = true;
323 
324  /* Intersect with outer cylinder. */
325  float2 tc_outer;
326  float u_outer0, u_outer1;
327  float3 Ng_outer0, Ng_outer1;
328  valid = cylinder_intersect(float4_to_float3(P0),
329  float4_to_float3(P3),
330  r_outer,
331  ray_dir,
332  &tc_outer,
333  &u_outer0,
334  &Ng_outer0,
335  &u_outer1,
336  &Ng_outer1);
337  if (!valid) {
338  continue;
339  }
340 
341  /* Intersect with cap-planes. */
342  float2 tp = make_float2(-dt, isect->t - dt);
343  tp = make_float2(max(tp.x, tc_outer.x), min(tp.y, tc_outer.y));
344  const float2 h0 = half_plane_intersect(
345  float4_to_float3(P0), float4_to_float3(dP0du), ray_dir);
346  tp = make_float2(max(tp.x, h0.x), min(tp.y, h0.y));
347  const float2 h1 = half_plane_intersect(
348  float4_to_float3(P3), -float4_to_float3(dP3du), ray_dir);
349  tp = make_float2(max(tp.x, h1.x), min(tp.y, h1.y));
350  valid = tp.x <= tp.y;
351  if (!valid) {
352  continue;
353  }
354 
355  /* Clamp and correct u parameter. */
356  u_outer0 = clamp(u_outer0, 0.0f, 1.0f);
357  u_outer1 = clamp(u_outer1, 0.0f, 1.0f);
358  u_outer0 = mix(u0, u1, (step + u_outer0) * (1.0f / (float)(CURVE_NUM_BEZIER_STEPS + 1)));
359  u_outer1 = mix(u0, u1, (step + u_outer1) * (1.0f / (float)(CURVE_NUM_BEZIER_STEPS + 1)));
360 
361  /* Intersect with inner cylinder. */
362  float2 tc_inner;
363  float u_inner0, u_inner1;
364  float3 Ng_inner0, Ng_inner1;
365  const bool valid_inner = cylinder_intersect(float4_to_float3(P0),
366  float4_to_float3(P3),
367  r_inner,
368  ray_dir,
369  &tc_inner,
370  &u_inner0,
371  &Ng_inner0,
372  &u_inner1,
373  &Ng_inner1);
374 
375  /* At the unstable area we subdivide deeper. */
376 # if 0
377  const bool unstable0 = (!valid_inner) |
378  (fabsf(dot(normalize(ray_dir), normalize(Ng_inner0))) < 0.3f);
379  const bool unstable1 = (!valid_inner) |
380  (fabsf(dot(normalize(ray_dir), normalize(Ng_inner1))) < 0.3f);
381 # else
382  /* On the GPU appears to be a little faster if always enabled. */
383  (void)valid_inner;
384 
385  const bool unstable0 = true;
386  const bool unstable1 = true;
387 # endif
388 
389  /* Subtract the inner interval from the current hit interval. */
390  float2 tp0 = make_float2(tp.x, min(tp.y, tc_inner.x));
391  float2 tp1 = make_float2(max(tp.x, tc_inner.y), tp.y);
392  bool valid0 = valid && (tp0.x <= tp0.y);
393  bool valid1 = valid && (tp1.x <= tp1.y);
394  if (!(valid0 || valid1)) {
395  continue;
396  }
397 
398  /* Process one or two hits. */
399  bool recurse = false;
400  if (valid0) {
401  const int termDepth = unstable0 ? CURVE_NUM_BEZIER_SUBDIVISIONS_UNSTABLE :
403  if (depth >= termDepth) {
404  found |= curve_intersect_iterative(
405  ray_dir, dt, curve, u_outer0, tp0.x, use_backfacing, isect);
406  }
407  else {
408  recurse = true;
409  }
410  }
411 
412  if (valid1 && (tp1.x + dt <= isect->t)) {
413  const int termDepth = unstable1 ? CURVE_NUM_BEZIER_SUBDIVISIONS_UNSTABLE :
415  if (depth >= termDepth) {
416  found |= curve_intersect_iterative(
417  ray_dir, dt, curve, u_outer1, tp1.y, use_backfacing, isect);
418  }
419  else {
420  recurse = true;
421  }
422  }
423 
424  if (recurse) {
425  stack[depth].u0 = u0;
426  stack[depth].u1 = u1;
427  stack[depth].i = i + 1;
428  depth++;
429 
430  u0 = vu0;
431  u1 = vu1;
432  i = -1;
433  }
434  }
435 
436  if (depth > 0) {
437  depth--;
438  u0 = stack[depth].u0;
439  u1 = stack[depth].u1;
440  i = stack[depth].i;
441  }
442  else {
443  break;
444  }
445  }
446 
447  return found;
448 }
449 
450 /* Ribbons */
451 
452 ccl_device_inline bool cylinder_culling_test(const float2 p1, const float2 p2, const float r)
453 {
454  /* Performs culling against a cylinder. */
455  const float2 dp = p2 - p1;
456  const float num = dp.x * p1.y - dp.y * p1.x;
457  const float den2 = dot(dp, dp);
458  return num * num <= r * r * den2;
459 }
460 
465 ccl_device_inline bool ribbon_intersect_quad(const float ray_tfar,
466  const float3 quad_v0,
467  const float3 quad_v1,
468  const float3 quad_v2,
469  const float3 quad_v3,
470  float *u_o,
471  float *v_o,
472  float *t_o)
473 {
474  /* Calculate vertices relative to ray origin? */
475  const float3 O = make_float3(0.0f, 0.0f, 0.0f);
476  const float3 D = make_float3(0.0f, 0.0f, 1.0f);
477  const float3 va = quad_v0 - O;
478  const float3 vb = quad_v1 - O;
479  const float3 vc = quad_v2 - O;
480  const float3 vd = quad_v3 - O;
481 
482  const float3 edb = vb - vd;
483  const float WW = dot(cross(vd, edb), D);
484  const float3 v0 = (WW <= 0.0f) ? va : vc;
485  const float3 v1 = (WW <= 0.0f) ? vb : vd;
486  const float3 v2 = (WW <= 0.0f) ? vd : vb;
487 
488  /* Calculate edges? */
489  const float3 e0 = v2 - v0;
490  const float3 e1 = v0 - v1;
491 
492  /* perform edge tests */
493  const float U = dot(cross(v0, e0), D);
494  const float V = dot(cross(v1, e1), D);
495  if (!(max(U, V) <= 0.0f)) {
496  return false;
497  }
498 
499  /* Calculate geometry normal and denominator? */
500  const float3 Ng = cross(e1, e0);
501  const float den = dot(Ng, D);
502  const float rcpDen = 1.0f / den;
503 
504  /* Perform depth test? */
505  const float t = rcpDen * dot(v0, Ng);
506  if (!(0.0f <= t && t <= ray_tfar)) {
507  return false;
508  }
509 
510  /* Avoid division by 0? */
511  if (!(den != 0.0f)) {
512  return false;
513  }
514 
515  /* Update hit information? */
516  *t_o = t;
517  *u_o = U * rcpDen;
518  *v_o = V * rcpDen;
519  *u_o = (WW <= 0.0f) ? *u_o : 1.0f - *u_o;
520  *v_o = (WW <= 0.0f) ? *v_o : 1.0f - *v_o;
521  return true;
522 }
523 
524 ccl_device_inline void ribbon_ray_space(const float3 ray_dir, float3 ray_space[3])
525 {
526  const float3 dx0 = make_float3(0, ray_dir.z, -ray_dir.y);
527  const float3 dx1 = make_float3(-ray_dir.z, 0, ray_dir.x);
528  ray_space[0] = normalize(dot(dx0, dx0) > dot(dx1, dx1) ? dx0 : dx1);
529  ray_space[1] = normalize(cross(ray_dir, ray_space[0]));
530  ray_space[2] = ray_dir;
531 }
532 
533 ccl_device_inline float4 ribbon_to_ray_space(const float3 ray_space[3],
534  const float3 ray_org,
535  const float4 P4)
536 {
537  float3 P = float4_to_float3(P4) - ray_org;
538  return make_float4(dot(ray_space[0], P), dot(ray_space[1], P), dot(ray_space[2], P), P4.w);
539 }
540 
541 ccl_device_inline bool ribbon_intersect(const float3 ray_org,
542  const float3 ray_dir,
543  const float ray_tfar,
544  const int N,
545  float4 curve[4],
546  Intersection *isect)
547 {
548  /* Transform control points into ray space. */
549  float3 ray_space[3];
550  ribbon_ray_space(ray_dir, ray_space);
551 
552  curve[0] = ribbon_to_ray_space(ray_space, ray_org, curve[0]);
553  curve[1] = ribbon_to_ray_space(ray_space, ray_org, curve[1]);
554  curve[2] = ribbon_to_ray_space(ray_space, ray_org, curve[2]);
555  curve[3] = ribbon_to_ray_space(ray_space, ray_org, curve[3]);
556 
557  const float4 mx = max(max(fabs(curve[0]), fabs(curve[1])), max(fabs(curve[2]), fabs(curve[3])));
558  const float eps = 4.0f * FLT_EPSILON * max(max(mx.x, mx.y), max(mx.z, mx.w));
559  const float step_size = 1.0f / (float)N;
560 
561  /* Evaluate first point and radius scaled normal direction. */
562  float4 p0 = catmull_rom_basis_eval(curve, 0.0f);
563  float3 dp0dt = float4_to_float3(catmull_rom_basis_derivative(curve, 0.0f));
564  if (max3(fabs(dp0dt)) < eps) {
565  const float4 p1 = catmull_rom_basis_eval(curve, step_size);
566  dp0dt = float4_to_float3(p1 - p0);
567  }
568  float3 wn0 = normalize(make_float3(dp0dt.y, -dp0dt.x, 0.0f)) * p0.w;
569 
570  /* Evaluate the bezier curve. */
571  for (int i = 0; i < N; i++) {
572  const float u = i * step_size;
573  const float4 p1 = catmull_rom_basis_eval(curve, u + step_size);
574  const bool valid = cylinder_culling_test(
575  make_float2(p0.x, p0.y), make_float2(p1.x, p1.y), max(p0.w, p1.w));
576 
577  /* Evaluate next point. */
578  float3 dp1dt = float4_to_float3(catmull_rom_basis_derivative(curve, u + step_size));
579  dp1dt = (max3(fabs(dp1dt)) < eps) ? float4_to_float3(p1 - p0) : dp1dt;
580  const float3 wn1 = normalize(make_float3(dp1dt.y, -dp1dt.x, 0.0f)) * p1.w;
581 
582  if (valid) {
583  /* Construct quad coordinates. */
584  const float3 lp0 = float4_to_float3(p0) + wn0;
585  const float3 lp1 = float4_to_float3(p1) + wn1;
586  const float3 up0 = float4_to_float3(p0) - wn0;
587  const float3 up1 = float4_to_float3(p1) - wn1;
588 
589  /* Intersect quad. */
590  float vu, vv, vt;
591  bool valid0 = ribbon_intersect_quad(isect->t, lp0, lp1, up1, up0, &vu, &vv, &vt);
592 
593  if (valid0) {
594  /* ignore self intersections */
595  const float avoidance_factor = 2.0f;
596  if (avoidance_factor != 0.0f) {
597  float r = mix(p0.w, p1.w, vu);
598  valid0 = vt > avoidance_factor * r;
599  }
600 
601  if (valid0) {
602  vv = 2.0f * vv - 1.0f;
603 
604  /* Record intersection. */
605  isect->t = vt;
606  isect->u = u + vu * step_size;
607  isect->v = vv;
608  return true;
609  }
610  }
611  }
612 
613  /* Store point for next step. */
614  p0 = p1;
615  wn0 = wn1;
616  }
617  return false;
618 }
619 
620 ccl_device_forceinline bool curve_intersect(KernelGlobals *kg,
621  Intersection *isect,
622  const float3 P,
623  const float3 dir,
624  uint visibility,
625  int object,
626  int curveAddr,
627  float time,
628  int type)
629 {
630  const bool is_motion = (type & PRIMITIVE_ALL_MOTION);
631 
632 # ifndef __KERNEL_OPTIX__ /* See OptiX motion flag OPTIX_MOTION_FLAG_[START|END]_VANISH */
633  if (is_motion && kernel_data.bvh.use_bvh_steps) {
634  const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
635  if (time < prim_time.x || time > prim_time.y) {
636  return false;
637  }
638  }
639 # endif
640 
642  int prim = kernel_tex_fetch(__prim_index, curveAddr);
643 
644  float4 v00 = kernel_tex_fetch(__curves, prim);
645 
646  int k0 = __float_as_int(v00.x) + segment;
647  int k1 = k0 + 1;
648 
649  int ka = max(k0 - 1, __float_as_int(v00.x));
650  int kb = min(k1 + 1, __float_as_int(v00.x) + __float_as_int(v00.y) - 1);
651 
652  float4 curve[4];
653  if (!is_motion) {
654  curve[0] = kernel_tex_fetch(__curve_keys, ka);
655  curve[1] = kernel_tex_fetch(__curve_keys, k0);
656  curve[2] = kernel_tex_fetch(__curve_keys, k1);
657  curve[3] = kernel_tex_fetch(__curve_keys, kb);
658  }
659  else {
660  int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
661  motion_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, curve);
662  }
663 
664 # ifdef __VISIBILITY_FLAG__
665  if (!(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)) {
666  return false;
667  }
668 # endif
669 
671  /* todo: adaptive number of subdivisions could help performance here. */
672  const int subdivisions = kernel_data.bvh.curve_subdivisions;
673  if (ribbon_intersect(P, dir, isect->t, subdivisions, curve, isect)) {
674  isect->prim = curveAddr;
675  isect->object = object;
676  isect->type = type;
677  return true;
678  }
679 
680  return false;
681  }
682  else {
683  if (curve_intersect_recursive(P, dir, curve, isect)) {
684  isect->prim = curveAddr;
685  isect->object = object;
686  isect->type = type;
687  return true;
688  }
689 
690  return false;
691  }
692 }
693 
694 ccl_device_inline void curve_shader_setup(KernelGlobals *kg,
695  ShaderData *sd,
696  const Intersection *isect,
697  const Ray *ray)
698 {
699  float t = isect->t;
700  float3 P = ray->P;
701  float3 D = ray->D;
702 
703  if (isect->object != OBJECT_NONE) {
704 # ifdef __OBJECT_MOTION__
705  Transform tfm = sd->ob_itfm;
706 # else
708 # endif
709 
710  P = transform_point(&tfm, P);
711  D = transform_direction(&tfm, D * t);
712  D = normalize_len(D, &t);
713  }
714 
715  int prim = kernel_tex_fetch(__prim_index, isect->prim);
716  float4 v00 = kernel_tex_fetch(__curves, prim);
717 
718  int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
719  int k1 = k0 + 1;
720 
721  int ka = max(k0 - 1, __float_as_int(v00.x));
722  int kb = min(k1 + 1, __float_as_int(v00.x) + __float_as_int(v00.y) - 1);
723 
724  float4 P_curve[4];
725 
726  if (!(sd->type & PRIMITIVE_ALL_MOTION)) {
727  P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
728  P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
729  P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
730  P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
731  }
732  else {
733  motion_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
734  }
735 
736  sd->u = isect->u;
737 
738  P = P + D * t;
739 
740  const float4 dPdu4 = catmull_rom_basis_derivative(P_curve, isect->u);
741  const float3 dPdu = float4_to_float3(dPdu4);
742 
744  /* Rounded smooth normals for ribbons, to approximate thick curve shape. */
745  const float3 tangent = normalize(dPdu);
746  const float3 bitangent = normalize(cross(tangent, -D));
747  const float sine = isect->v;
748  const float cosine = safe_sqrtf(1.0f - sine * sine);
749 
750  sd->N = normalize(sine * bitangent - cosine * normalize(cross(tangent, bitangent)));
751  sd->Ng = -D;
752  sd->v = isect->v;
753 
754 # if 0
755  /* This approximates the position and geometric normal of a thick curve too,
756  * but gives too many issues with wrong self intersections. */
757  const float dPdu_radius = dPdu4.w;
758  sd->Ng = sd->N;
759  P += sd->N * dPdu_radius;
760 # endif
761  }
762  else {
763  /* Thick curves, compute normal using direction from inside the curve.
764  * This could be optimized by recording the normal in the intersection,
765  * however for Optix this would go beyond the size of the payload. */
766  const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, isect->u));
767  const float3 Ng = normalize(P - P_inside);
768 
769  sd->N = Ng;
770  sd->Ng = Ng;
771  sd->v = 0.0f;
772  }
773 
774 # ifdef __DPDU__
775  /* dPdu/dPdv */
776  sd->dPdu = dPdu;
777  sd->dPdv = cross(dPdu, sd->Ng);
778 # endif
779 
780  if (isect->object != OBJECT_NONE) {
781 # ifdef __OBJECT_MOTION__
782  Transform tfm = sd->ob_tfm;
783 # else
785 # endif
786 
787  P = transform_point(&tfm, P);
788  }
789 
790  sd->P = P;
791 
792  float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
793  sd->shader = __float_as_int(curvedata.z);
794 }
795 
796 #endif
797 
typedef float(TangentPoint)[2]
MINLINE float safe_sqrtf(float a)
unsigned int uint
Definition: BLI_sys_types.h:83
#define K(key)
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble u1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
#define C
Definition: RandGen.cpp:39
ATTR_WARN_UNUSED_RESULT const BMVert * v2
#define A
unsigned int U
Definition: btGjkEpa3.h:78
double time
Curve curve
#define CURVE_NUM_BEZIER_SUBDIVISIONS_UNSTABLE
#define CURVE_NUM_BEZIER_STEPS
#define CURVE_NUM_JACOBIAN_ITERATIONS
#define CURVE_NUM_BEZIER_SUBDIVISIONS
@ OBJECT_INVERSE_TRANSFORM
Definition: geom_object.h:31
@ OBJECT_TRANSFORM
Definition: geom_object.h:30
ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
Definition: geom_object.h:38
#define kernel_data
#define kernel_tex_fetch(tex, index)
#define ccl_device_forceinline
#define ccl_device
#define ccl_device_inline
#define CCL_NAMESPACE_END
#define make_float2(x, y)
#define make_float4(x, y, z, w)
#define fabsf(x)
#define sqrtf(x)
#define make_float3(x, y, z)
@ PRIMITIVE_MOTION_CURVE_RIBBON
Definition: kernel_types.h:691
@ PRIMITIVE_CURVE_RIBBON
Definition: kernel_types.h:690
@ PRIMITIVE_ALL_MOTION
Definition: kernel_types.h:700
#define PRIMITIVE_UNPACK_SEGMENT(type)
Definition: kernel_types.h:711
#define OBJECT_NONE
Definition: kernel_types.h:59
ShaderData
static float P(float k)
Definition: math_interp.c:41
#define T
#define B
#define R
Segment< FEdge *, Vec3r > segment
params N
const btScalar eps
Definition: poly34.cpp:11
#define min(a, b)
Definition: sort.c:51
float3 P
Definition: kernel_types.h:647
float3 D
Definition: kernel_types.h:648
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
float max
__forceinline avxf cross(const avxf &a, const avxf &b)
Definition: util_avxf.h:119
#define mix(a, b, c)
Definition: util_hash.h:30
ccl_device_inline int __float_as_int(float f)
Definition: util_math.h:202
ccl_device_inline float sqr(float a)
Definition: util_math.h:651
ccl_device_inline float inversesqrtf(float f)
Definition: util_math.h:591
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition: util_math.h:415
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float2 normalize_len(const float2 &a, float *t)
ccl_device_inline float2 fabs(const float2 &a)
ccl_device_inline float max3(float3 a)
ccl_device_inline float3 transform_direction(const Transform *t, const float3 a)
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)
CCL_NAMESPACE_BEGIN struct View V
uint len
BLI_INLINE float D(const float *data, const int res[3], int x, int y, int z)
Definition: voxel.c:29