35 :
BVH(params_, geometry_, objects_)
93 return std::move(root);
223 assert(num_leaf_nodes <= num_nodes);
224 const size_t num_inner_nodes = num_nodes - num_leaf_nodes;
226 if (
params.use_unaligned_nodes) {
236 pack.leaf_nodes.clear();
242 pack.nodes.resize(node_size);
247 int nextLeafNodeIdx = 0;
259 while (!stack.empty()) {
263 if (
e.node->is_leaf()) {
271 for (
int i = 0;
i < 2; ++
i) {
272 if (
e.node->get_child(
i)->is_leaf()) {
273 idx[
i] = nextLeafNodeIdx++;
276 idx[
i] = nextNodeIdx;
285 pack_inner(
e, stack[stack.size() - 2], stack[stack.size() - 1]);
288 assert(node_size == nextNodeIdx);
299 refit_node(0, (
pack.root_index == -1) ?
true :
false, bbox, visibility);
308 const int c0 =
data[0].x;
309 const int c1 =
data[0].y;
317 leaf_data[0].
z = visibility;
318 leaf_data[0].
w =
data[0].w;
326 const int c0 =
data[0].z;
327 const int c1 =
data[0].w;
331 uint visibility0 = 0;
332 uint visibility1 = 0;
334 refit_node((c0 < 0) ? -c0 - 1 : c0, (c0 < 0), bbox0, visibility0);
335 refit_node((c1 < 0) ? -c1 - 1 : c1, (c1 < 0), bbox1, visibility1);
340 idx, aligned_space, aligned_space, bbox0, bbox1, c0, c1, visibility0, visibility1);
348 visibility = visibility0 | visibility1;
357 for (
int prim = start; prim < end; prim++) {
358 const int pidx =
pack.prim_index[prim];
359 const int tob =
pack.prim_object[prim];
370 const Hair *hair =
static_cast<const Hair *
>(ob->get_geometry());
375 curve.
bounds_grow(k, hair->get_curve_keys().data(), hair->get_curve_radius().data(), bbox);
378 if (hair->get_use_motion_blur()) {
382 const size_t hair_size = hair->get_curve_keys().size();
383 const size_t steps = hair->get_motion_steps() - 1;
386 for (
size_t i = 0;
i < steps;
i++) {
388 k, key_steps +
i * hair_size, hair->get_curve_radius().data(), bbox);
397 const float3 *points = pointcloud->points.data();
398 const float *radius = pointcloud->radius.data();
404 if (pointcloud->get_use_motion_blur()) {
408 const size_t pointcloud_size = pointcloud->points.size();
409 const size_t steps = pointcloud->get_motion_steps() - 1;
412 for (
size_t i = 0;
i < steps;
i++) {
413 point.
bounds_grow(point_steps +
i * pointcloud_size, radius, bbox);
420 const Mesh *mesh =
static_cast<const Mesh *
>(ob->get_geometry());
423 const float3 *vpos = mesh->verts.data();
428 if (mesh->use_motion_blur) {
432 const size_t mesh_size = mesh->verts.size();
433 const size_t steps = mesh->motion_steps - 1;
436 for (
size_t i = 0;
i < steps;
i++) {
451 const size_t tidx_size =
pack.prim_index.size();
453 pack.prim_visibility.clear();
454 pack.prim_visibility.resize(tidx_size);
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];
463 pack.prim_visibility[
i] = 0;
475 for (
size_t i = 0;
i <
pack.prim_index.size();
i++) {
476 if (
pack.prim_index[
i] != -1) {
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;
487 pack.object_node.clear();
490 size_t prim_index_size =
pack.prim_index.size();
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;
498 BVH2 *bvh =
static_cast<BVH2 *
>(geom->bvh.get());
500 if (geom->need_build_bvh(
params.bvh_layout)) {
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);
515 if (
params.num_motion_curve_steps > 0 ||
params.num_motion_triangle_steps > 0 ||
516 params.num_motion_point_steps > 0)
518 pack.prim_time.resize(prim_index_size);
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() :
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;
530 unordered_map<Geometry *, int> geometry_map;
534 Geometry *geom = ob->get_geometry();
540 pack.object_node[object_offset++] = 0;
546 const unordered_map<Geometry *, int>::iterator it = geometry_map.find(geom);
548 if (geometry_map.find(geom) != geometry_map.end()) {
549 const int noffset = it->second;
550 pack.object_node[object_offset++] = noffset;
556 const int noffset = nodes_offset;
557 const int noffset_leaf = nodes_leaf_offset;
562 pack.object_node[object_offset++] = -noffset_leaf - 1;
565 pack.object_node[object_offset++] = noffset;
568 geometry_map[geom] =
pack.object_node[object_offset - 1];
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;
583 if (bvh_prim_time !=
nullptr) {
584 pack_prim_time[pack_prim_index_offset] = bvh_prim_time[
i];
586 pack_prim_index_offset++;
596 data.x += prim_offset;
597 data.y += prim_offset;
598 pack_leaf_nodes[pack_leaf_nodes_offset] =
data;
600 pack_leaf_nodes[pack_leaf_nodes_offset + j] = leaf_nodes_offset[
i + j];
610 for (
size_t i = 0;
i < bvh_nodes_size;) {
622 std::copy_n(bvh_nodes +
i, nsize_bbox,
pack_nodes + pack_nodes_offset);
626 data.z += (
data.z < 0) ? -noffset_leaf : noffset;
627 data.w += (
data.w < 0) ? -noffset_leaf : noffset;
633 std::copy_n(&bvh_nodes[
i + nsize_bbox + 1],
634 (nsize - (nsize_bbox + 1)),
635 &
pack_nodes[pack_nodes_offset + nsize_bbox + 1]);
637 pack_nodes_offset += nsize;
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
#define BVH_NODE_LEAF_SIZE
#define BVH_UNALIGNED_NODE_SIZE
@ BVH_STAT_UNALIGNED_INNER_COUNT
Attribute * find(ustring name) const
void pack_aligned_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
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)
void refit_node(const int idx, bool leaf, BoundBox &bbox, uint &visibility)
virtual unique_ptr< BVHNode > widen_children_nodes(unique_ptr< BVHNode > &&root)
void pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
void pack_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
void refit_primitives(const int start, const int end, BoundBox &bbox, uint &visibility)
void pack_instances(const size_t nodes_size, const size_t leaf_nodes_size)
void pack_aligned_node(const int idx, const BoundBox &b0, const BoundBox &b1, int c0, int c1, uint visibility0, uint visibility1)
void pack_unaligned_inner(const BVHStackEntry &e, const BVHStackEntry &e0, const BVHStackEntry &e1)
void pack_nodes(const BVHNode *root)
void refit(Progress &progress)
BVH2(const BVHParams ¶ms, const vector< Geometry * > &geometry, const vector< Object * > &objects)
void build(Progress &progress, Stats *stats)
unique_ptr< BVHNode > run()
static Transform compute_node_transform(const BoundBox &bounds, const Transform &aligned_space)
vector< Geometry * > geometry
BVH(const BVHParams ¶ms, const vector< Geometry * > &geometry, const vector< Object * > &objects)
vector< Object * > objects
bool need_build_bvh(BVHLayout layout) const
Curve get_curve(const size_t i) const
int num_triangles() const override
void set_substatus(const string &substatus_)
#define PRIMITIVE_UNPACK_SEGMENT(type)
#define CCL_NAMESPACE_END
#define assert(assertion)
@ ATTR_STD_MOTION_VERTEX_POSITION
@ PATH_RAY_NODE_UNALIGNED
ccl_device_inline int4 __float4_as_int4(const float4 f)
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const
virtual bool is_leaf() const =0
bool has_unaligned() const
Transform get_aligned_space() const
BVHStackEntry(const BVHNode *n=nullptr, const int i=0)
__forceinline void grow(const float3 &pt)
void bounds_grow(const int k, const float3 *curve_keys, const float *curve_radius, BoundBox &bounds) const
void bounds_grow(const float3 *verts, BoundBox &bounds) const
Triangle get_triangle(const size_t i) const
NODE_DECLARE BoundBox bounds
uint visibility_for_tracing() const
array< uint > prim_visibility
array< float2 > prim_time
void bounds_grow(const float3 *points, const float *radius, BoundBox &bounds) const
Point get_point(const int i) const
ccl_device_inline int4 zero_int4()