/* * Adapted from code copyright 2009-2011 Intel Corporation * Modifications Copyright 2012, Blender Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __BVH_BINNING_H__ #define __BVH_BINNING_H__ #include "bvh/bvh_params.h" #include "bvh/bvh_unaligned.h" #include "util/util_types.h" CCL_NAMESPACE_BEGIN class BVHBuild; /* Single threaded object binner. Finds the split with the best SAH heuristic * by testing for each dimension multiple partitionings for regular spaced * partition locations. A partitioning for a partition location is computed, * by putting primitives whose centroid is on the left and right of the split * location to different sets. The SAH is evaluated by computing the number of * blocks occupied by the primitives in the partitions. */ class BVHObjectBinning : public BVHRange { public: __forceinline BVHObjectBinning() : leafSAH(FLT_MAX) { } BVHObjectBinning(const BVHRange &job, BVHReference *prims, const BVHUnaligned *unaligned_heuristic = NULL, const Transform *aligned_space = NULL); void split(BVHReference *prims, BVHObjectBinning &left_o, BVHObjectBinning &right_o) const; __forceinline const BoundBox &unaligned_bounds() { return bounds_; } float splitSAH; /* SAH cost of the best split */ float leafSAH; /* SAH cost of creating a leaf */ protected: int dim; /* best split dimension */ int pos; /* best split position */ 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_; const BVHUnaligned *unaligned_heuristic_; const Transform *aligned_space_; 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 mn = make_int4(0); int4 mx = make_int4((int)num_bins - 1); return clamp(a, mn, mx); } /* 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)); } /* compute the number of blocks occupied for each dimension. */ __forceinline float4 blocks(const int4 &a) const { return make_float4((a + make_int4((1 << LOG_BLOCK_SIZE) - 1)) >> LOG_BLOCK_SIZE); } /* compute the number of blocks occupied in one dimension. */ __forceinline int blocks(size_t a) const { return (int)((a + ((1LL << LOG_BLOCK_SIZE) - 1)) >> LOG_BLOCK_SIZE); } __forceinline BoundBox get_prim_bounds(const BVHReference &prim) const { if (aligned_space_ == NULL) { return prim.bounds(); } else { return unaligned_heuristic_->compute_aligned_prim_boundbox(prim, *aligned_space_); } } }; CCL_NAMESPACE_END #endif /* __BVH_BINNING_H__ */