[Bf-blender-cvs] [021fdce3] cycles_hair_bvh: Cycles: Fix aligned range boundbox used to scale binning when doing unaligned split

Sergey Sharybin noreply at git.blender.org
Thu May 12 16:19:29 CEST 2016


Commit: 021fdce3fb7a0e1556c838618064d1440406aaa4
Author: Sergey Sharybin
Date:   Wed May 11 17:04:14 2016 +0200
Branches: cycles_hair_bvh
https://developer.blender.org/rB021fdce3fb7a0e1556c838618064d1440406aaa4

Cycles: Fix aligned range boundbox used to scale binning when doing unaligned split

===================================================================

M	intern/cycles/bvh/bvh_binning.cpp
M	intern/cycles/bvh/bvh_binning.h
M	intern/cycles/bvh/bvh_unaligned.cpp
M	intern/cycles/bvh/bvh_unaligned.h

===================================================================

diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp
index 5ccf9b7..832c1de 100644
--- a/intern/cycles/bvh/bvh_binning.cpp
+++ b/intern/cycles/bvh/bvh_binning.cpp
@@ -55,9 +55,12 @@ __forceinline int get_best_dimension(const float4& bestSAH)
 BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
 : BVHRange(job), splitSAH(FLT_MAX), dim(0), pos(0)
 {
+	bounds_ = bounds();
+	cent_bounds_ = cent_bounds();
+
 	/* compute number of bins to use and precompute scaling factor for binning */
 	num_bins = min(size_t(MAX_BINS), size_t(4.0f + 0.05f*size()));
-	scale = rcp(cent_bounds().size()) * make_float3((float)num_bins);
+	scale = rcp(cent_bounds_.size()) * make_float3((float)num_bins);
 
 	/* initialize binning counter and bounds */
 	BoundBox bin_bounds[MAX_BINS][4];	/* bounds for every bin in every dimension */
@@ -101,7 +104,7 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
 			/* map primitive to bin */
 			const BVHReference& prim0 = prims[start() + i];
 			BoundBox bounds0 = prim0.bounds();
-			int4 bin0 = get_bin(prim0.bounds());
+			int4 bin0 = get_bin(bounds0);
 
 			/* increase bounds of bins */
 			int b00 = (int)extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(bounds0);
@@ -155,14 +158,14 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
 		bestSAH = min(sah,bestSAH);
 	}
 
-	int4 mask = float3_to_float4(cent_bounds().size()) <= make_float4(0.0f);
+	int4 mask = float3_to_float4(cent_bounds_.size()) <= make_float4(0.0f);
 	bestSAH = insert<3>(select(mask, make_float4(FLT_MAX), bestSAH), FLT_MAX);
 
 	/* find best dimension */
 	dim = get_best_dimension(bestSAH);
 	splitSAH = bestSAH[dim];
 	pos = bestSplit[dim];
-	leafSAH	= bounds().half_area() * blocks(size());
+	leafSAH = bounds_.half_area() * blocks(size());
 }
 
 BVHObjectBinning::BVHObjectBinning(const BVHUnaligned& unaligned_heuristic,
@@ -174,9 +177,15 @@ BVHObjectBinning::BVHObjectBinning(const BVHUnaligned& unaligned_heuristic,
   dim(0),
   pos(0)
 {
+	bounds_ = unaligned_heuristic.compute_aligned_boundbox(
+	        *this,
+	        prims,
+	        aligned_space,
+	        &cent_bounds_);
+
 	/* compute number of bins to use and precompute scaling factor for binning */
 	num_bins = min(size_t(MAX_BINS), size_t(4.0f + 0.05f*size()));
-	scale = rcp(cent_bounds().size()) * make_float3((float)num_bins);
+	scale = rcp(cent_bounds_.size()) * make_float3((float)num_bins);
 
 	/* initialize binning counter and bounds */
 	BoundBox bin_bounds[MAX_BINS][4];	/* bounds for every bin in every dimension */
@@ -220,7 +229,7 @@ BVHObjectBinning::BVHObjectBinning(const BVHUnaligned& unaligned_heuristic,
 			/* map primitive to bin */
 			const BVHReference& prim0 = prims[start() + i];
 			BoundBox bounds0 = unaligned_heuristic.compute_aligned_prim_boundbox(prim0, aligned_space);
-			int4 bin0 = get_bin(prim0.bounds());
+			int4 bin0 = get_bin(bounds0);
 
 			/* increase bounds of bins */
 			int b00 = (int)extract<0>(bin0); bin_count[b00][0]++; bin_bounds[b00][0].grow(bounds0);
@@ -274,15 +283,14 @@ BVHObjectBinning::BVHObjectBinning(const BVHUnaligned& unaligned_heuristic,
 		bestSAH = min(sah,bestSAH);
 	}
 
-	int4 mask = float3_to_float4(cent_bounds().size()) <= make_float4(0.0f);
+	int4 mask = float3_to_float4(cent_bounds_.size()) <= make_float4(0.0f);
 	bestSAH = insert<3>(select(mask, make_float4(FLT_MAX), bestSAH), FLT_MAX);
 
 	/* find best dimension */
 	dim = get_best_dimension(bestSAH);
 	splitSAH = bestSAH[dim];
 	pos = bestSplit[dim];
-	/* TODO(sergey): Transform full bounds to aligned space. */
-	leafSAH = bounds().half_area() * blocks(size());
+	leafSAH = bounds_.half_area() * blocks(size());
 }
 
 void BVHObjectBinning::split(BVHReference* prims,
@@ -382,7 +390,6 @@ void BVHObjectBinning::split(const BVHUnaligned& unaligned_heuristic,
 			r--;
 		}
 	}
-
 	/* finish */
 	if(l != 0 && N-1-r != 0) {
 		right_o = BVHObjectBinning(BVHRange(rgeom_bounds, rcent_bounds, start() + l, N-1-r), prims);
diff --git a/intern/cycles/bvh/bvh_binning.h b/intern/cycles/bvh/bvh_binning.h
index 2bfdea7..03961c7 100644
--- a/intern/cycles/bvh/bvh_binning.h
+++ b/intern/cycles/bvh/bvh_binning.h
@@ -65,13 +65,17 @@ protected:
 	size_t num_bins;	/* actual number of bins to use */
 	float3 scale;		/* scaling factor to compute bin */
 
+	/* Effective bounds and centroid bounds. */
+	BoundBox bounds_;
+	BoundBox cent_bounds_;
+
 	enum { MAX_BINS = 32 };
 	enum { LOG_BLOCK_SIZE = 2 };
 
 	/* computes the bin numbers for each dimension for a box. */
 	__forceinline int4 get_bin(const BoundBox& box) const
 	{
-		int4 a = make_int4((box.center2() - cent_bounds().min)*scale - make_float3(0.5f));
+		int4 a = make_int4((box.center2() - cent_bounds_.min)*scale - make_float3(0.5f));
 		int4 mn = make_int4(0);
 		int4 mx = make_int4((int)num_bins-1);
 
@@ -81,7 +85,7 @@ protected:
 	/* computes the bin numbers for each dimension for a point. */
 	__forceinline int4 get_bin(const float3& c) const
 	{
-		return make_int4((c - cent_bounds().min)*scale - make_float3(0.5f));
+		return make_int4((c - cent_bounds_.min)*scale - make_float3(0.5f));
 	}
 
 	/* compute the number of blocks occupied for each dimension. */
diff --git a/intern/cycles/bvh/bvh_unaligned.cpp b/intern/cycles/bvh/bvh_unaligned.cpp
index f5aad23..316a2c5 100644
--- a/intern/cycles/bvh/bvh_unaligned.cpp
+++ b/intern/cycles/bvh/bvh_unaligned.cpp
@@ -21,6 +21,7 @@
 #include "object.h"
 
 #include "bvh_binning.h"
+#include "bvh_params.h"
 
 #include "util_boundbox.h"
 #include "util_debug.h"
@@ -51,6 +52,23 @@ Transform BVHUnaligned::compute_aligned_space(
 	return make_trasnform_frame(make_float3(0.0f, 0.0f, 1.0f));
 }
 
+Transform BVHUnaligned::compute_aligned_space(
+    const BVHRange& range,
+    const vector<BVHReference>& references) const
+{
+	for(int i = range.start(); i < range.end(); ++i) {
+		const BVHReference& ref = references[i];
+		Transform aligned_space;
+		/* Use first primitive which defines correct direction to define
+		 * the orientation space.
+		 */
+		if(compute_aligned_space(ref, &aligned_space)) {
+			return aligned_space;
+		}
+	}
+	return make_trasnform_frame(make_float3(0.0f, 0.0f, 1.0f));
+}
+
 bool BVHUnaligned::compute_aligned_space(const BVHReference& ref,
                                          Transform *aligned_space) const
 {
@@ -99,18 +117,55 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(
 
 BoundBox BVHUnaligned::compute_aligned_boundbox(
         const BVHObjectBinning& range,
+        const BVHReference *references,
+        const Transform& aligned_space) const
+{
+	BoundBox bounds = BoundBox::empty;
+	for(int i = range.start(); i < range.end(); ++i) {
+		const BVHReference& ref = references[i];
+		BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
+		bounds.grow(ref_bounds);
+	}
+	return bounds;
+}
+
+BoundBox BVHUnaligned::compute_aligned_boundbox(
+        const BVHObjectBinning& range,
         const vector<BVHReference>& references,
         const Transform& aligned_space) const
 {
+	return compute_aligned_boundbox(range, &references[0], aligned_space);
+}
+
+BoundBox BVHUnaligned::compute_aligned_boundbox(
+        const BVHRange& range,
+        const BVHReference *references,
+        const Transform& aligned_space,
+        BoundBox *cent_bounds) const
+{
 	BoundBox bounds = BoundBox::empty;
+	if(cent_bounds != NULL) {
+		*cent_bounds = BoundBox::empty;
+	}
 	for(int i = range.start(); i < range.end(); ++i) {
 		const BVHReference& ref = references[i];
 		BoundBox ref_bounds = compute_aligned_prim_boundbox(ref, aligned_space);
 		bounds.grow(ref_bounds);
+		if(cent_bounds != NULL) {
+			cent_bounds->grow(ref_bounds.center2());
+		}
 	}
 	return bounds;
 }
 
+BoundBox BVHUnaligned::compute_aligned_boundbox(
+        const BVHRange& range,
+        const vector<BVHReference>& references,
+        const Transform& aligned_space) const
+{
+	return compute_aligned_boundbox(range, &references[0], aligned_space, NULL);
+}
+
 Transform BVHUnaligned::compute_node_transform(
         const BoundBox& bounds,
         const Transform& aligned_space)
diff --git a/intern/cycles/bvh/bvh_unaligned.h b/intern/cycles/bvh/bvh_unaligned.h
index 23a4579..10bf7f1 100644
--- a/intern/cycles/bvh/bvh_unaligned.h
+++ b/intern/cycles/bvh/bvh_unaligned.h
@@ -23,6 +23,7 @@ CCL_NAMESPACE_BEGIN
 
 class BoundBox;
 class BVHObjectBinning;
+class BVHRange;
 class BVHReference;
 class Transform;
 class Object;
@@ -36,6 +37,9 @@ public:
 	Transform compute_aligned_space(
 	        const BVHObjectBinning& range,
 	        const vector<BVHReference>& references) const;
+	Transform compute_aligned_space(
+	        const BVHRange& range,
+	        const vector<BVHReference>& references) const;
 
 	/* Calculate alignment for the oriented node for a given reference.
 	 *
@@ -54,6 +58,19 @@ public:
 	        const BVHObjectBinning& range,
 	        const vector<BVHReference>& references,
 	        const Transform& aligned_space) const;
+	BoundBox compute_aligned_boundbox(
+	        const BVHObjectBinning& range,
+	        const BVHReference* references,
+	        const Transform& aligned_space) const;
+	BoundBox compute_aligned_boundbox(
+	        const BVHRange& range,
+	        const vector<BVHReference>& references,
+	        const Transform& aligned_space) const;
+	BoundBox compute_aligned_boundbox(
+	        const BVHRange& range,
+	        const BVHReference *references,
+	        const Transform& aligned_space,
+	        BoundBox *cent_bounds) const;
 
 	/* Calculate affine transform for node packing.
 	 * Bounds will be in the range of 0..1.




More information about the Bf-blender-cvs mailing list