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