[Bf-blender-cvs] [e4b2ae0fb62] soc-2019-embree-gpu: Add support for curve and unaligned nodes
MATILLAT Quentin
noreply at git.blender.org
Fri Aug 16 16:33:55 CEST 2019
Commit: e4b2ae0fb62addc6f1b34db934d1785f960833bf
Author: MATILLAT Quentin
Date: Fri Aug 16 16:31:12 2019 +0200
Branches: soc-2019-embree-gpu
https://developer.blender.org/rBe4b2ae0fb62addc6f1b34db934d1785f960833bf
Add support for curve and unaligned nodes
===================================================================
M intern/cycles/bvh/bvh_embree.cpp
M intern/cycles/bvh/bvh_embree_converter.cpp
M intern/cycles/bvh/bvh_embree_converter.h
===================================================================
diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp
index 6a1c2c90489..c3bc8dd3509 100644
--- a/intern/cycles/bvh/bvh_embree.cpp
+++ b/intern/cycles/bvh/bvh_embree.cpp
@@ -487,8 +487,8 @@ void BVHEmbree::build(Progress &progress, Stats *stats_)
progress.set_substatus("Packing geometry");
if(this->bvh_layout == BVH_LAYOUT_EMBREE_CONVERTED) {
- BVHEmbreeConverter conv(scene, objects, this->params);
- conv.fillPack(this->pack, this->objects);
+ BVHEmbreeConverter conv(this->scene, this->objects, this->params);
+ conv.fillPack(this->pack);
} else {
pack_primitives();
@@ -817,7 +817,7 @@ void BVHEmbree::add_curves(Object *ob, int i)
rtcReleaseGeometry(geom_id);
}
-void BVHEmbree::pack_nodes(const BVHNode *r)
+void BVHEmbree::pack_nodes(const BVHNode *)
{
/* Quite a bit of this code is for compatibility with Cycles' native BVH. */
if (!params.top_level) {
diff --git a/intern/cycles/bvh/bvh_embree_converter.cpp b/intern/cycles/bvh/bvh_embree_converter.cpp
index fe851b8074f..ed804f59adf 100644
--- a/intern/cycles/bvh/bvh_embree_converter.cpp
+++ b/intern/cycles/bvh/bvh_embree_converter.cpp
@@ -14,9 +14,6 @@
* limitations under the License.
*/
-/* This class implements a converter from Embree internal data structure to
- * Blender's internal structure
- */
#ifdef WITH_EMBREE
@@ -28,296 +25,355 @@
CCL_NAMESPACE_BEGIN
/* Utility functions */
+void packPush(PackedBVH *pack, const size_t packIdx,
+ const int object_id, const int prim_id,
+ const int prim_type, const uint visibility,
+ const uint tri_index)
+{
+ pack->prim_index.resize(packIdx + 1);
+ pack->prim_type.resize(packIdx + 1);
+ pack->prim_object.resize(packIdx + 1);
+ pack->prim_visibility.resize(packIdx + 1);
+ pack->prim_tri_index.resize(packIdx + 1);
+
+ pack->prim_index[packIdx] = prim_id;
+ pack->prim_type[packIdx] = prim_type;
+ pack->prim_object[packIdx] = object_id;
+ pack->prim_visibility[packIdx] = visibility;
+ pack->prim_tri_index[packIdx] = tri_index;
-void packPush(PackedBVH *pack, const size_t packIdx, const int object_id, const int prim_id, const int prim_type, const uint visibility, const uint tri_index) {
- pack->prim_index.resize(packIdx + 1);
- pack->prim_type.resize(packIdx + 1);
- pack->prim_object.resize(packIdx + 1);
- pack->prim_visibility.resize(packIdx + 1);
- pack->prim_tri_index.resize(packIdx + 1);
+}
- pack->prim_index[packIdx] = prim_id;
- pack->prim_type[packIdx] = prim_type;
- pack->prim_object[packIdx] = object_id;
- pack->prim_visibility[packIdx] = visibility;
- pack->prim_tri_index[packIdx] = tri_index;
+BoundBox RTCBoundBoxToCCL(const RTCBounds &bound)
+{
+ return BoundBox(make_float3(bound.lower_x, bound.lower_y, bound.lower_z),
+ make_float3(bound.upper_x, bound.upper_y, bound.upper_z));
}
-ccl::BoundBox RTCBoundBoxToCCL(const RTCBounds &bound) {
- return ccl::BoundBox(
- make_float3(bound.lower_x, bound.lower_y, bound.lower_z),
- make_float3(bound.upper_x, bound.upper_y, bound.upper_z));
+Transform transformSpaceFromBound(const BoundBox &bounds) {
+ Transform space = transform_identity();
-}
+ space.x.w -= bounds.min.x;
+ space.y.w -= bounds.min.y;
+ space.z.w -= bounds.min.z;
+ float3 dim = bounds.max - bounds.min;
-BVHNode *bvh_shrink(BVHNode *root) {
- if(root->is_leaf()) {
- if(root->num_triangles() == 0) // Remove empty leafs
- return nullptr;
- else
- return root;
- }
+ return transform_scale(1.0f / max(1e-18f, dim.x),
+ 1.0f / max(1e-18f, dim.y),
+ 1.0f / max(1e-18f, dim.z)) * space;
+}
- InnerNode *node = dynamic_cast<InnerNode*>(root);
- int num_children = 0;
- BVHNode* children[4];
+BVHNode *merge(BVHNode *oldRoot, BVHNode *n0, BVHNode *n1) {
+ BoundBox childBB = merge(n0->bounds, n1->bounds);
+ BVHNode *root = new InnerNode(childBB, n0, n1);
- for(int i = 0; i < node->num_children(); ++i) {
- BVHNode *child = bvh_shrink(node->get_child(i));
- if(child != nullptr)
- children[num_children++] = child;
- }
+ /* If one of the child has linear bound, take the parents bound */
+ if(n0->deltaBounds != nullptr || n1->deltaBounds != nullptr) {
+ root->bounds = oldRoot->bounds;
+ if(oldRoot->deltaBounds != nullptr) root->deltaBounds = new BoundBox(*oldRoot->deltaBounds);
+ }
- if(num_children == 0) {
- delete root;
- return nullptr;
- }
+ return root;
+}
- if(num_children == 1) {
- delete root;
- return children[0];
+BVHNode *makeBVHTreeFromList(std::deque<BVHNode *> nodes)
+{
+ BVHNode *ret = nullptr;
+ while(!nodes.empty()) {
+ if(ret == nullptr) {
+ ret = nodes.front();
+ nodes.pop_front();
+ continue;
}
- // We have 2 node or more, we'll pack them into 2 nodes (to respect BVH2)
- node->num_children_ = 2;
- if(num_children == 2) {
- node->children[0] = children[0];
- node->children[1] = children[1];
- return node;
+ /* If it's a leaf or a full node -> create a new parrent */
+ if(ret->is_leaf() || ret->num_children() == 4) {
+ ret = new InnerNode(ret->bounds, &ret, 1);
}
- // node->children[0] = new InnerNode(merge(children[0]->bounds, children[1]->bounds), children[0], children[1]);
- node->children[0] = new InnerNode(node->bounds, children[0], children[1]);
- if(node->deltaBounds != nullptr) node->children[0]->deltaBounds = new BoundBox(*node->deltaBounds);
+ InnerNode *innerNode = dynamic_cast<InnerNode*>(ret);
+ innerNode->children[innerNode->num_children_++] = nodes.front();
+ innerNode->bounds.grow(nodes.front()->bounds);
+ nodes.pop_front();
- if(num_children == 3) {
- node->children[1] = children[2];
- } else {
- // node->children[1] = new InnerNode(merge(children[2]->bounds, children[3]->bounds), children[2], children[3]);
- node->children[1] = new InnerNode(node->bounds, children[2], children[3]);
- if(node->deltaBounds != nullptr) node->children[1]->deltaBounds = new BoundBox(*node->deltaBounds);
+ if(ret->num_children() == 4) {
+ nodes.push_back(ret);
+ ret = nullptr;
}
+ }
- return node;
+ return ret;
}
-BVHEmbreeConverter::BVHEmbreeConverter(RTCScene scene, std::vector<Object *> objects, const BVHParams ¶ms)
- : s(scene),
- objects(objects),
- params(params) {}
+BVHNode *bvh_shrink(BVHNode *root)
+{
+ if(root->is_leaf()) {
+ if(root->num_triangles() == 0) // Remove empty leafs
+ return nullptr;
+ else
+ return root;
+ }
+ InnerNode *node = dynamic_cast<InnerNode*>(root);
-struct Data {
- unsigned int packIdx = 0;
- std::vector<Object *> object;
- PackedBVH *pack;
-};
+ int num_children = 0;
+ BVHNode* children[4];
-BVHNode* createLeaf(unsigned int nbPrim, BVHPrimitive prims[], const RTCBounds &bounds, Data *userData) {
- const BoundBox bb = RTCBoundBoxToCCL(bounds);
- const unsigned int from = userData->packIdx;
+ for(int i = 0; i < node->num_children(); ++i) {
+ BVHNode *child = bvh_shrink(node->get_child(i));
+ if(child != nullptr)
+ children[num_children++] = child;
+ }
- uint visibility = 0;
- for(unsigned int i = 0; i < nbPrim; i++) {
- const auto geom_id = prims[i].geomID;
- const auto prim_id = prims[i].primID;
+ if(num_children == 0) {
+ delete root;
+ return nullptr;
+ }
- const unsigned int object_id = geom_id / 2;
- Object *obj = userData->object.at(object_id);
- Mesh::Triangle tri = obj->mesh->get_triangle(prim_id);
+ if(num_children == 1) {
+ delete root;
+ return children[0];
+ }
- int prim_type = obj->mesh->has_motion_blur() ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE;
+ // We have 2 node or more, we'll pack them into 2 nodes (to respect BVH2)
+ node->num_children_ = 2;
+ if(num_children == 2) {
+ node->children[0] = children[0];
+ node->children[1] = children[1];
+ return node;
+ }
- visibility |= obj->visibility;
- packPush(userData->pack, userData->packIdx++, object_id, prim_id, prim_type, obj->visibility, userData->pack->prim_tri_verts.size());
+ node->children[0] = merge(root, children[0], children[1]);
- userData->pack->prim_tri_verts.push_back_slow(float3_to_float4(obj->mesh->verts[tri.v[0]]));
- userData->pack->prim_tri_verts.push_back_slow(float3_to_float4(obj->mesh->verts[tri.v[1]]));
- userData->pack->prim_tri_verts.push_back_slow(float3_to_float4(obj->mesh->verts[tri.v[2]]));
- }
+ if(num_children == 3) {
+ node->children[1] = children[2];
+ } else {
+ node->children[1] = merge(root, children[2], children[3]);
+ }
- return new LeafNode(bb, visibility, from, from + nbPrim);
+ return node;
}
-BVHNode* createInstance(int nbPrim, unsigned int geomID[], const RTCBounds &bounds, Data *userData) {
- const BoundBox bb = RTCBoundBoxToCCL(bounds);
- std::deque<BVHNode *> nodes;
-
- for(size_t i = 0; i < nbPrim; i++) {
- uint id = geomID[i] / 2;
- Object *obj = userData->object.at(id);
- LeafNode *leafNode = new LeafNode(obj->bounds, obj->visibility, userData->packIdx, userData->packIdx + 1);
+BVHEmbreeConverter::BVHEmbreeConverter(RTCScene scene,
+ std::vector<Object *> objects,
+ const BVHParams ¶ms)
+ : s(scene),
+ objects(objects),
+ params(params)
+{}
- packPush(userData->pack, userData->packIdx++, id, -1, PRIMITIVE_NONE, obj->visibility, -1);
-
- nodes.push_back(leafNode);
- }
+BVHNode* BVHEmbreeConverter::createLeaf(unsigned int nbPrim,
+ const BVHPrimitive prims[])
+{
+ const unsigned int from = this->packIdx;
+
+ uint visibility = 0;
+ for(unsigned int i = 0; i < nbPrim; i++) {
+ const unsigned int geom_id = prims[i].geomID;
+ const unsigned int prim_id = prims[i].primID;
+
+ const unsigned int object_id = geom_id / 2;
+ Object *obj = this-
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list