Revert "Cycles: Tweak empty boundbox children"
[blender.git] / intern / cycles / bvh / bvh_params.h
1 /*
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011, 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_PARAMS_H__
19 #define __BVH_PARAMS_H__
20
21 #include "util_boundbox.h"
22
23 #include "kernel_types.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 /* BVH Parameters */
28
29 class BVHParams
30 {
31 public:
32         /* spatial split area threshold */
33         bool use_spatial_split;
34         float spatial_split_alpha;
35
36         /* Unaligned nodes creation threshold */
37         float unaligned_split_threshold;
38
39         /* SAH costs */
40         float sah_node_cost;
41         float sah_primitive_cost;
42
43         /* number of primitives in leaf */
44         int min_leaf_size;
45         int max_triangle_leaf_size;
46         int max_curve_leaf_size;
47
48         /* object or mesh level bvh */
49         bool top_level;
50
51         /* QBVH */
52         bool use_qbvh;
53
54         /* Mask of primitives to be included into the BVH. */
55         int primitive_mask;
56
57         /* Use unaligned bounding boxes.
58          * Only used for curves BVH.
59          */
60         bool use_unaligned_nodes;
61
62         /* fixed parameters */
63         enum {
64                 MAX_DEPTH = 64,
65                 MAX_SPATIAL_DEPTH = 48,
66                 NUM_SPATIAL_BINS = 32
67         };
68
69         BVHParams()
70         {
71                 use_spatial_split = true;
72                 spatial_split_alpha = 1e-5f;
73
74                 unaligned_split_threshold = 0.7f;
75
76                 /* todo: see if splitting up primitive cost to be separate for triangles
77                  * and curves can help. so far in tests it doesn't help, but why? */
78                 sah_node_cost = 1.0f;
79                 sah_primitive_cost = 1.0f;
80
81                 min_leaf_size = 1;
82                 max_triangle_leaf_size = 8;
83                 max_curve_leaf_size = 2;
84
85                 top_level = false;
86                 use_qbvh = false;
87                 use_unaligned_nodes = false;
88
89                 primitive_mask = PRIMITIVE_ALL;
90         }
91
92         /* SAH costs */
93         __forceinline float cost(int num_nodes, int num_primitives) const
94         { return node_cost(num_nodes) + primitive_cost(num_primitives); }
95
96         __forceinline float primitive_cost(int n) const
97         { return n*sah_primitive_cost; }
98
99         __forceinline float node_cost(int n) const
100         { return n*sah_node_cost; }
101
102         __forceinline bool small_enough_for_leaf(int size, int level)
103         { return (size <= min_leaf_size || level >= MAX_DEPTH); }
104 };
105
106 /* BVH Reference
107  *
108  * Reference to a primitive. Primitive index and object are sneakily packed
109  * into BoundBox to reduce memory usage and align nicely */
110
111 class BVHReference
112 {
113 public:
114         __forceinline BVHReference() {}
115
116         __forceinline BVHReference(const BoundBox& bounds_, int prim_index_, int prim_object_, int prim_type)
117         : rbounds(bounds_)
118         {
119                 rbounds.min.w = __int_as_float(prim_index_);
120                 rbounds.max.w = __int_as_float(prim_object_);
121                 type = prim_type;
122         }
123
124         __forceinline const BoundBox& bounds() const { return rbounds; }
125         __forceinline int prim_index() const { return __float_as_int(rbounds.min.w); }
126         __forceinline int prim_object() const { return __float_as_int(rbounds.max.w); }
127         __forceinline int prim_type() const { return type; }
128
129         BVHReference& operator=(const BVHReference &arg) {
130                 if(&arg != this) {
131                         memcpy(this, &arg, sizeof(BVHReference));
132                 }
133                 return *this;
134         }
135
136 protected:
137         BoundBox rbounds;
138         uint type;
139 };
140
141 /* BVH Range
142  *
143  * Build range used during construction, to indicate the bounds and place in
144  * the reference array of a subset of primitives Again uses trickery to pack
145  * integers into BoundBox for alignment purposes. */
146
147 class BVHRange
148 {
149 public:
150         __forceinline BVHRange()
151         {
152                 rbounds.min.w = __int_as_float(0);
153                 rbounds.max.w = __int_as_float(0);
154         }
155
156         __forceinline BVHRange(const BoundBox& bounds_, int start_, int size_)
157         : rbounds(bounds_)
158         {
159                 rbounds.min.w = __int_as_float(start_);
160                 rbounds.max.w = __int_as_float(size_);
161         }
162
163         __forceinline BVHRange(const BoundBox& bounds_, const BoundBox& cbounds_, int start_, int size_)
164         : rbounds(bounds_), cbounds(cbounds_)
165         {
166                 rbounds.min.w = __int_as_float(start_);
167                 rbounds.max.w = __int_as_float(size_);
168         }
169
170         __forceinline void set_start(int start_) { rbounds.min.w = __int_as_float(start_); }
171
172         __forceinline const BoundBox& bounds() const { return rbounds; }
173         __forceinline const BoundBox& cent_bounds() const { return cbounds; }
174         __forceinline int start() const { return __float_as_int(rbounds.min.w); }
175         __forceinline int size() const { return __float_as_int(rbounds.max.w); }
176         __forceinline int end() const { return start() + size(); }
177
178 protected:
179         BoundBox rbounds;
180         BoundBox cbounds;
181 };
182
183 /* BVH Spatial Bin */
184
185 struct BVHSpatialBin
186 {
187         BoundBox bounds;
188         int enter;
189         int exit;
190
191         __forceinline BVHSpatialBin()
192         {
193         }
194 };
195
196 /* BVH Spatial Storage
197  *
198  * The idea of this storage is have thread-specific storage for the spatial
199  * splitters. We can pre-allocate this storage in advance and avoid heavy memory
200  * operations during split process.
201  */
202
203 struct BVHSpatialStorage {
204         /* Accumulated bounds when sweeping from right to left.  */
205         vector<BoundBox> right_bounds;
206
207         /* Bins used for histogram when selecting best split plane. */
208         BVHSpatialBin bins[3][BVHParams::NUM_SPATIAL_BINS];
209
210         /* Temporary storage for the new references. Used by spatial split to store
211          * new references in before they're getting inserted into actual array,
212          */
213         vector<BVHReference> new_references;
214 };
215
216 CCL_NAMESPACE_END
217
218 #endif /* __BVH_PARAMS_H__ */
219