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