diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-08-22 22:19:00 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2015-08-24 10:46:40 +0300 |
commit | 334208e67086530924c1172d4c993ae14508c0cf (patch) | |
tree | 43877b87e7b3bf835b9b3e70ad7971e96f5fa428 /intern/cycles/bvh/bvh_split.cpp | |
parent | c88c5db3601b82f347f2f54f49fae8ae173ff03b (diff) |
Cycles: Implementation of object reference nodes spatial split
This commit implements object reference node spatial split making it possible
to use spatial split for top-level BVH.
The code is not in use yet because enabling spatial split on top level BVH is
not coming for free and it needs to be investigated if it's worth in terms of
improved render times.
Diffstat (limited to 'intern/cycles/bvh/bvh_split.cpp')
-rw-r--r-- | intern/cycles/bvh/bvh_split.cpp | 69 |
1 files changed, 58 insertions, 11 deletions
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 7d29f84445f..caf1b4dfc46 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -244,6 +244,7 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, } void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, + const Transform *tfm, int prim_index, int dim, float pos, @@ -252,25 +253,25 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, { const int *inds = mesh->triangles[prim_index].v; const float3 *verts = &mesh->verts[0]; - const float3 *v1 = &verts[inds[2]]; + float3 v1 = tfm ? transform_point(tfm, verts[inds[2]]) : verts[inds[2]]; for(int i = 0; i < 3; i++) { - const float3 *v0 = v1; + float3 v0 = v1; int vindex = inds[i]; - v1 = &verts[vindex]; - float v0p = (*v0)[dim]; - float v1p = (*v1)[dim]; + v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex]; + float v0p = v0[dim]; + float v1p = v1[dim]; /* insert vertex to the boxes it belongs to. */ if(v0p <= pos) - left_bounds.grow(*v0); + left_bounds.grow(v0); if(v0p >= pos) - right_bounds.grow(*v0); + right_bounds.grow(v0); /* edge intersects the plane => insert intersection to both boxes. */ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) { - float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); + float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f)); left_bounds.grow(t); right_bounds.grow(t); } @@ -278,6 +279,7 @@ void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh, } void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, + const Transform *tfm, int prim_index, int segment_index, int dim, @@ -290,8 +292,13 @@ void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh, const int k1 = k0 + 1; const float4 key0 = mesh->curve_keys[k0]; const float4 key1 = mesh->curve_keys[k1]; - const float3 v0 = float4_to_float3(key0); - const float3 v1 = float4_to_float3(key1); + float3 v0 = float4_to_float3(key0); + float3 v1 = float4_to_float3(key1); + + if(tfm != NULL) { + v0 = transform_point(tfm, v0); + v1 = transform_point(tfm, v1); + } float v0p = v0[dim]; float v1p = v1[dim]; @@ -325,6 +332,7 @@ void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref, BoundBox& right_bounds) { split_triangle_primitive(mesh, + NULL, ref.prim_index(), dim, pos, @@ -340,6 +348,7 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference& ref, BoundBox& right_bounds) { split_curve_primitive(mesh, + NULL, ref.prim_index(), PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()), dim, @@ -348,6 +357,40 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference& ref, right_bounds); } +void BVHSpatialSplit::split_object_reference(const Object *object, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + Mesh *mesh = object->mesh; + for(int tri_idx = 0; tri_idx < mesh->triangles.size(); ++tri_idx) { + split_triangle_primitive(mesh, + &object->tfm, + tri_idx, + dim, + pos, + left_bounds, + right_bounds); + } + for(int curve_idx = 0; curve_idx < mesh->curves.size(); ++curve_idx) { + Mesh::Curve &curve = mesh->curves[curve_idx]; + for(int segment_idx = 0; + segment_idx < curve.num_keys - 1; + ++segment_idx) + { + split_curve_primitive(mesh, + &object->tfm, + curve_idx, + segment_idx, + dim, + pos, + left_bounds, + right_bounds); + } + } +} + void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, @@ -380,7 +423,11 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, right_bounds); } else { - assert(!"Unknown primitive type in BVH reference split."); + split_object_reference(ob, + dim, + pos, + left_bounds, + right_bounds); } /* intersect with original bounds. */ |