diff options
Diffstat (limited to 'intern/cycles/bvh')
-rw-r--r-- | intern/cycles/bvh/bvh.cpp | 43 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh.h | 6 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_build.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_node.h | 5 |
4 files changed, 45 insertions, 18 deletions
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 664bdd98b1f..9bd748157bf 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -84,6 +84,7 @@ bool BVH::cache_read(CacheData& key) value.read(pack.nodes); value.read(pack.object_node); value.read(pack.tri_woop); + value.read(pack.prim_visibility); value.read(pack.prim_index); value.read(pack.prim_object); value.read(pack.is_leaf); @@ -103,6 +104,7 @@ void BVH::cache_write(CacheData& key) value.add(pack.nodes); value.add(pack.object_node); value.add(pack.tri_woop); + value.add(pack.prim_visibility); value.add(pack.prim_index); value.add(pack.prim_object); value.add(pack.is_leaf); @@ -236,6 +238,8 @@ void BVH::pack_triangles() pack.tri_woop.clear(); pack.tri_woop.resize(tidx_size * nsize); + pack.prim_visibility.clear(); + pack.prim_visibility.resize(tidx_size); for(unsigned int i = 0; i < tidx_size; i++) { if(pack.prim_index[i] != -1) { @@ -243,6 +247,10 @@ void BVH::pack_triangles() pack_triangle(i, woop); memcpy(&pack.tri_woop[i * nsize], woop, sizeof(float4)*3); + + int tob = pack.prim_object[i]; + Object *ob = objects[tob]; + pack.prim_visibility[i] = ob->visibility; } } } @@ -292,12 +300,14 @@ void BVH::pack_instances(size_t nodes_size) pack.prim_index.resize(prim_index_size); pack.prim_object.resize(prim_index_size); + pack.prim_visibility.resize(prim_index_size); pack.tri_woop.resize(tri_woop_size); pack.nodes.resize(nodes_size); pack.object_node.resize(objects.size()); int *pack_prim_index = &pack.prim_index[0]; int *pack_prim_object = &pack.prim_object[0]; + uint *pack_prim_visibility = &pack.prim_visibility[0]; float4 *pack_tri_woop = &pack.tri_woop[0]; int4 *pack_nodes = &pack.nodes[0]; @@ -327,9 +337,11 @@ void BVH::pack_instances(size_t nodes_size) { size_t bvh_prim_index_size = bvh->pack.prim_index.size(); int *bvh_prim_index = &bvh->pack.prim_index[0]; + uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0]; for(size_t i = 0; i < bvh_prim_index_size; i++) { pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + mesh_tri_offset; + pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i] + mesh_tri_offset; pack_prim_object[pack_prim_index_offset] = 0; // unused for instances pack_prim_index_offset++; } @@ -394,25 +406,25 @@ void RegularBVH::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf) { if(leaf->num_triangles() == 1 && pack.prim_index[leaf->m_lo] == -1) /* object */ - pack_node(e.idx, leaf->m_bounds, leaf->m_bounds, ~(leaf->m_lo), 0); + pack_node(e.idx, leaf->m_bounds, leaf->m_bounds, ~(leaf->m_lo), 0, leaf->m_visibility, leaf->m_visibility); else /* triangle */ - pack_node(e.idx, leaf->m_bounds, leaf->m_bounds, leaf->m_lo, leaf->m_hi); + pack_node(e.idx, leaf->m_bounds, leaf->m_bounds, leaf->m_lo, leaf->m_hi, leaf->m_visibility, leaf->m_visibility); } void RegularBVH::pack_inner(const BVHStackEntry& e, const BVHStackEntry& e0, const BVHStackEntry& e1) { - pack_node(e.idx, e0.node->m_bounds, e1.node->m_bounds, e0.encodeIdx(), e1.encodeIdx()); + pack_node(e.idx, e0.node->m_bounds, e1.node->m_bounds, e0.encodeIdx(), e1.encodeIdx(), e0.node->m_visibility, e1.node->m_visibility); } -void RegularBVH::pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int c0, int c1) +void RegularBVH::pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int c0, int c1, uint visibility0, uint visibility1) { int4 data[BVH_NODE_SIZE] = { make_int4(__float_as_int(b0.min.x), __float_as_int(b0.max.x), __float_as_int(b0.min.y), __float_as_int(b0.max.y)), make_int4(__float_as_int(b1.min.x), __float_as_int(b1.max.x), __float_as_int(b1.min.y), __float_as_int(b1.max.y)), make_int4(__float_as_int(b0.min.z), __float_as_int(b0.max.z), __float_as_int(b1.min.z), __float_as_int(b1.max.z)), - make_int4(c0, c1, 0, 0) + make_int4(c0, c1, visibility0, visibility1) }; memcpy(&pack.nodes[idx * BVH_NODE_SIZE], data, sizeof(int4)*BVH_NODE_SIZE); @@ -467,10 +479,11 @@ void RegularBVH::refit_nodes() assert(!params.top_level); BoundBox bbox; - refit_node(0, (pack.is_leaf[0])? true: false, bbox); + uint visibility = 0; + refit_node(0, (pack.is_leaf[0])? true: false, bbox, visibility); } -void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox) +void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility) { int4 *data = &pack.nodes[idx*4]; @@ -499,21 +512,25 @@ void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox) bbox.grow(vpos[vidx[1]]); bbox.grow(vpos[vidx[2]]); } + + visibility |= ob->visibility; } - pack_node(idx, bbox, bbox, c0, c1); + pack_node(idx, bbox, bbox, c0, c1, visibility, visibility); } else { /* refit inner node, set bbox from children */ BoundBox bbox0, bbox1; + uint visibility0 = 0, visibility1 = 0; - refit_node((c0 < 0)? -c0-1: c0, (c0 < 0), bbox0); - refit_node((c1 < 0)? -c1-1: c1, (c1 < 0), bbox1); + refit_node((c0 < 0)? -c0-1: c0, (c0 < 0), bbox0, visibility0); + refit_node((c1 < 0)? -c1-1: c1, (c1 < 0), bbox1, visibility1); + + pack_node(idx, bbox0, bbox1, c0, c1, visibility0, visibility1); bbox.grow(bbox0); bbox.grow(bbox1); - - pack_node(idx, bbox0, bbox1, c0, c1); + visibility = visibility0|visibility1; } } @@ -523,6 +540,8 @@ QBVH::QBVH(const BVHParams& params_, const vector<Object*>& objects_) : BVH(params_, objects_) { params.use_qbvh = true; + + /* todo: use visibility */ } void QBVH::pack_leaf(const BVHStackEntry& e, const LeafNode *leaf) diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h index 79e46d6a13c..e502af72335 100644 --- a/intern/cycles/bvh/bvh.h +++ b/intern/cycles/bvh/bvh.h @@ -51,6 +51,8 @@ struct PackedBVH { array<int> object_node; /* precomputed triangle intersection data, one triangle is 4x float4 */ array<float4> tri_woop; + /* visibility visibilitys for primitives */ + array<uint> prim_visibility; /* mapping from BVH primitive index to true primitive index, as primitives may be duplicated due to spatial splits. -1 for instances. */ array<int> prim_index; @@ -121,11 +123,11 @@ protected: void pack_nodes(const array<int>& prims, const BVHNode *root); void pack_leaf(const BVHStackEntry& e, const LeafNode *leaf); void pack_inner(const BVHStackEntry& e, const BVHStackEntry& e0, const BVHStackEntry& e1); - void pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int c0, int c1); + void pack_node(int idx, const BoundBox& b0, const BoundBox& b1, int c0, int c1, uint visibility0, uint visibility1); /* refit */ void refit_nodes(); - void refit_node(int idx, bool leaf, BoundBox& bbox); + void refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility); }; /* QBVH diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 3e47cb75014..d3e84e11d53 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -218,12 +218,13 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const Reference *ref, int num) { if(num == 0) { BoundBox bounds; - return new LeafNode(bounds, 0, 0); + return new LeafNode(bounds, 0, 0, 0); } else if(num == 1) { prim_index.push_back(ref[0].prim_index); prim_object.push_back(ref[0].prim_object); - return new LeafNode(ref[0].bounds, prim_index.size()-1, prim_index.size()); + uint visibility = objects[ref[0].prim_object]->visibility; + return new LeafNode(ref[0].bounds, visibility, prim_index.size()-1, prim_index.size()); } else { int mid = num/2; @@ -244,12 +245,14 @@ BVHNode* BVHBuild::create_leaf_node(const NodeSpec& spec) vector<int>& p_object = prim_object; BoundBox bounds; int num = 0; + uint visibility = 0; for(int i = 0; i < spec.num; i++) { if(references.back().prim_index != -1) { p_index.push_back(references.back().prim_index); p_object.push_back(references.back().prim_object); bounds.grow(references.back().bounds); + visibility |= objects[references.back().prim_object]->visibility; references.pop_back(); num++; } @@ -258,7 +261,7 @@ BVHNode* BVHBuild::create_leaf_node(const NodeSpec& spec) BVHNode *leaf = NULL; if(num > 0) { - leaf = new LeafNode(bounds, p_index.size() - num, p_index.size()); + leaf = new LeafNode(bounds, visibility, p_index.size() - num, p_index.size()); if(num == spec.num) return leaf; diff --git a/intern/cycles/bvh/bvh_node.h b/intern/cycles/bvh/bvh_node.h index f8f0ffecd95..5e0a17a1193 100644 --- a/intern/cycles/bvh/bvh_node.h +++ b/intern/cycles/bvh/bvh_node.h @@ -52,6 +52,7 @@ public: float getArea() const { return m_bounds.area(); } BoundBox m_bounds; + uint m_visibility; // Subtree functions int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const; @@ -65,6 +66,7 @@ public: InnerNode(const BoundBox& bounds, BVHNode* child0, BVHNode* child1) { m_bounds = bounds; + m_visibility = child0->m_visibility|child1->m_visibility; children[0] = child0; children[1] = child1; } @@ -80,9 +82,10 @@ public: class LeafNode : public BVHNode { public: - LeafNode(const BoundBox& bounds, int lo, int hi) + LeafNode(const BoundBox& bounds, uint visibility, int lo, int hi) { m_bounds = bounds; + m_visibility = visibility; m_lo = lo; m_hi = hi; } |