Update bundled version of minilzo
[blender-staging.git] / intern / cycles / bvh / bvh_binning.h
1 /*
2  * Adapted from code copyright 2009-2011 Intel Corporation
3  * Modifications Copyright 2012, Blender Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef __BVH_BINNING_H__
19 #define __BVH_BINNING_H__
20
21 #include "bvh_params.h"
22
23 #include "util_types.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 /* Single threaded object binner. Finds the split with the best SAH heuristic
28  * by testing for each dimension multiple partitionings for regular spaced
29  * partition locations. A partitioning for a partition location is computed,
30  * by putting primitives whose centroid is on the left and right of the split
31  * location to different sets. The SAH is evaluated by computing the number of
32  * blocks occupied by the primitives in the partitions. */
33
34 class BVHObjectBinning : public BVHRange
35 {
36 public:
37         __forceinline BVHObjectBinning() {}
38         BVHObjectBinning(const BVHRange& job, BVHReference *prims);
39
40         void split(BVHReference *prims, BVHObjectBinning& left_o, BVHObjectBinning& right_o) const;
41
42         float splitSAH; /* SAH cost of the best split */
43         float leafSAH;  /* SAH cost of creating a leaf */
44
45 protected:
46         int dim;                        /* best split dimension */
47         int pos;                        /* best split position */
48         size_t num_bins;        /* actual number of bins to use */
49         float3 scale;           /* scaling factor to compute bin */
50
51         enum { MAX_BINS = 32 };
52         enum { LOG_BLOCK_SIZE = 2 };
53
54         /* computes the bin numbers for each dimension for a box. */
55         __forceinline int4 get_bin(const BoundBox& box) const
56         {
57                 int4 a = make_int4((box.center2() - cent_bounds().min)*scale - make_float3(0.5f));
58                 int4 mn = make_int4(0);
59                 int4 mx = make_int4((int)num_bins-1);
60
61                 return clamp(a, mn, mx);
62         }
63
64         /* computes the bin numbers for each dimension for a point. */
65         __forceinline int4 get_bin(const float3& c) const
66         {
67                 return make_int4((c - cent_bounds().min)*scale - make_float3(0.5f));
68         }
69
70         /* compute the number of blocks occupied for each dimension. */
71         __forceinline float4 blocks(const int4& a) const
72         {
73                 return make_float4((a + make_int4((1 << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE);
74         }
75
76         /* compute the number of blocks occupied in one dimension. */
77         __forceinline int blocks(size_t a) const
78         {
79                 return (int)((a+((1LL << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE);
80         }
81 };
82
83 CCL_NAMESPACE_END
84
85 #endif
86