Blender  V2.93
bvh2.cpp
Go to the documentation of this file.
1 /*
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011, Blender Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "bvh/bvh2.h"
19 
20 #include "render/hair.h"
21 #include "render/mesh.h"
22 #include "render/object.h"
23 
24 #include "bvh/bvh_build.h"
25 #include "bvh/bvh_node.h"
26 #include "bvh/bvh_unaligned.h"
27 
28 #include "util/util_foreach.h"
29 #include "util/util_progress.h"
30 
32 
33 BVHStackEntry::BVHStackEntry(const BVHNode *n, int i) : node(n), idx(i)
34 {
35 }
36 
38 {
39  return (node->is_leaf()) ? ~idx : idx;
40 }
41 
42 BVH2::BVH2(const BVHParams &params_,
43  const vector<Geometry *> &geometry_,
44  const vector<Object *> &objects_)
45  : BVH(params_, geometry_, objects_)
46 {
47 }
48 
49 void BVH2::build(Progress &progress, Stats *)
50 {
51  progress.set_substatus("Building BVH");
52 
53  /* build nodes */
54  BVHBuild bvh_build(objects,
59  params,
60  progress);
61  BVHNode *bvh2_root = bvh_build.run();
62 
63  if (progress.get_cancel()) {
64  if (bvh2_root != NULL) {
65  bvh2_root->deleteSubtree();
66  }
67  return;
68  }
69 
70  /* BVH builder returns tree in a binary mode (with two children per inner
71  * node. Need to adopt that for a wider BVH implementations. */
72  BVHNode *root = widen_children_nodes(bvh2_root);
73  if (root != bvh2_root) {
74  bvh2_root->deleteSubtree();
75  }
76 
77  if (progress.get_cancel()) {
78  if (root != NULL) {
79  root->deleteSubtree();
80  }
81  return;
82  }
83 
84  /* pack triangles */
85  progress.set_substatus("Packing BVH triangles and strands");
87 
88  if (progress.get_cancel()) {
89  root->deleteSubtree();
90  return;
91  }
92 
93  /* pack nodes */
94  progress.set_substatus("Packing BVH nodes");
95  pack_nodes(root);
96 
97  /* free build nodes */
98  root->deleteSubtree();
99 }
100 
101 void BVH2::refit(Progress &progress)
102 {
103  progress.set_substatus("Packing BVH primitives");
104  pack_primitives();
105 
106  if (progress.get_cancel())
107  return;
108 
109  progress.set_substatus("Refitting BVH nodes");
110  refit_nodes();
111 }
112 
114 {
115  return const_cast<BVHNode *>(root);
116 }
117 
118 void BVH2::pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
119 {
120  assert(e.idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
121  float4 data[BVH_NODE_LEAF_SIZE];
122  memset(data, 0, sizeof(data));
123  if (leaf->num_triangles() == 1 && pack.prim_index[leaf->lo] == -1) {
124  /* object */
125  data[0].x = __int_as_float(~(leaf->lo));
126  data[0].y = __int_as_float(0);
127  }
128  else {
129  /* triangle */
130  data[0].x = __int_as_float(leaf->lo);
131  data[0].y = __int_as_float(leaf->hi);
132  }
133  data[0].z = __uint_as_float(leaf->visibility);
134  if (leaf->num_triangles() != 0) {
135  data[0].w = __uint_as_float(pack.prim_type[leaf->lo]);
136  }
137 
138  memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4) * BVH_NODE_LEAF_SIZE);
139 }
140 
141 void BVH2::pack_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
142 {
143  if (e0.node->is_unaligned || e1.node->is_unaligned) {
144  pack_unaligned_inner(e, e0, e1);
145  }
146  else {
147  pack_aligned_inner(e, e0, e1);
148  }
149 }
150 
152  const BVHStackEntry &e0,
153  const BVHStackEntry &e1)
154 {
155  pack_aligned_node(e.idx,
156  e0.node->bounds,
157  e1.node->bounds,
158  e0.encodeIdx(),
159  e1.encodeIdx(),
160  e0.node->visibility,
161  e1.node->visibility);
162 }
163 
165  const BoundBox &b0,
166  const BoundBox &b1,
167  int c0,
168  int c1,
169  uint visibility0,
170  uint visibility1)
171 {
172  assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
173  assert(c0 < 0 || c0 < pack.nodes.size());
174  assert(c1 < 0 || c1 < pack.nodes.size());
175 
176  int4 data[BVH_NODE_SIZE] = {
177  make_int4(
178  visibility0 & ~PATH_RAY_NODE_UNALIGNED, visibility1 & ~PATH_RAY_NODE_UNALIGNED, c0, c1),
180  __float_as_int(b1.min.x),
181  __float_as_int(b0.max.x),
182  __float_as_int(b1.max.x)),
184  __float_as_int(b1.min.y),
185  __float_as_int(b0.max.y),
186  __float_as_int(b1.max.y)),
188  __float_as_int(b1.min.z),
189  __float_as_int(b0.max.z),
190  __float_as_int(b1.max.z)),
191  };
192 
193  memcpy(&pack.nodes[idx], data, sizeof(int4) * BVH_NODE_SIZE);
194 }
195 
197  const BVHStackEntry &e0,
198  const BVHStackEntry &e1)
199 {
201  e0.node->get_aligned_space(),
202  e1.node->get_aligned_space(),
203  e0.node->bounds,
204  e1.node->bounds,
205  e0.encodeIdx(),
206  e1.encodeIdx(),
207  e0.node->visibility,
208  e1.node->visibility);
209 }
210 
212  const Transform &aligned_space0,
213  const Transform &aligned_space1,
214  const BoundBox &bounds0,
215  const BoundBox &bounds1,
216  int c0,
217  int c1,
218  uint visibility0,
219  uint visibility1)
220 {
221  assert(idx + BVH_UNALIGNED_NODE_SIZE <= pack.nodes.size());
222  assert(c0 < 0 || c0 < pack.nodes.size());
223  assert(c1 < 0 || c1 < pack.nodes.size());
224 
226  Transform space0 = BVHUnaligned::compute_node_transform(bounds0, aligned_space0);
227  Transform space1 = BVHUnaligned::compute_node_transform(bounds1, aligned_space1);
230  __int_as_float(c0),
231  __int_as_float(c1));
232 
233  data[1] = space0.x;
234  data[2] = space0.y;
235  data[3] = space0.z;
236  data[4] = space1.x;
237  data[5] = space1.y;
238  data[6] = space1.z;
239 
240  memcpy(&pack.nodes[idx], data, sizeof(float4) * BVH_UNALIGNED_NODE_SIZE);
241 }
242 
243 void BVH2::pack_nodes(const BVHNode *root)
244 {
245  const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
246  const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
247  assert(num_leaf_nodes <= num_nodes);
248  const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
249  size_t node_size;
251  const size_t num_unaligned_nodes = root->getSubtreeSize(BVH_STAT_UNALIGNED_INNER_COUNT);
252  node_size = (num_unaligned_nodes * BVH_UNALIGNED_NODE_SIZE) +
253  (num_inner_nodes - num_unaligned_nodes) * BVH_NODE_SIZE;
254  }
255  else {
256  node_size = num_inner_nodes * BVH_NODE_SIZE;
257  }
258  /* Resize arrays */
259  pack.nodes.clear();
261  /* For top level BVH, first merge existing BVH's so we know the offsets. */
262  if (params.top_level) {
263  pack_instances(node_size, num_leaf_nodes * BVH_NODE_LEAF_SIZE);
264  }
265  else {
266  pack.nodes.resize(node_size);
267  pack.leaf_nodes.resize(num_leaf_nodes * BVH_NODE_LEAF_SIZE);
268  }
269 
270  int nextNodeIdx = 0, nextLeafNodeIdx = 0;
271 
272  vector<BVHStackEntry> stack;
273  stack.reserve(BVHParams::MAX_DEPTH * 2);
274  if (root->is_leaf()) {
275  stack.push_back(BVHStackEntry(root, nextLeafNodeIdx++));
276  }
277  else {
278  stack.push_back(BVHStackEntry(root, nextNodeIdx));
279  nextNodeIdx += root->has_unaligned() ? BVH_UNALIGNED_NODE_SIZE : BVH_NODE_SIZE;
280  }
281 
282  while (stack.size()) {
283  BVHStackEntry e = stack.back();
284  stack.pop_back();
285 
286  if (e.node->is_leaf()) {
287  /* leaf node */
288  const LeafNode *leaf = reinterpret_cast<const LeafNode *>(e.node);
289  pack_leaf(e, leaf);
290  }
291  else {
292  /* inner node */
293  int idx[2];
294  for (int i = 0; i < 2; ++i) {
295  if (e.node->get_child(i)->is_leaf()) {
296  idx[i] = nextLeafNodeIdx++;
297  }
298  else {
299  idx[i] = nextNodeIdx;
300  nextNodeIdx += e.node->get_child(i)->has_unaligned() ? BVH_UNALIGNED_NODE_SIZE :
302  }
303  }
304 
305  stack.push_back(BVHStackEntry(e.node->get_child(0), idx[0]));
306  stack.push_back(BVHStackEntry(e.node->get_child(1), idx[1]));
307 
308  pack_inner(e, stack[stack.size() - 2], stack[stack.size() - 1]);
309  }
310  }
311  assert(node_size == nextNodeIdx);
312  /* root index to start traversal at, to handle case of single leaf node */
313  pack.root_index = (root->is_leaf()) ? -1 : 0;
314 }
315 
317 {
318  assert(!params.top_level);
319 
320  BoundBox bbox = BoundBox::empty;
321  uint visibility = 0;
322  refit_node(0, (pack.root_index == -1) ? true : false, bbox, visibility);
323 }
324 
325 void BVH2::refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
326 {
327  if (leaf) {
328  /* refit leaf node */
329  assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
330  const int4 *data = &pack.leaf_nodes[idx];
331  const int c0 = data[0].x;
332  const int c1 = data[0].y;
333 
334  refit_primitives(c0, c1, bbox, visibility);
335 
336  /* TODO(sergey): De-duplicate with pack_leaf(). */
337  float4 leaf_data[BVH_NODE_LEAF_SIZE];
338  leaf_data[0].x = __int_as_float(c0);
339  leaf_data[0].y = __int_as_float(c1);
340  leaf_data[0].z = __uint_as_float(visibility);
341  leaf_data[0].w = __uint_as_float(data[0].w);
342  memcpy(&pack.leaf_nodes[idx], leaf_data, sizeof(float4) * BVH_NODE_LEAF_SIZE);
343  }
344  else {
345  assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
346 
347  const int4 *data = &pack.nodes[idx];
348  const bool is_unaligned = (data[0].x & PATH_RAY_NODE_UNALIGNED) != 0;
349  const int c0 = data[0].z;
350  const int c1 = data[0].w;
351  /* refit inner node, set bbox from children */
352  BoundBox bbox0 = BoundBox::empty, bbox1 = BoundBox::empty;
353  uint visibility0 = 0, visibility1 = 0;
354 
355  refit_node((c0 < 0) ? -c0 - 1 : c0, (c0 < 0), bbox0, visibility0);
356  refit_node((c1 < 0) ? -c1 - 1 : c1, (c1 < 0), bbox1, visibility1);
357 
358  if (is_unaligned) {
359  Transform aligned_space = transform_identity();
361  idx, aligned_space, aligned_space, bbox0, bbox1, c0, c1, visibility0, visibility1);
362  }
363  else {
364  pack_aligned_node(idx, bbox0, bbox1, c0, c1, visibility0, visibility1);
365  }
366 
367  bbox.grow(bbox0);
368  bbox.grow(bbox1);
369  visibility = visibility0 | visibility1;
370  }
371 }
372 
373 /* Refitting */
374 
375 void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility)
376 {
377  /* Refit range of primitives. */
378  for (int prim = start; prim < end; prim++) {
379  int pidx = pack.prim_index[prim];
380  int tob = pack.prim_object[prim];
381  Object *ob = objects[tob];
382 
383  if (pidx == -1) {
384  /* Object instance. */
385  bbox.grow(ob->bounds);
386  }
387  else {
388  /* Primitives. */
389  if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) {
390  /* Curves. */
391  const Hair *hair = static_cast<const Hair *>(ob->get_geometry());
392  int prim_offset = (params.top_level) ? hair->prim_offset : 0;
393  Hair::Curve curve = hair->get_curve(pidx - prim_offset);
394  int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
395 
396  curve.bounds_grow(k, &hair->get_curve_keys()[0], &hair->get_curve_radius()[0], bbox);
397 
398  /* Motion curves. */
399  if (hair->get_use_motion_blur()) {
401 
402  if (attr) {
403  size_t hair_size = hair->get_curve_keys().size();
404  size_t steps = hair->get_motion_steps() - 1;
405  float3 *key_steps = attr->data_float3();
406 
407  for (size_t i = 0; i < steps; i++)
408  curve.bounds_grow(k, key_steps + i * hair_size, &hair->get_curve_radius()[0], bbox);
409  }
410  }
411  }
412  else {
413  /* Triangles. */
414  const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry());
415  int prim_offset = (params.top_level) ? mesh->prim_offset : 0;
416  Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset);
417  const float3 *vpos = &mesh->verts[0];
418 
419  triangle.bounds_grow(vpos, bbox);
420 
421  /* Motion triangles. */
422  if (mesh->use_motion_blur) {
424 
425  if (attr) {
426  size_t mesh_size = mesh->verts.size();
427  size_t steps = mesh->motion_steps - 1;
428  float3 *vert_steps = attr->data_float3();
429 
430  for (size_t i = 0; i < steps; i++)
431  triangle.bounds_grow(vert_steps + i * mesh_size, bbox);
432  }
433  }
434  }
435  }
436  visibility |= ob->visibility_for_tracing();
437  }
438 }
439 
440 /* Triangles */
441 
442 void BVH2::pack_triangle(int idx, float4 tri_verts[3])
443 {
444  int tob = pack.prim_object[idx];
445  assert(tob >= 0 && tob < objects.size());
446  const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->get_geometry());
447 
448  int tidx = pack.prim_index[idx];
450  const float3 *vpos = &mesh->verts[0];
451  float3 v0 = vpos[t.v[0]];
452  float3 v1 = vpos[t.v[1]];
453  float3 v2 = vpos[t.v[2]];
454 
455  tri_verts[0] = float3_to_float4(v0);
456  tri_verts[1] = float3_to_float4(v1);
457  tri_verts[2] = float3_to_float4(v2);
458 }
459 
461 {
462  const size_t tidx_size = pack.prim_index.size();
463  size_t num_prim_triangles = 0;
464  /* Count number of triangles primitives in BVH. */
465  for (unsigned int i = 0; i < tidx_size; i++) {
466  if ((pack.prim_index[i] != -1)) {
467  if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
468  ++num_prim_triangles;
469  }
470  }
471  }
472  /* Reserve size for arrays. */
474  pack.prim_tri_index.resize(tidx_size);
476  pack.prim_tri_verts.resize(num_prim_triangles * 3);
478  pack.prim_visibility.resize(tidx_size);
479  /* Fill in all the arrays. */
480  size_t prim_triangle_index = 0;
481  for (unsigned int i = 0; i < tidx_size; i++) {
482  if (pack.prim_index[i] != -1) {
483  int tob = pack.prim_object[i];
484  Object *ob = objects[tob];
485  if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
486  pack_triangle(i, (float4 *)&pack.prim_tri_verts[3 * prim_triangle_index]);
487  pack.prim_tri_index[i] = 3 * prim_triangle_index;
488  ++prim_triangle_index;
489  }
490  else {
491  pack.prim_tri_index[i] = -1;
492  }
494  }
495  else {
496  pack.prim_tri_index[i] = -1;
497  pack.prim_visibility[i] = 0;
498  }
499  }
500 }
501 
502 /* Pack Instances */
503 
504 void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
505 {
506  /* Adjust primitive index to point to the triangle in the global array, for
507  * geometry with transform applied and already in the top level BVH.
508  */
509  for (size_t i = 0; i < pack.prim_index.size(); i++) {
510  if (pack.prim_index[i] != -1) {
511  pack.prim_index[i] += objects[pack.prim_object[i]]->get_geometry()->prim_offset;
512  }
513  }
514 
515  /* track offsets of instanced BVH data in global array */
516  size_t prim_offset = pack.prim_index.size();
517  size_t nodes_offset = nodes_size;
518  size_t nodes_leaf_offset = leaf_nodes_size;
519 
520  /* clear array that gives the node indexes for instanced objects */
522 
523  /* reserve */
524  size_t prim_index_size = pack.prim_index.size();
525  size_t prim_tri_verts_size = pack.prim_tri_verts.size();
526 
527  size_t pack_prim_index_offset = prim_index_size;
528  size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
529  size_t pack_nodes_offset = nodes_size;
530  size_t pack_leaf_nodes_offset = leaf_nodes_size;
531  size_t object_offset = 0;
532 
533  foreach (Geometry *geom, geometry) {
534  BVH2 *bvh = static_cast<BVH2 *>(geom->bvh);
535 
536  if (geom->need_build_bvh(params.bvh_layout)) {
537  prim_index_size += bvh->pack.prim_index.size();
538  prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
539  nodes_size += bvh->pack.nodes.size();
540  leaf_nodes_size += bvh->pack.leaf_nodes.size();
541  }
542  }
543 
544  pack.prim_index.resize(prim_index_size);
545  pack.prim_type.resize(prim_index_size);
546  pack.prim_object.resize(prim_index_size);
547  pack.prim_visibility.resize(prim_index_size);
548  pack.prim_tri_verts.resize(prim_tri_verts_size);
549  pack.prim_tri_index.resize(prim_index_size);
550  pack.nodes.resize(nodes_size);
551  pack.leaf_nodes.resize(leaf_nodes_size);
552  pack.object_node.resize(objects.size());
553 
555  pack.prim_time.resize(prim_index_size);
556  }
557 
558  int *pack_prim_index = (pack.prim_index.size()) ? &pack.prim_index[0] : NULL;
559  int *pack_prim_type = (pack.prim_type.size()) ? &pack.prim_type[0] : NULL;
560  int *pack_prim_object = (pack.prim_object.size()) ? &pack.prim_object[0] : NULL;
561  uint *pack_prim_visibility = (pack.prim_visibility.size()) ? &pack.prim_visibility[0] : NULL;
562  float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size()) ? &pack.prim_tri_verts[0] : NULL;
563  uint *pack_prim_tri_index = (pack.prim_tri_index.size()) ? &pack.prim_tri_index[0] : NULL;
564  int4 *pack_nodes = (pack.nodes.size()) ? &pack.nodes[0] : NULL;
565  int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL;
566  float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL;
567 
568  unordered_map<Geometry *, int> geometry_map;
569 
570  /* merge */
571  foreach (Object *ob, objects) {
572  Geometry *geom = ob->get_geometry();
573 
574  /* We assume that if mesh doesn't need own BVH it was already included
575  * into a top-level BVH and no packing here is needed.
576  */
577  if (!geom->need_build_bvh(params.bvh_layout)) {
578  pack.object_node[object_offset++] = 0;
579  continue;
580  }
581 
582  /* if mesh already added once, don't add it again, but used set
583  * node offset for this object */
584  unordered_map<Geometry *, int>::iterator it = geometry_map.find(geom);
585 
586  if (geometry_map.find(geom) != geometry_map.end()) {
587  int noffset = it->second;
588  pack.object_node[object_offset++] = noffset;
589  continue;
590  }
591 
592  BVH2 *bvh = static_cast<BVH2 *>(geom->bvh);
593 
594  int noffset = nodes_offset;
595  int noffset_leaf = nodes_leaf_offset;
596  int geom_prim_offset = geom->prim_offset;
597 
598  /* fill in node indexes for instances */
599  if (bvh->pack.root_index == -1)
600  pack.object_node[object_offset++] = -noffset_leaf - 1;
601  else
602  pack.object_node[object_offset++] = noffset;
603 
604  geometry_map[geom] = pack.object_node[object_offset - 1];
605 
606  /* merge primitive, object and triangle indexes */
607  if (bvh->pack.prim_index.size()) {
608  size_t bvh_prim_index_size = bvh->pack.prim_index.size();
609  int *bvh_prim_index = &bvh->pack.prim_index[0];
610  int *bvh_prim_type = &bvh->pack.prim_type[0];
611  uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
612  uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
613  float2 *bvh_prim_time = bvh->pack.prim_time.size() ? &bvh->pack.prim_time[0] : NULL;
614 
615  for (size_t i = 0; i < bvh_prim_index_size; i++) {
616  if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
617  pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
618  pack_prim_tri_index[pack_prim_index_offset] = -1;
619  }
620  else {
621  pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
622  pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] +
623  pack_prim_tri_verts_offset;
624  }
625 
626  pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
627  pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
628  pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
629  if (bvh_prim_time != NULL) {
630  pack_prim_time[pack_prim_index_offset] = bvh_prim_time[i];
631  }
632  pack_prim_index_offset++;
633  }
634  }
635 
636  /* Merge triangle vertices data. */
637  if (bvh->pack.prim_tri_verts.size()) {
638  const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
639  memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
640  &bvh->pack.prim_tri_verts[0],
641  prim_tri_size * sizeof(float4));
642  pack_prim_tri_verts_offset += prim_tri_size;
643  }
644 
645  /* merge nodes */
646  if (bvh->pack.leaf_nodes.size()) {
647  int4 *leaf_nodes_offset = &bvh->pack.leaf_nodes[0];
648  size_t leaf_nodes_offset_size = bvh->pack.leaf_nodes.size();
649  for (size_t i = 0, j = 0; i < leaf_nodes_offset_size; i += BVH_NODE_LEAF_SIZE, j++) {
650  int4 data = leaf_nodes_offset[i];
651  data.x += prim_offset;
652  data.y += prim_offset;
653  pack_leaf_nodes[pack_leaf_nodes_offset] = data;
654  for (int j = 1; j < BVH_NODE_LEAF_SIZE; ++j) {
655  pack_leaf_nodes[pack_leaf_nodes_offset + j] = leaf_nodes_offset[i + j];
656  }
657  pack_leaf_nodes_offset += BVH_NODE_LEAF_SIZE;
658  }
659  }
660 
661  if (bvh->pack.nodes.size()) {
662  int4 *bvh_nodes = &bvh->pack.nodes[0];
663  size_t bvh_nodes_size = bvh->pack.nodes.size();
664 
665  for (size_t i = 0, j = 0; i < bvh_nodes_size; j++) {
666  size_t nsize, nsize_bbox;
667  if (bvh_nodes[i].x & PATH_RAY_NODE_UNALIGNED) {
668  nsize = BVH_UNALIGNED_NODE_SIZE;
669  nsize_bbox = 0;
670  }
671  else {
672  nsize = BVH_NODE_SIZE;
673  nsize_bbox = 0;
674  }
675 
676  memcpy(pack_nodes + pack_nodes_offset, bvh_nodes + i, nsize_bbox * sizeof(int4));
677 
678  /* Modify offsets into arrays */
679  int4 data = bvh_nodes[i + nsize_bbox];
680  data.z += (data.z < 0) ? -noffset_leaf : noffset;
681  data.w += (data.w < 0) ? -noffset_leaf : noffset;
682  pack_nodes[pack_nodes_offset + nsize_bbox] = data;
683 
684  /* Usually this copies nothing, but we better
685  * be prepared for possible node size extension.
686  */
687  memcpy(&pack_nodes[pack_nodes_offset + nsize_bbox + 1],
688  &bvh_nodes[i + nsize_bbox + 1],
689  sizeof(int4) * (nsize - (nsize_bbox + 1)));
690 
691  pack_nodes_offset += nsize;
692  i += nsize;
693  }
694  }
695 
696  nodes_offset += bvh->pack.nodes.size();
697  nodes_leaf_offset += bvh->pack.leaf_nodes.size();
698  prim_offset += bvh->pack.prim_index.size();
699  }
700 }
701 
unsigned int uint
Definition: BLI_sys_types.h:83
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
ATTR_WARN_UNUSED_RESULT const BMVert * v2
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:29
#define BVH_NODE_LEAF_SIZE
Definition: bvh2.h:30
#define BVH_UNALIGNED_NODE_SIZE
Definition: bvh2.h:31
@ BVH_STAT_NODE_COUNT
Definition: bvh_node.h:27
@ BVH_STAT_UNALIGNED_INNER_COUNT
Definition: bvh_node.h:35
@ BVH_STAT_LEAF_COUNT
Definition: bvh_node.h:29
Attribute * find(ustring name) const
Definition: attribute.cpp:447
float3 * data_float3()
Definition: attribute.h:86
Definition: bvh2.h:46
void pack_instances(size_t nodes_size, size_t leaf_nodes_size)
Definition: bvh2.cpp:504
void pack_aligned_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
Definition: bvh2.cpp:151
void refit_node(int idx, bool leaf, BoundBox &bbox, uint &visibility)
Definition: bvh2.cpp:325
void pack_triangle(int idx, float4 storage[3])
Definition: bvh2.cpp:442
void pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
Definition: bvh2.cpp:118
void refit_primitives(int start, int end, BoundBox &bbox, uint &visibility)
Definition: bvh2.cpp:375
void pack_aligned_node(int idx, const BoundBox &b0, const BoundBox &b1, int c0, int c1, uint visibility0, uint visibility1)
Definition: bvh2.cpp:164
PackedBVH pack
Definition: bvh2.h:51
void pack_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
Definition: bvh2.cpp:141
virtual BVHNode * widen_children_nodes(const BVHNode *root)
Definition: bvh2.cpp:113
void pack_unaligned_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
Definition: bvh2.cpp:196
void pack_primitives()
Definition: bvh2.cpp:460
void pack_nodes(const BVHNode *root)
Definition: bvh2.cpp:243
void refit(Progress &progress)
Definition: bvh2.cpp:101
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:211
BVH2(const BVHParams &params, const vector< Geometry * > &geometry, const vector< Object * > &objects)
Definition: bvh2.cpp:42
void refit_nodes()
Definition: bvh2.cpp:316
void build(Progress &progress, Stats *stats)
Definition: bvh2.cpp:49
BVHNode * run()
Definition: bvh_build.cpp:370
int num_motion_triangle_steps
Definition: bvh_params.h:86
BVHLayout bvh_layout
Definition: bvh_params.h:70
bool use_unaligned_nodes
Definition: bvh_params.h:75
bool top_level
Definition: bvh_params.h:67
int num_motion_curve_steps
Definition: bvh_params.h:83
static Transform compute_node_transform(const BoundBox &bounds, const Transform &aligned_space)
Definition: bvh/bvh.h:80
vector< Geometry * > geometry
Definition: bvh/bvh.h:83
BVHParams params
Definition: bvh/bvh.h:82
vector< Object * > objects
Definition: bvh/bvh.h:84
BVH * bvh
Definition: geometry.h:100
bool need_build_bvh(BVHLayout layout) const
Definition: geometry.cpp:171
size_t prim_offset
Definition: geometry.h:102
AttributeSet attributes
Definition: geometry.h:81
int num_triangles() const
Definition: bvh_node.h:243
int hi
Definition: bvh_node.h:250
int lo
Definition: bvh_node.h:249
bool get_cancel()
void set_substatus(const string &substatus_)
size_t size() const
Definition: util_array.h:203
T * resize(size_t newsize)
Definition: util_array.h:150
void clear()
Definition: util_array.h:188
OperationNode * node
Curve curve
#define CCL_NAMESPACE_END
#define make_int4(x, y, z, w)
#define make_float4(x, y, z, w)
@ PRIMITIVE_ALL_TRIANGLE
Definition: kernel_types.h:697
@ PRIMITIVE_ALL_CURVE
Definition: kernel_types.h:698
@ ATTR_STD_MOTION_VERTEX_POSITION
Definition: kernel_types.h:756
#define PRIMITIVE_UNPACK_SEGMENT(type)
Definition: kernel_types.h:711
@ PATH_RAY_NODE_UNALIGNED
Definition: kernel_types.h:293
static const int steps
Definition: sky_nishita.cpp:28
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const
Definition: bvh_node.cpp:29
uint visibility
Definition: bvh_node.h:104
bool is_unaligned
Definition: bvh_node.h:106
virtual bool is_leaf() const =0
void deleteSubtree()
Definition: bvh_node.cpp:105
bool has_unaligned() const
Definition: bvh_node.h:78
Transform get_aligned_space() const
Definition: bvh_node.h:70
BoundBox bounds
Definition: bvh_node.h:103
const BVHNode * node
Definition: bvh2.h:35
BVHStackEntry(const BVHNode *n=0, int i=0)
Definition: bvh2.cpp:33
int idx
Definition: bvh2.h:36
int encodeIdx() const
Definition: bvh2.cpp:37
float3 max
Definition: util_boundbox.h:34
__forceinline void grow(const float3 &pt)
Definition: util_boundbox.h:55
float3 min
Definition: util_boundbox.h:34
Curve get_curve(size_t i) const
Definition: hair.h:119
float size[3]
Triangle get_triangle(size_t i) const
Definition: mesh.h:86
NODE_DECLARE BoundBox bounds
Definition: object.h:56
uint visibility_for_tracing() const
Definition: object.cpp:271
array< int > prim_index
Definition: bvh/bvh.h:63
array< int > prim_type
Definition: bvh/bvh.h:58
array< int4 > nodes
Definition: bvh/bvh.h:48
array< uint > prim_visibility
Definition: bvh/bvh.h:60
array< float4 > prim_tri_verts
Definition: bvh/bvh.h:56
array< float2 > prim_time
Definition: bvh/bvh.h:67
array< int4 > leaf_nodes
Definition: bvh/bvh.h:50
array< uint > prim_tri_index
Definition: bvh/bvh.h:54
array< int > prim_object
Definition: bvh/bvh.h:65
int root_index
Definition: bvh/bvh.h:70
array< int > object_node
Definition: bvh/bvh.h:52
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
#define foreach(x, y)
Definition: util_foreach.h:22
ccl_device_inline float __uint_as_float(uint i)
Definition: util_math.h:232
ccl_device_inline int __float_as_int(float f)
Definition: util_math.h:202
ccl_device_inline float4 float3_to_float4(const float3 a)
Definition: util_math.h:420
ccl_device_inline float __int_as_float(int i)
Definition: util_math.h:212
ccl_device_inline Transform transform_identity()