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