1 /*
2  * Copyright 2011-2020 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "render/hair.h"
18 #include "render/curves.h"
19 #include "render/scene.h"
20 
21 CCL_NAMESPACE_BEGIN
22 
23 /* Hair Curve */
24 
bounds_grow(const int k,const float3 * curve_keys,const float * curve_radius,BoundBox & bounds) const25 void Hair::Curve::bounds_grow(const int k,
26                               const float3 *curve_keys,
27                               const float *curve_radius,
28                               BoundBox &bounds) const
29 {
30   float3 P[4];
31 
32   P[0] = curve_keys[max(first_key + k - 1, first_key)];
33   P[1] = curve_keys[first_key + k];
34   P[2] = curve_keys[first_key + k + 1];
35   P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
36 
37   float3 lower;
38   float3 upper;
39 
40   curvebounds(&lower.x, &upper.x, P, 0);
41   curvebounds(&lower.y, &upper.y, P, 1);
42   curvebounds(&lower.z, &upper.z, P, 2);
43 
44   float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
45 
46   bounds.grow(lower, mr);
47   bounds.grow(upper, mr);
48 }
49 
bounds_grow(const int k,const float3 * curve_keys,const float * curve_radius,const Transform & aligned_space,BoundBox & bounds) const50 void Hair::Curve::bounds_grow(const int k,
51                               const float3 *curve_keys,
52                               const float *curve_radius,
53                               const Transform &aligned_space,
54                               BoundBox &bounds) const
55 {
56   float3 P[4];
57 
58   P[0] = curve_keys[max(first_key + k - 1, first_key)];
59   P[1] = curve_keys[first_key + k];
60   P[2] = curve_keys[first_key + k + 1];
61   P[3] = curve_keys[min(first_key + k + 2, first_key + num_keys - 1)];
62 
63   P[0] = transform_point(&aligned_space, P[0]);
64   P[1] = transform_point(&aligned_space, P[1]);
65   P[2] = transform_point(&aligned_space, P[2]);
66   P[3] = transform_point(&aligned_space, P[3]);
67 
68   float3 lower;
69   float3 upper;
70 
71   curvebounds(&lower.x, &upper.x, P, 0);
72   curvebounds(&lower.y, &upper.y, P, 1);
73   curvebounds(&lower.z, &upper.z, P, 2);
74 
75   float mr = max(curve_radius[first_key + k], curve_radius[first_key + k + 1]);
76 
77   bounds.grow(lower, mr);
78   bounds.grow(upper, mr);
79 }
80 
bounds_grow(float4 keys[4],BoundBox & bounds) const81 void Hair::Curve::bounds_grow(float4 keys[4], BoundBox &bounds) const
82 {
83   float3 P[4] = {
84       float4_to_float3(keys[0]),
85       float4_to_float3(keys[1]),
86       float4_to_float3(keys[2]),
87       float4_to_float3(keys[3]),
88   };
89 
90   float3 lower;
91   float3 upper;
92 
93   curvebounds(&lower.x, &upper.x, P, 0);
94   curvebounds(&lower.y, &upper.y, P, 1);
95   curvebounds(&lower.z, &upper.z, P, 2);
96 
97   float mr = max(keys[1].w, keys[2].w);
98 
99   bounds.grow(lower, mr);
100   bounds.grow(upper, mr);
101 }
102 
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]) const103 void Hair::Curve::motion_keys(const float3 *curve_keys,
104                               const float *curve_radius,
105                               const float3 *key_steps,
106                               size_t num_curve_keys,
107                               size_t num_steps,
108                               float time,
109                               size_t k0,
110                               size_t k1,
111                               float4 r_keys[2]) const
112 {
113   /* Figure out which steps we need to fetch and their interpolation factor. */
114   const size_t max_step = num_steps - 1;
115   const size_t step = min((int)(time * max_step), max_step - 1);
116   const float t = time * max_step - step;
117   /* Fetch vertex coordinates. */
118   float4 curr_keys[2];
119   float4 next_keys[2];
120   keys_for_step(
121       curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step, k0, k1, curr_keys);
122   keys_for_step(
123       curve_keys, curve_radius, key_steps, num_curve_keys, num_steps, step + 1, k0, k1, next_keys);
124   /* Interpolate between steps. */
125   r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0];
126   r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1];
127 }
128 
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]) const129 void Hair::Curve::cardinal_motion_keys(const float3 *curve_keys,
130                                        const float *curve_radius,
131                                        const float3 *key_steps,
132                                        size_t num_curve_keys,
133                                        size_t num_steps,
134                                        float time,
135                                        size_t k0,
136                                        size_t k1,
137                                        size_t k2,
138                                        size_t k3,
139                                        float4 r_keys[4]) const
140 {
141   /* Figure out which steps we need to fetch and their interpolation factor. */
142   const size_t max_step = num_steps - 1;
143   const size_t step = min((int)(time * max_step), max_step - 1);
144   const float t = time * max_step - step;
145   /* Fetch vertex coordinates. */
146   float4 curr_keys[4];
147   float4 next_keys[4];
148   cardinal_keys_for_step(curve_keys,
149                          curve_radius,
150                          key_steps,
151                          num_curve_keys,
152                          num_steps,
153                          step,
154                          k0,
155                          k1,
156                          k2,
157                          k3,
158                          curr_keys);
159   cardinal_keys_for_step(curve_keys,
160                          curve_radius,
161                          key_steps,
162                          num_curve_keys,
163                          num_steps,
164                          step + 1,
165                          k0,
166                          k1,
167                          k2,
168                          k3,
169                          next_keys);
170   /* Interpolate between steps. */
171   r_keys[0] = (1.0f - t) * curr_keys[0] + t * next_keys[0];
172   r_keys[1] = (1.0f - t) * curr_keys[1] + t * next_keys[1];
173   r_keys[2] = (1.0f - t) * curr_keys[2] + t * next_keys[2];
174   r_keys[3] = (1.0f - t) * curr_keys[3] + t * next_keys[3];
175 }
176 
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]) const177 void Hair::Curve::keys_for_step(const float3 *curve_keys,
178                                 const float *curve_radius,
179                                 const float3 *key_steps,
180                                 size_t num_curve_keys,
181                                 size_t num_steps,
182                                 size_t step,
183                                 size_t k0,
184                                 size_t k1,
185                                 float4 r_keys[2]) const
186 {
187   k0 = max(k0, 0);
188   k1 = min(k1, num_keys - 1);
189   const size_t center_step = ((num_steps - 1) / 2);
190   if (step == center_step) {
191     /* Center step: regular key location. */
192     /* TODO(sergey): Consider adding make_float4(float3, float)
193      * function.
194      */
195     r_keys[0] = make_float4(curve_keys[first_key + k0].x,
196                             curve_keys[first_key + k0].y,
197                             curve_keys[first_key + k0].z,
198                             curve_radius[first_key + k0]);
199     r_keys[1] = make_float4(curve_keys[first_key + k1].x,
200                             curve_keys[first_key + k1].y,
201                             curve_keys[first_key + k1].z,
202                             curve_radius[first_key + k1]);
203   }
204   else {
205     /* Center step is not stored in this array. */
206     if (step > center_step) {
207       step--;
208     }
209     const size_t offset = first_key + step * num_curve_keys;
210     r_keys[0] = make_float4(key_steps[offset + k0].x,
211                             key_steps[offset + k0].y,
212                             key_steps[offset + k0].z,
213                             curve_radius[first_key + k0]);
214     r_keys[1] = make_float4(key_steps[offset + k1].x,
215                             key_steps[offset + k1].y,
216                             key_steps[offset + k1].z,
217                             curve_radius[first_key + k1]);
218   }
219 }
220 
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]) const221 void Hair::Curve::cardinal_keys_for_step(const float3 *curve_keys,
222                                          const float *curve_radius,
223                                          const float3 *key_steps,
224                                          size_t num_curve_keys,
225                                          size_t num_steps,
226                                          size_t step,
227                                          size_t k0,
228                                          size_t k1,
229                                          size_t k2,
230                                          size_t k3,
231                                          float4 r_keys[4]) const
232 {
233   k0 = max(k0, 0);
234   k3 = min(k3, num_keys - 1);
235   const size_t center_step = ((num_steps - 1) / 2);
236   if (step == center_step) {
237     /* Center step: regular key location. */
238     r_keys[0] = make_float4(curve_keys[first_key + k0].x,
239                             curve_keys[first_key + k0].y,
240                             curve_keys[first_key + k0].z,
241                             curve_radius[first_key + k0]);
242     r_keys[1] = make_float4(curve_keys[first_key + k1].x,
243                             curve_keys[first_key + k1].y,
244                             curve_keys[first_key + k1].z,
245                             curve_radius[first_key + k1]);
246     r_keys[2] = make_float4(curve_keys[first_key + k2].x,
247                             curve_keys[first_key + k2].y,
248                             curve_keys[first_key + k2].z,
249                             curve_radius[first_key + k2]);
250     r_keys[3] = make_float4(curve_keys[first_key + k3].x,
251                             curve_keys[first_key + k3].y,
252                             curve_keys[first_key + k3].z,
253                             curve_radius[first_key + k3]);
254   }
255   else {
256     /* Center step is not stored in this array. */
257     if (step > center_step) {
258       step--;
259     }
260     const size_t offset = first_key + step * num_curve_keys;
261     r_keys[0] = make_float4(key_steps[offset + k0].x,
262                             key_steps[offset + k0].y,
263                             key_steps[offset + k0].z,
264                             curve_radius[first_key + k0]);
265     r_keys[1] = make_float4(key_steps[offset + k1].x,
266                             key_steps[offset + k1].y,
267                             key_steps[offset + k1].z,
268                             curve_radius[first_key + k1]);
269     r_keys[2] = make_float4(key_steps[offset + k2].x,
270                             key_steps[offset + k2].y,
271                             key_steps[offset + k2].z,
272                             curve_radius[first_key + k2]);
273     r_keys[3] = make_float4(key_steps[offset + k3].x,
274                             key_steps[offset + k3].y,
275                             key_steps[offset + k3].z,
276                             curve_radius[first_key + k3]);
277   }
278 }
279 
280 /* Hair */
281 
NODE_DEFINE(Hair)282 NODE_DEFINE(Hair)
283 {
284   NodeType *type = NodeType::add("hair", create, NodeType::NONE, Geometry::node_base_type);
285 
286   SOCKET_POINT_ARRAY(curve_keys, "Curve Keys", array<float3>());
287   SOCKET_FLOAT_ARRAY(curve_radius, "Curve Radius", array<float>());
288   SOCKET_INT_ARRAY(curve_first_key, "Curve First Key", array<int>());
289   SOCKET_INT_ARRAY(curve_shader, "Curve Shader", array<int>());
290 
291   return type;
292 }
293 
Hair()294 Hair::Hair() : Geometry(node_type, Geometry::HAIR)
295 {
296   curvekey_offset = 0;
297   curve_shape = CURVE_RIBBON;
298 }
299 
~Hair()300 Hair::~Hair()
301 {
302 }
303 
resize_curves(int numcurves,int numkeys)304 void Hair::resize_curves(int numcurves, int numkeys)
305 {
306   curve_keys.resize(numkeys);
307   curve_radius.resize(numkeys);
308   curve_first_key.resize(numcurves);
309   curve_shader.resize(numcurves);
310 
311   attributes.resize();
312 }
313 
reserve_curves(int numcurves,int numkeys)314 void Hair::reserve_curves(int numcurves, int numkeys)
315 {
316   curve_keys.reserve(numkeys);
317   curve_radius.reserve(numkeys);
318   curve_first_key.reserve(numcurves);
319   curve_shader.reserve(numcurves);
320 
321   attributes.resize(true);
322 }
323 
clear()324 void Hair::clear()
325 {
326   Geometry::clear();
327 
328   curve_keys.clear();
329   curve_radius.clear();
330   curve_first_key.clear();
331   curve_shader.clear();
332 
333   attributes.clear();
334 }
335 
add_curve_key(float3 co,float radius)336 void Hair::add_curve_key(float3 co, float radius)
337 {
338   curve_keys.push_back_reserved(co);
339   curve_radius.push_back_reserved(radius);
340 }
341 
add_curve(int first_key,int shader)342 void Hair::add_curve(int first_key, int shader)
343 {
344   curve_first_key.push_back_reserved(first_key);
345   curve_shader.push_back_reserved(shader);
346 }
347 
copy_center_to_motion_step(const int motion_step)348 void Hair::copy_center_to_motion_step(const int motion_step)
349 {
350   Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
351   if (attr_mP) {
352     float3 *keys = &curve_keys[0];
353     size_t numkeys = curve_keys.size();
354     memcpy(attr_mP->data_float3() + motion_step * numkeys, keys, sizeof(float3) * numkeys);
355   }
356 }
357 
get_uv_tiles(ustring map,unordered_set<int> & tiles)358 void Hair::get_uv_tiles(ustring map, unordered_set<int> &tiles)
359 {
360   Attribute *attr;
361 
362   if (map.empty()) {
363     attr = attributes.find(ATTR_STD_UV);
364   }
365   else {
366     attr = attributes.find(map);
367   }
368 
369   if (attr) {
370     attr->get_uv_tiles(this, ATTR_PRIM_GEOMETRY, tiles);
371   }
372 }
373 
compute_bounds()374 void Hair::compute_bounds()
375 {
376   BoundBox bnds = BoundBox::empty;
377   size_t curve_keys_size = curve_keys.size();
378 
379   if (curve_keys_size > 0) {
380     for (size_t i = 0; i < curve_keys_size; i++)
381       bnds.grow(curve_keys[i], curve_radius[i]);
382 
383     Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
384     if (use_motion_blur && curve_attr) {
385       size_t steps_size = curve_keys.size() * (motion_steps - 1);
386       float3 *key_steps = curve_attr->data_float3();
387 
388       for (size_t i = 0; i < steps_size; i++)
389         bnds.grow(key_steps[i]);
390     }
391 
392     if (!bnds.valid()) {
393       bnds = BoundBox::empty;
394 
395       /* skip nan or inf coordinates */
396       for (size_t i = 0; i < curve_keys_size; i++)
397         bnds.grow_safe(curve_keys[i], curve_radius[i]);
398 
399       if (use_motion_blur && curve_attr) {
400         size_t steps_size = curve_keys.size() * (motion_steps - 1);
401         float3 *key_steps = curve_attr->data_float3();
402 
403         for (size_t i = 0; i < steps_size; i++)
404           bnds.grow_safe(key_steps[i]);
405       }
406     }
407   }
408 
409   if (!bnds.valid()) {
410     /* empty mesh */
411     bnds.grow(make_float3(0.0f, 0.0f, 0.0f));
412   }
413 
414   bounds = bnds;
415 }
416 
apply_transform(const Transform & tfm,const bool apply_to_motion)417 void Hair::apply_transform(const Transform &tfm, const bool apply_to_motion)
418 {
419   /* compute uniform scale */
420   float3 c0 = transform_get_column(&tfm, 0);
421   float3 c1 = transform_get_column(&tfm, 1);
422   float3 c2 = transform_get_column(&tfm, 2);
423   float scalar = powf(fabsf(dot(cross(c0, c1), c2)), 1.0f / 3.0f);
424 
425   /* apply transform to curve keys */
426   for (size_t i = 0; i < curve_keys.size(); i++) {
427     float3 co = transform_point(&tfm, curve_keys[i]);
428     float radius = curve_radius[i] * scalar;
429 
430     /* scale for curve radius is only correct for uniform scale */
431     curve_keys[i] = co;
432     curve_radius[i] = radius;
433   }
434 
435   if (apply_to_motion) {
436     Attribute *curve_attr = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
437 
438     if (curve_attr) {
439       /* apply transform to motion curve keys */
440       size_t steps_size = curve_keys.size() * (motion_steps - 1);
441       float4 *key_steps = curve_attr->data_float4();
442 
443       for (size_t i = 0; i < steps_size; i++) {
444         float3 co = transform_point(&tfm, float4_to_float3(key_steps[i]));
445         float radius = key_steps[i].w * scalar;
446 
447         /* scale for curve radius is only correct for uniform scale */
448         key_steps[i] = float3_to_float4(co);
449         key_steps[i].w = radius;
450       }
451     }
452   }
453 }
454 
pack_curves(Scene * scene,float4 * curve_key_co,float4 * curve_data,size_t curvekey_offset)455 void Hair::pack_curves(Scene *scene,
456                        float4 *curve_key_co,
457                        float4 *curve_data,
458                        size_t curvekey_offset)
459 {
460   size_t curve_keys_size = curve_keys.size();
461 
462   /* pack curve keys */
463   if (curve_keys_size) {
464     float3 *keys_ptr = curve_keys.data();
465     float *radius_ptr = curve_radius.data();
466 
467     for (size_t i = 0; i < curve_keys_size; i++)
468       curve_key_co[i] = make_float4(keys_ptr[i].x, keys_ptr[i].y, keys_ptr[i].z, radius_ptr[i]);
469   }
470 
471   /* pack curve segments */
472   size_t curve_num = num_curves();
473 
474   for (size_t i = 0; i < curve_num; i++) {
475     Curve curve = get_curve(i);
476     int shader_id = curve_shader[i];
477     Shader *shader = (shader_id < used_shaders.size()) ? used_shaders[shader_id] :
478                                                          scene->default_surface;
479     shader_id = scene->shader_manager->get_shader_id(shader, false);
480 
481     curve_data[i] = make_float4(__int_as_float(curve.first_key + curvekey_offset),
482                                 __int_as_float(curve.num_keys),
483                                 __int_as_float(shader_id),
484                                 0.0f);
485   }
486 }
487 
488 CCL_NAMESPACE_END
489