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,
44 pack.prim_type,
45 pack.prim_index,
46 pack.prim_object,
47 pack.prim_time,
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());
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
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
216 Transform space0 = BVHUnaligned::compute_node_transform(bounds0, aligned_space0);
217 Transform space1 = BVHUnaligned::compute_node_transform(bounds1, aligned_space1);
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;
240 if (params.use_unaligned_nodes) {
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();
250 pack.leaf_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);
384 int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]);
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()) {
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) {
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. */
463 pack.prim_visibility.clear();
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];
470 pack.prim_visibility[i] = ob->visibility_for_tracing();
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 */
497 pack.object_node.clear();
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
525 if (params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0 ||
526 params.num_motion_point_steps > 0)
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
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 Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture 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: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()
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
friend class BVH
Definition bvh2.h:45
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
@ MAX_DEPTH
Definition params.h:112
static Transform compute_node_transform(const BoundBox &bounds, const Transform &aligned_space)
vector< Geometry * > geometry
Definition bvh/bvh.h:69
BVHParams params
Definition bvh/bvh.h:68
vector< Object * > objects
Definition bvh/bvh.h:70
bool need_build_bvh(BVHLayout layout) const
size_t prim_offset
AttributeSet attributes
Definition hair.h:14
Curve get_curve(size_t i) const
Definition hair.h:112
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
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 int k, const float3 *curve_keys, const float *curve_radius, BoundBox &bounds) const
Definition hair.cpp:42
void bounds_grow(const float3 *verts, BoundBox &bounds) const
Triangle get_triangle(size_t i) const
Definition scene/mesh.h:74
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
int root_index
Definition bvh/bvh.h:56
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
VecBase< float, 4 > float4
ccl_device_inline Transform transform_identity()
Definition transform.h:296