diff options
Diffstat (limited to 'intern/cycles/bvh')
-rw-r--r-- | intern/cycles/bvh/bvh_split.cpp | 148 | ||||
-rw-r--r-- | intern/cycles/bvh/bvh_split.h | 21 |
2 files changed, 113 insertions, 56 deletions
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 2290c4143ad..2e14eee36f0 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -243,75 +243,113 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right, right = BVHRange(right_bounds, right_start, right_end - right_start); } -void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos) +void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) { - /* initialize boundboxes */ - BoundBox left_bounds = BoundBox::empty; - BoundBox right_bounds = BoundBox::empty; - - /* loop over vertices/edges. */ - Object *ob = builder->objects[ref.prim_object()]; - const Mesh *mesh = ob->mesh; - - if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { - const int *inds = mesh->triangles[ref.prim_index()].v; - const float3 *verts = &mesh->verts[0]; - const float3* v1 = &verts[inds[2]]; - - for(int i = 0; i < 3; i++) { - const float3* v0 = v1; - int vindex = inds[i]; - v1 = &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); - - if(v0p >= pos) - 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)); - left_bounds.grow(t); - right_bounds.grow(t); - } - } - } - else { - /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ - const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()); - 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); + const int *inds = mesh->triangles[ref.prim_index()].v; + const float3 *verts = &mesh->verts[0]; + const float3 *v1 = &verts[inds[2]]; - float v0p = v0[dim]; - float v1p = v1[dim]; + for(int i = 0; i < 3; i++) { + const float3 *v0 = v1; + int vindex = inds[i]; + v1 = &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); - - if(v1p <= pos) - left_bounds.grow(v1); - - if(v1p >= pos) - right_bounds.grow(v1); + 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); } } +} + +void BVHSpatialSplit::split_curve_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds) +{ + /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/ + const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()); + 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); + + float v0p = v0[dim]; + float v1p = v1[dim]; + + /* insert vertex to the boxes it belongs to. */ + if(v0p <= pos) + left_bounds.grow(v0); + + if(v0p >= pos) + right_bounds.grow(v0); + + if(v1p <= pos) + left_bounds.grow(v1); + + if(v1p >= pos) + right_bounds.grow(v1); + + /* 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)); + left_bounds.grow(t); + right_bounds.grow(t); + } +} + +void BVHSpatialSplit::split_reference(BVHBuild *builder, + BVHReference& left, + BVHReference& right, + const BVHReference& ref, + int dim, + float pos) +{ + /* initialize boundboxes */ + BoundBox left_bounds = BoundBox::empty; + BoundBox right_bounds = BoundBox::empty; + + /* loop over vertices/edges. */ + Object *ob = builder->objects[ref.prim_object()]; + const Mesh *mesh = ob->mesh; + + if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { + split_triangle_reference(ref, + mesh, + dim, + pos, + left_bounds, + right_bounds); + } + else if(ref.prim_type() & PRIMITIVE_ALL_CURVE) { + split_curve_reference(ref, + mesh, + dim, + pos, + left_bounds, + right_bounds); + } + else { + assert(!"Unknown primitive type in BVH reference split."); + } /* intersect with original bounds. */ left_bounds.max[dim] = pos; diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h index 5b739311e5f..1b550d11b15 100644 --- a/intern/cycles/bvh/bvh_split.h +++ b/intern/cycles/bvh/bvh_split.h @@ -55,7 +55,26 @@ public: BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH); void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range); - void split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos); + void split_reference(BVHBuild *builder, + BVHReference& left, + BVHReference& right, + const BVHReference& ref, + int dim, + float pos); + +protected: + void split_triangle_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); + void split_curve_reference(const BVHReference& ref, + const Mesh *mesh, + int dim, + float pos, + BoundBox& left_bounds, + BoundBox& right_bounds); }; /* Mixed Object-Spatial Split */ |