Blender V4.3
hair.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "bvh/bvh.h"
6
7#include "scene/curves.h"
8#include "scene/hair.h"
9#include "scene/object.h"
10#include "scene/scene.h"
11
13
14#include "util/progress.h"
15#include "util/tbb.h"
16
18
19/* Hair Curve */
20void Hair::Curve::bounds_grow(const int k, const float4 *keys, BoundBox &bounds) const
21{
22 float3 P[4];
23
24 P[0] = float4_to_float3(keys[max(first_key + k - 1, first_key)]);
25 P[1] = float4_to_float3(keys[first_key + k]);
26 P[2] = float4_to_float3(keys[first_key + k + 1]);
27 P[3] = float4_to_float3(keys[min(first_key + k + 2, first_key + num_keys - 1)]);
28
29 float3 lower;
30 float3 upper;
31
32 curvebounds(&lower.x, &upper.x, P, 0);
33 curvebounds(&lower.y, &upper.y, P, 1);
34 curvebounds(&lower.z, &upper.z, P, 2);
35
36 float mr = max(keys[1].w, keys[2].w);
37
38 bounds.grow(lower, mr);
39 bounds.grow(upper, mr);
40}
41
42void Hair::Curve::bounds_grow(const int k,
43 const float3 *curve_keys,
44 const float *curve_radius,
45 BoundBox &bounds) const
46{
47 float3 P[4];
48
49 P[0] = curve_keys[max(first_key + k - 1, first_key)];
50 P[1] = curve_keys[first_key + k];
51 P[2] = curve_keys[first_key + k + 1];
52 P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
53
54 float3 lower;
55 float3 upper;
56
57 curvebounds(&lower.x, &upper.x, P, 0);
58 curvebounds(&lower.y, &upper.y, P, 1);
59 curvebounds(&lower.z, &upper.z, P, 2);
60
61 float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
62
63 bounds.grow(lower, mr);
64 bounds.grow(upper, mr);
65}
66
67void Hair::Curve::bounds_grow(const int k,
68 const float3 *curve_keys,
69 const float *curve_radius,
70 const Transform &aligned_space,
71 BoundBox &bounds) const
72{
73 float3 P[4];
74
75 P[0] = curve_keys[max(first_key + k - 1, first_key)];
76 P[1] = curve_keys[first_key + k];
77 P[2] = curve_keys[first_key + k + 1];
78 P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
79
80 P[0] = transform_point(&aligned_space, P[0]);
81 P[1] = transform_point(&aligned_space, P[1]);
82 P[2] = transform_point(&aligned_space, P[2]);
83 P[3] = transform_point(&aligned_space, P[3]);
84
85 float3 lower;
86 float3 upper;
87
88 curvebounds(&lower.x, &upper.x, P, 0);
89 curvebounds(&lower.y, &upper.y, P, 1);
90 curvebounds(&lower.z, &upper.z, P, 2);
91
92 float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
93
94 bounds.grow(lower, mr);
95 bounds.grow(upper, mr);
96}
97
98void Hair::Curve::bounds_grow(float4 keys[4], BoundBox &bounds) const
99{
100 float3 P[4] = {
101 float4_to_float3(keys[0]),
102 float4_to_float3(keys[1]),
103 float4_to_float3(keys[2]),
104 float4_to_float3(keys[3]),
105 };
106
107 float3 lower;
108 float3 upper;
109
110 curvebounds(&lower.x, &upper.x, P, 0);
111 curvebounds(&lower.y, &upper.y, P, 1);
112 curvebounds(&lower.z, &upper.z, P, 2);
113
114 float mr = max(keys[1].w, keys[2].w);
115
116 bounds.grow(lower, mr);
117 bounds.grow(upper, mr);
118}
119
120void Hair::Curve::motion_keys(const float3 *curve_keys,
121 const float *curve_radius,
122 const float4 *key_steps,
123 size_t num_curve_keys,
124 size_t num_steps,
125 float time,
126 size_t k0,
127 size_t k1,
128 float4 r_keys[2]) const
129{
130 /* Figure out which steps we need to fetch and their interpolation factor. */
131 const size_t max_step = num_steps - 1;
132 const size_t step = std::min((size_t)(time * max_step), max_step - 1);
133 const float t = time * max_step - step;
134 /* Fetch vertex coordinates. */
135 float4 curr_keys[2];
136 float4 next_keys[2];
137 keys_for_step(
138 curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step, k0, k1, curr_keys);
139 keys_for_step(
140 curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step + 1, k0, k1, next_keys);
141 /* Interpolate between steps. */
142 r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0];
143 r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1];
144}
145
147 const float *curve_radius,
148 const float4 *key_steps,
149 size_t num_curve_keys,
150 size_t num_steps,
151 float time,
152 size_t k0,
153 size_t k1,
154 size_t k2,
155 size_t k3,
156 float4 r_keys[4]) const
157{
158 /* Figure out which steps we need to fetch and their interpolation factor. */
159 const size_t max_step = num_steps - 1;
160 const size_t step = min((size_t)(time * max_step), max_step - 1);
161 const float t = time * max_step - step;
162 /* Fetch vertex coordinates. */
163 float4 curr_keys[4];
164 float4 next_keys[4];
165 cardinal_keys_for_step(curve_keys,
166 curve_radius,
167 key_steps,
168 num_curve_keys,
169 num_steps,
170 step,
171 k0,
172 k1,
173 k2,
174 k3,
175 curr_keys);
176 cardinal_keys_for_step(curve_keys,
177 curve_radius,
178 key_steps,
179 num_curve_keys,
180 num_steps,
181 step + 1,
182 k0,
183 k1,
184 k2,
185 k3,
186 next_keys);
187 /* Interpolate between steps. */
188 r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0];
189 r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1];
190 r_keys[2] = (1.0f - t) * curr_keys[2] + t * next_keys[2];
191 r_keys[3] = (1.0f - t) * curr_keys[3] + t * next_keys[3];
192}
193
194void Hair::Curve::keys_for_step(const float3 *curve_keys,
195 const float *curve_radius,
196 const float4 *key_steps,
197 size_t num_curve_keys,
198 size_t num_steps,
199 size_t step,
200 size_t k0,
201 size_t k1,
202 float4 r_keys[2]) const
203{
204 k0 = max(k0, (size_t)0);
205 k1 = min(k1, (size_t)(num_keys - 1));
206 const size_t center_step = ((num_steps - 1) / 2);
207 if (step == center_step) {
208 /* Center step: regular key location. */
209 /* TODO(sergey): Consider adding make_float4(float3, float)
210 * function.
211 */
212 r_keys[0] = make_float4(curve_keys[first_key + k0].x,
213 curve_keys[first_key + k0].y,
214 curve_keys[first_key + k0].z,
215 curve_radius[first_key + k0]);
216 r_keys[1] = make_float4(curve_keys[first_key + k1].x,
217 curve_keys[first_key + k1].y,
218 curve_keys[first_key + k1].z,
219 curve_radius[first_key + k1]);
220 }
221 else {
222 /* Center step is not stored in this array. */
223 if (step > center_step) {
224 step--;
225 }
226 const size_t offset = first_key + step * num_curve_keys;
227 r_keys[0] = make_float4(key_steps[offset + k0].x,
228 key_steps[offset + k0].y,
229 key_steps[offset + k0].z,
230 curve_radius[first_key + k0]);
231 r_keys[1] = make_float4(key_steps[offset + k1].x,
232 key_steps[offset + k1].y,
233 key_steps[offset + k1].z,
234 curve_radius[first_key + k1]);
235 }
236}
237
239 const float *curve_radius,
240 const float4 *key_steps,
241 size_t num_curve_keys,
242 size_t num_steps,
243 size_t step,
244 size_t k0,
245 size_t k1,
246 size_t k2,
247 size_t k3,
248 float4 r_keys[4]) const
249{
250 k0 = max(k0, (size_t)0);
251 k3 = min(k3, (size_t)(num_keys - 1));
252 const size_t center_step = ((num_steps - 1) / 2);
253 if (step == center_step) {
254 /* Center step: regular key location. */
255 r_keys[0] = make_float4(curve_keys[first_key + k0].x,
256 curve_keys[first_key + k0].y,
257 curve_keys[first_key + k0].z,
258 curve_radius[first_key + k0]);
259 r_keys[1] = make_float4(curve_keys[first_key + k1].x,
260 curve_keys[first_key + k1].y,
261 curve_keys[first_key + k1].z,
262 curve_radius[first_key + k1]);
263 r_keys[2] = make_float4(curve_keys[first_key + k2].x,
264 curve_keys[first_key + k2].y,
265 curve_keys[first_key + k2].z,
266 curve_radius[first_key + k2]);
267 r_keys[3] = make_float4(curve_keys[first_key + k3].x,
268 curve_keys[first_key + k3].y,
269 curve_keys[first_key + k3].z,
270 curve_radius[first_key + k3]);
271 }
272 else {
273 /* Center step is not stored in this array. */
274 if (step > center_step) {
275 step--;
276 }
277 const size_t offset = first_key + step * num_curve_keys;
278 r_keys[0] = make_float4(key_steps[offset + k0].x,
279 key_steps[offset + k0].y,
280 key_steps[offset + k0].z,
281 curve_radius[first_key + k0]);
282 r_keys[1] = make_float4(key_steps[offset + k1].x,
283 key_steps[offset + k1].y,
284 key_steps[offset + k1].z,
285 curve_radius[first_key + k1]);
286 r_keys[2] = make_float4(key_steps[offset + k2].x,
287 key_steps[offset + k2].y,
288 key_steps[offset + k2].z,
289 curve_radius[first_key + k2]);
290 r_keys[3] = make_float4(key_steps[offset + k3].x,
291 key_steps[offset + k3].y,
292 key_steps[offset + k3].z,
293 curve_radius[first_key + k3]);
294 }
295}
296
297/* Hair */
298
300{
301 NodeType *type = NodeType::add("hair", create, NodeType::NONE, Geometry::get_node_base_type());
302
303 SOCKET_POINT_ARRAY(curve_keys, "Curve Keys", array<float3>());
304 SOCKET_FLOAT_ARRAY(curve_radius, "Curve Radius", array<float>());
305 SOCKET_INT_ARRAY(curve_first_key, "Curve First Key", array<int>());
306 SOCKET_INT_ARRAY(curve_shader, "Curve Shader", array<int>());
307
308 return type;
309}
310
311Hair::Hair() : Geometry(get_node_type(), Geometry::HAIR)
312{
316}
317
319
320void Hair::resize_curves(int numcurves, int numkeys)
321{
322 curve_keys.resize(numkeys);
323 curve_radius.resize(numkeys);
324 curve_first_key.resize(numcurves);
325 curve_shader.resize(numcurves);
326
327 attributes.resize();
328}
329
330void Hair::reserve_curves(int numcurves, int numkeys)
331{
332 curve_keys.reserve(numkeys);
333 curve_radius.reserve(numkeys);
334 curve_first_key.reserve(numcurves);
335 curve_shader.reserve(numcurves);
336
337 attributes.resize(true);
338}
339
340void Hair::clear(bool preserve_shaders)
341{
342 Geometry::clear(preserve_shaders);
343
344 curve_keys.clear();
345 curve_radius.clear();
346 curve_first_key.clear();
347 curve_shader.clear();
348
349 attributes.clear();
350}
351
352void Hair::add_curve_key(float3 co, float radius)
353{
354 curve_keys.push_back_reserved(co);
355 curve_radius.push_back_reserved(radius);
356
357 tag_curve_keys_modified();
358 tag_curve_radius_modified();
359}
360
361void Hair::add_curve(int first_key, int shader)
362{
363 curve_first_key.push_back_reserved(first_key);
364 curve_shader.push_back_reserved(shader);
365
366 tag_curve_first_key_modified();
367 tag_curve_shader_modified();
368}
369
370void Hair::copy_center_to_motion_step(const int motion_step)
371{
372 Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
373 if (attr_mP) {
374 float3 *keys = &curve_keys[0];
375 size_t numkeys = curve_keys.size();
376 memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys);
377 }
378}
379
380void Hair::get_uv_tiles(ustring map, unordered_set<int> &tiles)
381{
382 Attribute *attr;
383
384 if (map.empty()) {
385 attr = attributes.find(ATTR_STD_UV);
386 }
387 else {
388 attr = attributes.find(map);
389 }
390
391 if (attr) {
393 }
394}
395
397{
399 size_t curve_keys_size = curve_keys.size();
400 size_t curve_num = num_curves();
401
402 if (curve_keys_size > 0) {
403 bnds.grow(parallel_reduce(
404 blocked_range<size_t>(0, curve_num),
406 [&](const blocked_range<size_t> &range, const BoundBox &partial_bounds) {
407 BoundBox current_bounds = partial_bounds;
408 for (size_t i = range.begin(); i < range.end(); ++i) {
409 const Curve curve = get_curve(i);
410 const int num_segments = curve.num_segments();
411 for (int k = 0; k < num_segments; k++) {
412 curve.bounds_grow(k, curve_keys.data(), curve_radius.data(), current_bounds);
413 }
414 }
415 return current_bounds;
416 },
417 [](const BoundBox &bounds_a, const BoundBox &bounds_b) {
418 BoundBox combined_bounds = bounds_a;
419 combined_bounds.grow(bounds_b);
420 return combined_bounds;
421 }));
422
423 Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
424 if (use_motion_blur && curve_attr) {
425 size_t steps_size = curve_keys.size() * (motion_steps - 1);
426 // Attribute data is stored as a float4 and is not
427 // interchangeable with float3
428 float4 *key_steps = curve_attr->data_float4();
429
430 for (size_t i = 0; i < steps_size; i++) {
431 bnds.grow(float4_to_float3(key_steps[i]));
432 }
433 }
434
435 if (!bnds.valid()) {
436 bnds = BoundBox::empty;
437
438 /* skip nan or inf coordinates */
439 for (size_t i = 0; i < curve_keys_size; i++) {
440 bnds.grow_safe(curve_keys[i], curve_radius[i]);
441 }
442
443 if (use_motion_blur && curve_attr) {
444 size_t steps_size = curve_keys.size() * (motion_steps - 1);
445 // Attribute data is stored as a float4 which is not
446 // interchangeable with float4
447 float4 *key_steps = curve_attr->data_float4();
448
449 for (size_t i = 0; i < steps_size; i++) {
450 bnds.grow_safe(float4_to_float3(key_steps[i]));
451 }
452 }
453 }
454 }
455
456 if (!bnds.valid()) {
457 /* empty mesh */
458 bnds.grow(zero_float3());
459 }
460
461 bounds = bnds;
462}
463
464void Hair::apply_transform(const Transform &tfm, const bool apply_to_motion)
465{
466 /* compute uniform scale */
467 float3 c0 = transform_get_column(&tfm, 0);
468 float3 c1 = transform_get_column(&tfm, 1);
469 float3 c2 = transform_get_column(&tfm, 2);
470 float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f / 3.0f);
471
472 /* apply transform to curve keys */
473 for (size_t i = 0; i < curve_keys.size(); i++) {
474 float3 co = transform_point(&tfm, curve_keys[i]);
475 float radius = curve_radius[i] * scalar;
476
477 /* scale for curve radius is only correct for uniform scale */
478 curve_keys[i] = co;
479 curve_radius[i] = radius;
480 }
481
482 tag_curve_keys_modified();
483 tag_curve_radius_modified();
484
485 if (apply_to_motion) {
486 Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
487
488 if (curve_attr) {
489 /* apply transform to motion curve keys */
490 size_t steps_size = curve_keys.size() * (motion_steps - 1);
491 float4 *key_steps = curve_attr->data_float4();
492
493 for (size_t i = 0; i < steps_size; i++) {
494 float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
495 float radius = key_steps[i].w * scalar;
496
497 /* scale for curve radius is only correct for uniform scale */
498 key_steps[i] = float3_to_float4(co);
499 key_steps[i].w = radius;
500 }
501 }
502 }
503}
504
506 float4 *curve_key_co,
507 KernelCurve *curves,
508 KernelCurveSegment *curve_segments)
509{
510 size_t curve_keys_size = curve_keys.size();
511
512 /* pack curve keys */
513 if (curve_keys_size) {
514 float3 *keys_ptr = curve_keys.data();
515 float *radius_ptr = curve_radius.data();
516
517 for (size_t i = 0; i < curve_keys_size; i++) {
518 curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]);
519 }
520 }
521
522 /* pack curve segments */
523 const PrimitiveType type = primitive_type();
524
525 size_t curve_num = num_curves();
526 size_t index = 0;
527
528 for (size_t i = 0; i < curve_num; i++) {
529 Curve curve = get_curve(i);
530 int shader_id = curve_shader[i];
531 Shader *shader = (shader_id < used_shaders.size()) ?
532 static_cast<Shader *>(used_shaders[shader_id]) :
533 scene->default_surface;
534 shader_id = scene->shader_manager->get_shader_id(shader, false);
535
536 curves[i].shader_id = shader_id;
537 curves[i].first_key = curve_key_offset + curve.first_key;
538 curves[i].num_keys = curve.num_keys;
539 curves[i].type = type;
540
541 for (int k = 0; k < curve.num_segments(); ++k, ++index) {
542 curve_segments[index].prim = prim_offset + i;
543 curve_segments[index].type = PRIMITIVE_PACK_SEGMENT(type, k);
544 }
545 }
546}
547
555
556/* Fill in coordinates for curve transparency shader evaluation on device. */
557static int fill_shader_input(const Hair *hair,
558 const size_t object_index,
560{
561 int d_input_size = 0;
562 KernelShaderEvalInput *d_input_data = d_input.data();
563
564 const int num_curves = hair->num_curves();
565 for (int i = 0; i < num_curves; i++) {
566 const Hair::Curve curve = hair->get_curve(i);
567 const int num_segments = curve.num_segments();
568
569 for (int j = 0; j < num_segments + 1; j++) {
571 in.object = object_index;
572 in.prim = hair->prim_offset + i;
573 in.u = (j < num_segments) ? 0.0f : 1.0f;
574 in.v = (j < num_segments) ? __int_as_float(j) : __int_as_float(j - 1);
575 d_input_data[d_input_size++] = in;
576 }
577 }
578
579 return d_input_size;
580}
581
582/* Read back curve transparency shader output. */
583static void read_shader_output(float *shadow_transparency,
584 bool &is_fully_opaque,
585 const device_vector<float> &d_output)
586{
587 const int num_keys = d_output.size();
588 const float *output_data = d_output.data();
589 bool is_opaque = true;
590
591 for (int i = 0; i < num_keys; i++) {
592 shadow_transparency[i] = output_data[i];
593 if (shadow_transparency[i] > 0.0f) {
594 is_opaque = false;
595 }
596 }
597
598 is_fully_opaque = is_opaque;
599}
600
602{
603 for (const Node *node : used_shaders) {
604 const Shader *shader = static_cast<const Shader *>(node);
605 if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) {
606 return true;
607 }
608 }
609
610 return false;
611}
612
614{
616 /* If no shaders with shadow transparency, remove attribute. */
617 Attribute *attr = attributes.find(ATTR_STD_SHADOW_TRANSPARENCY);
618 if (attr) {
619 attributes.remove(attr);
620 return true;
621 }
622 else {
623 return false;
624 }
625 }
626
627 string msg = string_printf("Computing Shadow Transparency %s", name.c_str());
628 progress.set_status("Updating Hair", msg);
629
630 /* Create shadow transparency attribute. */
631 Attribute *attr = attributes.find(ATTR_STD_SHADOW_TRANSPARENCY);
632 const bool attribute_exists = (attr != nullptr);
633 if (!attribute_exists) {
634 attr = attributes.add(ATTR_STD_SHADOW_TRANSPARENCY);
635 }
636
637 float *attr_data = attr->data_float();
638
639 /* Find object index. */
640 size_t object_index = OBJECT_NONE;
641
642 for (size_t i = 0; i < scene->objects.size(); i++) {
643 if (scene->objects[i]->get_geometry() == this) {
644 object_index = i;
645 break;
646 }
647 }
648
649 /* Evaluate shader on device. */
650 ShaderEval shader_eval(device, progress);
651 bool is_fully_opaque = false;
653 num_keys(),
654 1,
655 function_bind(&fill_shader_input, this, object_index, _1),
656 function_bind(&read_shader_output, attr_data, is_fully_opaque, _1));
657
658 if (is_fully_opaque) {
659 attributes.remove(attr);
660 return attribute_exists;
661 }
662
663 return true;
664}
665
struct BoundBox BoundBox
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
void get_uv_tiles(Geometry *geom, AttributePrimitive prim, unordered_set< int > &tiles) const
float * data_float()
float3 * data_float3()
float4 * data_float4()
void add(const float &f)
BoundBox bounds
int motion_step(float time) const
size_t prim_offset
bool has_motion_blur() const
virtual void clear(bool preserve_shaders=false)
Definition hair.h:14
~Hair()
Definition hair.cpp:318
void resize_curves(int numcurves, int numkeys)
Definition hair.cpp:320
void add_curve(int first_key, int shader)
Definition hair.cpp:361
Curve get_curve(size_t i) const
Definition hair.h:112
bool need_shadow_transparency()
Definition hair.cpp:601
void compute_bounds() override
Definition hair.cpp:396
size_t curve_key_offset
Definition hair.h:90
void reserve_curves(int numcurves, int numkeys)
Definition hair.cpp:330
size_t curve_segment_offset
Definition hair.h:91
size_t num_curves() const
Definition hair.h:126
bool update_shadow_transparency(Device *device, Scene *scene, Progress &progress)
Definition hair.cpp:613
void get_uv_tiles(ustring map, unordered_set< int > &tiles) override
Definition hair.cpp:380
void copy_center_to_motion_step(const int motion_step)
Definition hair.cpp:370
void pack_curves(Scene *scene, float4 *curve_key_co, KernelCurve *curve, KernelCurveSegment *curve_segments)
Definition hair.cpp:505
size_t num_segments() const
Definition hair.h:131
CurveShapeType curve_shape
Definition hair.h:92
void clear(bool preserve_shaders=false) override
Definition hair.cpp:340
size_t num_keys() const
Definition hair.h:121
void apply_transform(const Transform &tfm, const bool apply_to_motion) override
Definition hair.cpp:464
PrimitiveType primitive_type() const override
Definition hair.cpp:548
Hair()
Definition hair.cpp:311
void add_curve_key(float3 loc, float radius)
Definition hair.cpp:352
void set_status(const string &status_, const string &substatus_="")
Definition progress.h:263
bool eval(const ShaderEvalType type, const int max_num_inputs, const int num_channels, const function< int(device_vector< KernelShaderEvalInput > &)> &fill_input, const function< void(device_vector< float > &)> &read_output)
size_t size() const
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
OperationNode * node
#define function_bind
#define powf(x, y)
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
#define __int_as_float(x)
#define fabsf(x)
static void read_shader_output(float *shadow_transparency, bool &is_fully_opaque, const device_vector< float > &d_output)
Definition hair.cpp:583
static int fill_shader_input(const Hair *hair, const size_t object_index, device_vector< KernelShaderEvalInput > &d_input)
Definition hair.cpp:557
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
#define PRIMITIVE_PACK_SEGMENT(type, segment)
PrimitiveType
@ PRIMITIVE_MOTION_CURVE_RIBBON
@ PRIMITIVE_CURVE_RIBBON
@ PRIMITIVE_MOTION_CURVE_THICK
@ PRIMITIVE_CURVE_THICK
@ ATTR_STD_UV
@ ATTR_STD_MOTION_VERTEX_POSITION
@ ATTR_STD_SHADOW_TRANSPARENCY
@ CURVE_RIBBON
#define OBJECT_NONE
@ ATTR_PRIM_GEOMETRY
ccl_device_inline float cross(const float2 a, const float2 b)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
#define SOCKET_POINT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:257
#define SOCKET_FLOAT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:248
#define SOCKET_INT_ARRAY(name, ui_name, default_value,...)
Definition node_type.h:246
#define NODE_DEFINE(structname)
Definition node_type.h:148
CCL_NAMESPACE_BEGIN void curvebounds(float *lower, float *upper, float3 *p, int dim)
@ SHADER_EVAL_CURVE_SHADOW_TRANSPARENCY
Definition shader_eval.h:21
#define min(a, b)
Definition sort.c:32
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition string.cpp:23
__forceinline bool valid() const
Definition boundbox.h:128
__forceinline float3 size() const
Definition boundbox.h:123
__forceinline void grow_safe(const float3 &pt)
Definition boundbox.h:57
__forceinline void grow(const float3 &pt)
Definition boundbox.h:36
void cardinal_motion_keys(const float3 *curve_keys, const float *curve_radius, const float4 *key_steps, size_t num_curve_keys, size_t num_steps, float time, size_t k0, size_t k1, size_t k2, size_t k3, float4 r_keys[4]) const
Definition hair.cpp:146
void bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox &bounds) const
Definition hair.cpp:42
void cardinal_keys_for_step(const float3 *curve_keys, const float *curve_radius, const float4 *key_steps, size_t num_curve_keys, size_t num_steps, size_t step, size_t k0, size_t k1, size_t k2, size_t k3, float4 r_keys[4]) const
Definition hair.cpp:238
void motion_keys(const float3 *curve_keys, const float *curve_radius, const float4 *key_steps, size_t num_curve_keys, size_t num_steps, float time, size_t k0, size_t k1, float4 r_keys[2]) const
Definition hair.cpp:120
int first_key
Definition hair.h:20
void keys_for_step(const float3 *curve_keys, const float *curve_radius, const float4 *key_steps, size_t num_curve_keys, size_t num_steps, size_t step, size_t k0, size_t k1, float4 r_keys[2]) const
Definition hair.cpp:194
int num_segments() const
Definition hair.h:23
int num_keys
Definition hair.h:21
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
const NodeType * type
Definition graph/node.h:178
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
ccl_device_inline float3 transform_get_column(const Transform *t, int column)
Definition transform.h:326
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float3 transform_point(ccl_private const Transform *t, const float3 a)
Definition transform.h:63
float max
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition util/math.h:540
ccl_device_inline float3 float4_to_float3(const float4 a)
Definition util/math.h:535