2
* Adapted from code copyright 2009-2011 Intel Corporation
3
* Modifications Copyright 2012, Blender Foundation.
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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
18
#ifndef __BVH_BINNING_H__
19
#define __BVH_BINNING_H__
21
#include "bvh_params.h"
23
#include "util_types.h"
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. */
34
class BVHObjectBinning : public BVHRange
37
__forceinline BVHObjectBinning() {}
38
BVHObjectBinning(const BVHRange& job, BVHReference *prims);
40
void split(BVHReference *prims, BVHObjectBinning& left_o, BVHObjectBinning& right_o) const;
42
float splitSAH; /* SAH cost of the best split */
43
float leafSAH; /* SAH cost of creating a leaf */
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 */
51
enum { MAX_BINS = 32 };
52
enum { LOG_BLOCK_SIZE = 2 };
54
/* computes the bin numbers for each dimension for a box. */
55
__forceinline int4 get_bin(const BoundBox& box) const
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);
61
return clamp(a, mn, mx);
64
/* computes the bin numbers for each dimension for a point. */
65
__forceinline int4 get_bin(const float3& c) const
67
return make_int4((c - cent_bounds().min)*scale - make_float3(0.5f));
70
/* compute the number of blocks occupied for each dimension. */
71
__forceinline float4 blocks(const int4& a) const
73
return make_float4((a + make_int4((1 << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE);
76
/* compute the number of blocks occupied in one dimension. */
77
__forceinline int blocks(size_t a) const
79
return (int)((a+((1LL << LOG_BLOCK_SIZE)-1)) >> LOG_BLOCK_SIZE);