Blender  V3.3
bvh2.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011-2022 Blender Foundation. */
4 
5 #include "bvh/bvh2.h"
6 
7 #include "scene/hair.h"
8 #include "scene/mesh.h"
9 #include "scene/object.h"
10 #include "scene/pointcloud.h"
11 
12 #include "bvh/build.h"
13 #include "bvh/node.h"
14 #include "bvh/unaligned.h"
15 
16 #include "util/foreach.h"
17 #include "util/progress.h"
18 
20 
21 BVHStackEntry::BVHStackEntry(const BVHNode *n, int i) : node(n), idx(i)
22 {
23 }
24 
26 {
27  return (node->is_leaf()) ? ~idx : idx;
28 }
29 
30 BVH2::BVH2(const BVHParams &params_,
31  const vector<Geometry *> &geometry_,
32  const vector<Object *> &objects_)
33  : BVH(params_, geometry_, objects_)
34 {
35 }
36 
37 void BVH2::build(Progress &progress, Stats *)
38 {
39  progress.set_substatus("Building BVH");
40 
41  /* build nodes */
42  BVHBuild bvh_build(objects,
47  params,
48  progress);
49  BVHNode *bvh2_root = bvh_build.run();
50 
51  if (progress.get_cancel()) {
52  if (bvh2_root != NULL) {
53  bvh2_root->deleteSubtree();
54  }
55  return;
56  }
57 
58  /* BVH builder returns tree in a binary mode (with two children per inner
59  * node. Need to adopt that for a wider BVH implementations. */
60  BVHNode *root = widen_children_nodes(bvh2_root);
61  if (root != bvh2_root) {
62  bvh2_root->deleteSubtree();
63  }
64 
65  if (progress.get_cancel()) {
66  if (root != NULL) {
67  root->deleteSubtree();
68  }
69  return;
70  }
71 
72  /* pack triangles */
73  progress.set_substatus("Packing BVH triangles and strands");
75 
76  if (progress.get_cancel()) {
77  root->deleteSubtree();
78  return;
79  }
80 
81  /* pack nodes */
82  progress.set_substatus("Packing BVH nodes");
83  pack_nodes(root);
84 
85  /* free build nodes */
86  root->deleteSubtree();
87 }
88 
89 void BVH2::refit(Progress &progress)
90 {
91  progress.set_substatus("Packing BVH primitives");
93 
94  if (progress.get_cancel())
95  return;
96 
97  progress.set_substatus("Refitting BVH nodes");
98  refit_nodes();
99 }
100 
102 {
103  return const_cast<BVHNode *>(root);
104 }
105 
106 void BVH2::pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
107 {
108  assert(e.idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
110  memset(data, 0, sizeof(data));
111  if (leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
112  /* object */
113  data[0].x = __int_as_float(~(leaf->lo));
114  data[0].y = __int_as_float(0);
115  }
116  else {
117  /* triangle */
118  data[0].x = __int_as_float(leaf->lo);
119  data[0].y = __int_as_float(leaf->hi);
120  }
121  data[0].z = __uint_as_float(leaf->visibility);
122  if (leaf->num_triangles() != 0) {
123  data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
124  }
125 
126  memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4) * BVH_NODE_LEAF_SIZE);
127 }
128 
129 void BVH2::pack_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
130 {
131  if (e0.node->is_unaligned || e1.node->is_unaligned) {
132  pack_unaligned_inner(e, e0, e1);
133  }
134  else {
135  pack_aligned_inner(e, e0, e1);
136  }
137 }
138 
140  const BVHStackEntry &e0,
141  const BVHStackEntry &e1)
142 {
143  pack_aligned_node(e.idx,
144  e0.node->bounds,
145  e1.node->bounds,
146  e0.encodeIdx(),
147  e1.encodeIdx(),
148  e0.node->visibility,
149  e1.node->visibility);
150 }
151 
153  const BoundBox &b0,
154  const BoundBox &b1,
155  int c0,
156  int c1,
157  uint visibility0,
158  uint visibility1)
159 {
160  assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
161  assert(c0 < 0 || c0 < pack.nodes.size());
162  assert(c1 < 0 || c1 < pack.nodes.size());
163 
164  int4 data[BVH_NODE_SIZE] = {
165  make_int4(
166  visibility0 & ~PATH_RAY_NODE_UNALIGNED, visibility1 & ~PATH_RAY_NODE_UNALIGNED, c0, c1),
168  __float_as_int(b1.min.x),
169  __float_as_int(b0.max.x),
170  __float_as_int(b1.max.x)),
172  __float_as_int(b1.min.y),
173  __float_as_int(b0.max.y),
174  __float_as_int(b1.max.y)),
176  __float_as_int(b1.min.z),
177  __float_as_int(b0.max.z),
178  __float_as_int(b1.max.z)),
179  };
180 
181  memcpy(&pack.nodes[idx], data, sizeof(int4) * BVH_NODE_SIZE);
182 }
183 
185  const BVHStackEntry &e0,
186  const BVHStackEntry &e1)
187 {
189  e0.node->get_aligned_space(),
190  e1.node->get_aligned_space(),
191  e0.node->bounds,
192  e1.node->bounds,
193  e0.encodeIdx(),
194  e1.encodeIdx(),
195  e0.node->visibility,
196  e1.node->visibility);
197 }
198 
200  const Transform &aligned_space0,
201  const Transform &aligned_space1,
202  const BoundBox &bounds0,
203  const BoundBox &bounds1,
204  int c0,
205  int c1,
206  uint visibility0,
207  uint visibility1)
208 {
209  assert(idx + BVH_UNALIGNED_NODE_SIZE <= pack.nodes.size());
210  assert(c0 < 0 || c0 < pack.nodes.size());
211  assert(c1 < 0 || c1 < pack.nodes.size());
212 
214  Transform space0 = BVHUnaligned::compute_node_transform(bounds0, aligned_space0);
215  Transform space1 = BVHUnaligned::compute_node_transform(bounds1, aligned_space1);
218  __int_as_float(c0),
219  __int_as_float(c1));
220 
221  data[1] = space0.x;
222  data[2] = space0.y;
223  data[3] = space0.z;
224  data[4] = space1.x;
225  data[5] = space1.y;
226  data[6] = space1.z;
227 
228  memcpy(&pack.nodes[idx], data, sizeof(float4) * BVH_UNALIGNED_NODE_SIZE);
229 }
230 
231 void BVH2::pack_nodes(const BVHNode *root)
232 {
233  const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
234  const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
235  assert(num_leaf_nodes <= num_nodes);
236  const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
237  size_t node_size;
239  const size_t num_unaligned_nodes = root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
240  node_size = (num_unaligned_nodes * BVH_UNALIGNED_NODE_SIZE) +
241  (num_inner_nodes - num_unaligned_nodes) * BVH_NODE_SIZE;
242  }
243  else {
244  node_size = num_inner_nodes * BVH_NODE_SIZE;
245  }
246  /* Resize arrays */
247  pack.nodes.clear();
249  /* For top level BVH, first merge existing BVH's so we know the offsets. */
250  if (params.top_level) {
251  pack_instances(node_size, num_leaf_nodes * BVH_NODE_LEAF_SIZE);
252  }
253  else {
254  pack.nodes.resize(node_size);
255  pack.leaf_nodes.resize(num_leaf_nodes * BVH_NODE_LEAF_SIZE);
256  }
257 
258  int nextNodeIdx = 0, nextLeafNodeIdx = 0;
259 
260  vector<BVHStackEntry> stack;
261  stack.reserve(BVHParams::MAX_DEPTH * 2);
262  if (root->is_leaf()) {
263  stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
264  }
265  else {
266  stack.push_back(BVHStackEntry(root, nextNodeIdx));
267  nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_NODE_SIZE : BVH_NODE_SIZE;
268  }
269 
270  while (stack.size()) {
271  BVHStackEntry e = stack.back();
272  stack.pop_back();
273 
274  if (e.node->is_leaf()) {
275  /* leaf node */
276  const LeafNode *leaf = reinterpret_cast<const LeafNode *>(e.node);
277  pack_leaf(e, leaf);
278  }
279  else {
280  /* inner node */
281  int idx[2];
282  for (int i = 0; i < 2; ++i) {
283  if (e.node->get_child(i)->is_leaf()) {
284  idx[i] = nextLeafNodeIdx++;
285  }
286  else {
287  idx[i] = nextNodeIdx;
288  nextNodeIdx += e.node->get_child(i)->has_unaligned() ? BVH_UNALIGNED_NODE_SIZE :
290  }
291  }
292 
293  stack.push_back(BVHStackEntry(e.node->get_child(0), idx[0]));
294  stack.push_back(BVHStackEntry(e.node->get_child(1), idx[1]));
295 
296  pack_inner(e, stack[stack.size() - 2], stack[stack.size() - 1]);
297  }
298  }
299  assert(node_size == nextNodeIdx);
300  /* root index to start traversal at, to handle case of single leaf node */
301  pack.root_index = (root->is_leaf()) ? -1 : 0;
302 }
303 
305 {
306  assert(!params.top_level);
307 
308  BoundBox bbox = BoundBox::empty;
309  uint visibility = 0;
310  refit_node(0, (pack.root_index == -1) ? true : false, bbox, visibility);
311 }
312 
313 void BVH2::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
314 {
315  if (leaf) {
316  /* refit leaf node */
317  assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
318  const int4 *data = &pack.leaf_nodes[idx];
319  const int c0 = data[0].x;
320  const int c1 = data[0].y;
321 
322  refit_primitives(c0, c1, bbox, visibility);
323 
324  /* TODO(sergey): De-duplicate with pack_leaf(). */
325  float4 leaf_data[BVH_NODE_LEAF_SIZE];
326  leaf_data[0].x = __int_as_float(c0);
327  leaf_data[0].y = __int_as_float(c1);
328  leaf_data[0].z = __uint_as_float(visibility);
329  leaf_data[0].w = __uint_as_float(data[0].w);
330  memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4) * BVH_NODE_LEAF_SIZE);
331  }
332  else {
333  assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
334 
335  const int4 *data = &pack.nodes[idx];
336  const bool is_unaligned = (data[0].x & PATH_RAY_NODE_UNALIGNED) != 0;
337  const int c0 = data[0].z;
338  const int c1 = data[0].w;
339  /* refit inner node, set bbox from children */
340  BoundBox bbox0 = BoundBox::empty, bbox1 = BoundBox::empty;
341  uint visibility0 = 0, visibility1 = 0;
342 
343  refit_node((c0 < 0) ? -c0 - 1 : c0, (c0 < 0), bbox0, visibility0);
344  refit_node((c1 < 0) ? -c1 - 1 : c1, (c1 < 0), bbox1, visibility1);
345 
346  if (is_unaligned) {
347  Transform aligned_space = transform_identity();
349  idx, aligned_space, aligned_space, bbox0, bbox1, c0, c1, visibility0, visibility1);
350  }
351  else {
352  pack_aligned_node(idx, bbox0, bbox1, c0, c1, visibility0, visibility1);
353  }
354 
355  bbox.grow(bbox0);
356  bbox.grow(bbox1);
357  visibility = visibility0 | visibility1;
358  }
359 }
360 
361 /* Refitting */
362 
363 void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility)
364 {
365  /* Refit range of primitives. */
366  for (int prim = start; prim < end; prim++) {
367  int pidx = pack.prim_index[prim];
368  int tob = pack.prim_object[prim];
369  Object *ob = objects[tob];
370 
371  if (pidx == -1) {
372  /* Object instance. */
373  bbox.grow(ob->bounds);
374  }
375  else {
376  /* Primitives. */
377  if (pack.prim_type[prim] & PRIMITIVE_CURVE) {
378  /* Curves. */
379  const Hair *hair = static_cast<const Hair *>(ob->get_geometry());
380  int prim_offset = (params.top_level) ? hair->prim_offset : 0;
381  Hair::Curve curve = hair->get_curve(pidx - prim_offset);
382  int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
383 
384  curve.bounds_grow(k, &hair->get_curve_keys()[0], &hair->get_curve_radius()[0], bbox);
385 
386  /* Motion curves. */
387  if (hair->get_use_motion_blur()) {
389 
390  if (attr) {
391  size_t hair_size = hair->get_curve_keys().size();
392  size_t steps = hair->get_motion_steps() - 1;
393  float3 *key_steps = attr->data_float3();
394 
395  for (size_t i = 0; i < steps; i++)
396  curve.bounds_grow(k, key_steps + i * hair_size, &hair->get_curve_radius()[0], bbox);
397  }
398  }
399  }
400  else if (pack.prim_type[prim] & PRIMITIVE_POINT) {
401  /* Points. */
402  const PointCloud *pointcloud = static_cast<const PointCloud *>(ob->get_geometry());
403  int prim_offset = (params.top_level) ? pointcloud->prim_offset : 0;
404  const float3 *points = &pointcloud->points[0];
405  const float *radius = &pointcloud->radius[0];
406  PointCloud::Point point = pointcloud->get_point(pidx - prim_offset);
407 
408  point.bounds_grow(points, radius, bbox);
409 
410  /* Motion points. */
411  if (pointcloud->get_use_motion_blur()) {
413 
414  if (attr) {
415  size_t pointcloud_size = pointcloud->points.size();
416  size_t steps = pointcloud->get_motion_steps() - 1;
417  float3 *point_steps = attr->data_float3();
418 
419  for (size_t i = 0; i < steps; i++)
420  point.bounds_grow(point_steps + i * pointcloud_size, radius, bbox);
421  }
422  }
423  }
424  else {
425  /* Triangles. */
426  const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry());
427  int prim_offset = (params.top_level) ? mesh->prim_offset : 0;
428  Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset);
429  const float3 *vpos = &mesh->verts[0];
430 
431  triangle.bounds_grow(vpos, bbox);
432 
433  /* Motion triangles. */
434  if (mesh->use_motion_blur) {
436 
437  if (attr) {
438  size_t mesh_size = mesh->verts.size();
439  size_t steps = mesh->motion_steps - 1;
440  float3 *vert_steps = attr->data_float3();
441 
442  for (size_t i = 0; i < steps; i++)
443  triangle.bounds_grow(vert_steps + i * mesh_size, bbox);
444  }
445  }
446  }
447  }
448  visibility |= ob->visibility_for_tracing();
449  }
450 }
451 
452 /* Triangles */
453 
455 {
456  const size_t tidx_size = pack.prim_index.size();
457  /* Reserve size for arrays. */
459  pack.prim_visibility.resize(tidx_size);
460  /* Fill in all the arrays. */
461  for (unsigned int i = 0; i < tidx_size; i++) {
462  if (pack.prim_index[i] != -1) {
463  int tob = pack.prim_object[i];
464  Object *ob = objects[tob];
466  }
467  else {
468  pack.prim_visibility[i] = 0;
469  }
470  }
471 }
472 
473 /* Pack Instances */
474 
475 void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
476 {
477  /* Adjust primitive index to point to the triangle in the global array, for
478  * geometry with transform applied and already in the top level BVH.
479  */
480  for (size_t i = 0; i < pack.prim_index.size(); i++) {
481  if (pack.prim_index[i] != -1) {
482  pack.prim_index[i] += objects[pack.prim_object[i]]->get_geometry()->prim_offset;
483  }
484  }
485 
486  /* track offsets of instanced BVH data in global array */
487  size_t prim_offset = pack.prim_index.size();
488  size_t nodes_offset = nodes_size;
489  size_t nodes_leaf_offset = leaf_nodes_size;
490 
491  /* clear array that gives the node indexes for instanced objects */
493 
494  /* reserve */
495  size_t prim_index_size = pack.prim_index.size();
496 
497  size_t pack_prim_index_offset = prim_index_size;
498  size_t pack_nodes_offset = nodes_size;
499  size_t pack_leaf_nodes_offset = leaf_nodes_size;
500  size_t object_offset = 0;
501 
502  foreach (Geometry *geom, geometry) {
503  BVH2 *bvh = static_cast<BVH2 *>(geom->bvh);
504 
505  if (geom->need_build_bvh(params.bvh_layout)) {
506  prim_index_size += bvh->pack.prim_index.size();
507  nodes_size += bvh->pack.nodes.size();
508  leaf_nodes_size += bvh->pack.leaf_nodes.size();
509  }
510  }
511 
512  pack.prim_index.resize(prim_index_size);
513  pack.prim_type.resize(prim_index_size);
514  pack.prim_object.resize(prim_index_size);
515  pack.prim_visibility.resize(prim_index_size);
516  pack.nodes.resize(nodes_size);
517  pack.leaf_nodes.resize(leaf_nodes_size);
518  pack.object_node.resize(objects.size());
519 
522  pack.prim_time.resize(prim_index_size);
523  }
524 
525  int *pack_prim_index = (pack.prim_index.size()) ? &pack.prim_index[0] : NULL;
526  int *pack_prim_type = (pack.prim_type.size()) ? &pack.prim_type[0] : NULL;
527  int *pack_prim_object = (pack.prim_object.size()) ? &pack.prim_object[0] : NULL;
528  uint *pack_prim_visibility = (pack.prim_visibility.size()) ? &pack.prim_visibility[0] : NULL;
529  int4 *pack_nodes = (pack.nodes.size()) ? &pack.nodes[0] : NULL;
530  int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL;
531  float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL;
532 
533  unordered_map<Geometry *, int> geometry_map;
534 
535  /* merge */
536  foreach (Object *ob, objects) {
537  Geometry *geom = ob->get_geometry();
538 
539  /* We assume that if mesh doesn't need own BVH it was already included
540  * into a top-level BVH and no packing here is needed.
541  */
542  if (!geom->need_build_bvh(params.bvh_layout)) {
543  pack.object_node[object_offset++] = 0;
544  continue;
545  }
546 
547  /* if mesh already added once, don't add it again, but used set
548  * node offset for this object */
549  unordered_map<Geometry *, int>::iterator it = geometry_map.find(geom);
550 
551  if (geometry_map.find(geom) != geometry_map.end()) {
552  int noffset = it->second;
553  pack.object_node[object_offset++] = noffset;
554  continue;
555  }
556 
557  BVH2 *bvh = static_cast<BVH2 *>(geom->bvh);
558 
559  int noffset = nodes_offset;
560  int noffset_leaf = nodes_leaf_offset;
561  int geom_prim_offset = geom->prim_offset;
562 
563  /* fill in node indexes for instances */
564  if (bvh->pack.root_index == -1)
565  pack.object_node[object_offset++] = -noffset_leaf - 1;
566  else
567  pack.object_node[object_offset++] = noffset;
568 
569  geometry_map[geom] = pack.object_node[object_offset - 1];
570 
571  /* merge primitive, object and triangle indexes */
572  if (bvh->pack.prim_index.size()) {
573  size_t bvh_prim_index_size = bvh->pack.prim_index.size();
574  int *bvh_prim_index = &bvh->pack.prim_index[0];
575  int *bvh_prim_type = &bvh->pack.prim_type[0];
576  uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
577  float2 *bvh_prim_time = bvh->pack.prim_time.size() ? &bvh->pack.prim_time[0] : NULL;
578 
579  for (size_t i = 0; i < bvh_prim_index_size; i++) {
580  pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
581  pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
582  pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
583  pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
584  if (bvh_prim_time != NULL) {
585  pack_prim_time[pack_prim_index_offset] = bvh_prim_time[i];
586  }
587  pack_prim_index_offset++;
588  }
589  }
590 
591  /* merge nodes */
592  if (bvh->pack.leaf_nodes.size()) {
593  int4 *leaf_nodes_offset = &bvh->pack.leaf_nodes[0];
594  size_t leaf_nodes_offset_size = bvh->pack.leaf_nodes.size();
595  for (size_t i = 0, j = 0; i < leaf_nodes_offset_size; i += BVH_NODE_LEAF_SIZE, j++) {
596  int4 data = leaf_nodes_offset[i];
597  data.x += prim_offset;
598  data.y += prim_offset;
599  pack_leaf_nodes[pack_leaf_nodes_offset] = data;
600  for (int j = 1; j < BVH_NODE_LEAF_SIZE; ++j) {
601  pack_leaf_nodes[pack_leaf_nodes_offset + j] = leaf_nodes_offset[i + j];
602  }
603  pack_leaf_nodes_offset += BVH_NODE_LEAF_SIZE;
604  }
605  }
606 
607  if (bvh->pack.nodes.size()) {
608  int4 *bvh_nodes = &bvh->pack.nodes[0];
609  size_t bvh_nodes_size = bvh->pack.nodes.size();
610 
611  for (size_t i = 0, j = 0; i < bvh_nodes_size; j++) {
612  size_t nsize, nsize_bbox;
613  if (bvh_nodes[i].x & PATH_RAY_NODE_UNALIGNED) {
614  nsize = BVH_UNALIGNED_NODE_SIZE;
615  nsize_bbox = 0;
616  }
617  else {
618  nsize = BVH_NODE_SIZE;
619  nsize_bbox = 0;
620  }
621 
622  memcpy(pack_nodes + pack_nodes_offset, bvh_nodes + i, nsize_bbox * sizeof(int4));
623 
624  /* Modify offsets into arrays */
625  int4 data = bvh_nodes[i + nsize_bbox];
626  data.z += (data.z < 0) ? -noffset_leaf : noffset;
627  data.w += (data.w < 0) ? -noffset_leaf : noffset;
628  pack_nodes[pack_nodes_offset + nsize_bbox] = data;
629 
630  /* Usually this copies nothing, but we better
631  * be prepared for possible node size extension.
632  */
633  memcpy(&pack_nodes[pack_nodes_offset + nsize_bbox + 1],
634  &bvh_nodes[i + nsize_bbox + 1],
635  sizeof(int4) * (nsize - (nsize_bbox + 1)));
636 
637  pack_nodes_offset += nsize;
638  i += nsize;
639  }
640  }
641 
642  nodes_offset += bvh->pack.nodes.size();
643  nodes_leaf_offset += bvh->pack.leaf_nodes.size();
644  prim_offset += bvh->pack.prim_index.size();
645  }
646 }
647 
unsigned int uint
Definition: BLI_sys_types.h:67
float float4[4]
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
#define BVH_NODE_SIZE
Definition: bvh2.h:16
#define BVH_NODE_LEAF_SIZE
Definition: bvh2.h:17
#define BVH_UNALIGNED_NODE_SIZE
Definition: bvh2.h:18
@ BVH_STAT_NODE_COUNT
Definition: bvh/node.h:14
@ BVH_STAT_UNALIGNED_INNER_COUNT
Definition: bvh/node.h:22
@ BVH_STAT_LEAF_COUNT
Definition: bvh/node.h:16
Attribute * find(ustring name) const
float3 * data_float3()
Definition: bvh2.h:33
void pack_instances(size_t nodes_size, size_t leaf_nodes_size)
Definition: bvh2.cpp:475
void pack_aligned_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
Definition: bvh2.cpp:139
void refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
Definition: bvh2.cpp:313
void pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
Definition: bvh2.cpp:106
void refit_primitives(int start, int end, BoundBox &bbox, uint &visibility)
Definition: bvh2.cpp:363
void pack_aligned_node(int idx, const BoundBox &b0, const BoundBox &b1, int c0, int c1, uint visibility0, uint visibility1)
Definition: bvh2.cpp:152
PackedBVH pack
Definition: bvh2.h:38
void pack_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
Definition: bvh2.cpp:129
virtual BVHNode * widen_children_nodes(const BVHNode *root)
Definition: bvh2.cpp:101
void pack_unaligned_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
Definition: bvh2.cpp:184
void pack_primitives()
Definition: bvh2.cpp:454
void pack_nodes(const BVHNode *root)
Definition: bvh2.cpp:231
void refit(Progress &progress)
Definition: bvh2.cpp:89
void pack_unaligned_node(int idx, const Transform &aligned_space0, const Transform &aligned_space1, const BoundBox &b0, const BoundBox &b1, int c0, int c1, uint visibility0, uint visibility1)
Definition: bvh2.cpp:199
BVH2(const BVHParams &params, const vector< Geometry * > &geometry, const vector< Object * > &objects)
Definition: bvh2.cpp:30
void refit_nodes()
Definition: bvh2.cpp:304
void build(Progress &progress, Stats *stats)
Definition: bvh2.cpp:37
Definition: build.h:34
BVHNode * run()
Definition: build.cpp:466
int num_motion_triangle_steps
Definition: params.h:97
BVHLayout bvh_layout
Definition: params.h:80
bool use_unaligned_nodes
Definition: params.h:85
int num_motion_point_steps
Definition: params.h:99
@ MAX_DEPTH
Definition: params.h:108
bool top_level
Definition: params.h:77
int num_motion_curve_steps
Definition: params.h:98
static Transform compute_node_transform(const BoundBox &bounds, const Transform &aligned_space)
Definition: unaligned.cpp:139
Definition: bvh/bvh.h:63
vector< Geometry * > geometry
Definition: bvh/bvh.h:66
BVHParams params
Definition: bvh/bvh.h:65
vector< Object * > objects
Definition: bvh/bvh.h:67
bool need_build_bvh(BVHLayout layout) const
size_t prim_offset
AttributeSet attributes
Definition: hair.h:13
Curve get_curve(size_t i) const
Definition: hair.h:109
int num_triangles() const
Definition: bvh/node.h:230
int hi
Definition: bvh/node.h:237
int lo
Definition: bvh/node.h:236
void set_substatus(const string &substatus_)
Definition: progress.h:259
bool get_cancel() const
Definition: progress.h:90
size_t size() const
T * resize(size_t newsize)
void clear()
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
OperationNode * node
Curve curve
#define foreach(x, y)
Definition: foreach.h:9
ccl_device_inline Transform transform_identity()
@ PRIMITIVE_CURVE
Definition: kernel/types.h:564
@ PRIMITIVE_POINT
Definition: kernel/types.h:554
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel/types.h:624
@ PATH_RAY_NODE_UNALIGNED
Definition: kernel/types.h:211
#define PRIMITIVE_UNPACK_SEGMENT(type)
Definition: kernel/types.h:579
#define make_int4(x, y, z, w)
Definition: metal/compat.h:208
#define make_float4(x, y, z, w)
Definition: metal/compat.h:205
static const int steps
Definition: sky_nishita.cpp:19
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const
Definition: bvh/node.cpp:16
uint visibility
Definition: bvh/node.h:91
bool is_unaligned
Definition: bvh/node.h:93
virtual bool is_leaf() const =0
void deleteSubtree()
Definition: bvh/node.cpp:92
bool has_unaligned() const
Definition: bvh/node.h:65
Transform get_aligned_space() const
Definition: bvh/node.h:57
BoundBox bounds
Definition: bvh/node.h:90
const BVHNode * node
Definition: bvh2.h:22
BVHStackEntry(const BVHNode *n=0, int i=0)
Definition: bvh2.cpp:21
int idx
Definition: bvh2.h:23
int encodeIdx() const
Definition: bvh2.cpp:25
@ empty
Definition: boundbox.h:35
float3 max
Definition: boundbox.h:21
__forceinline void grow(const float3 &pt)
Definition: boundbox.h:42
float3 min
Definition: boundbox.h:21
float size[3]
Triangle get_triangle(size_t i) const
Definition: scene/mesh.h:73
NODE_DECLARE BoundBox bounds
Definition: scene/object.h:43
uint visibility_for_tracing() const
array< int > prim_index
Definition: bvh/bvh.h:46
array< int > prim_type
Definition: bvh/bvh.h:41
array< int4 > nodes
Definition: bvh/bvh.h:35
array< uint > prim_visibility
Definition: bvh/bvh.h:43
array< float2 > prim_time
Definition: bvh/bvh.h:50
array< int4 > leaf_nodes
Definition: bvh/bvh.h:37
array< int > prim_object
Definition: bvh/bvh.h:48
int root_index
Definition: bvh/bvh.h:53
array< int > object_node
Definition: bvh/bvh.h:39
Point get_point(int i) const
float z
float y
float x
ccl_device_inline float __uint_as_float(uint i)
Definition: util/math.h:273
ccl_device_inline int __float_as_int(float f)
Definition: util/math.h:243
ccl_device_inline float __int_as_float(int i)
Definition: util/math.h:253