Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/builders/priminfo_mb.h
9913 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "primref_mb.h"
7
8
namespace embree
9
{
10
/*! stores bounding information for a set of primitives */
11
template<typename BBox>
12
class PrimInfoMBT : public CentGeom<BBox>
13
{
14
public:
15
using CentGeom<BBox>::geomBounds;
16
using CentGeom<BBox>::centBounds;
17
18
__forceinline PrimInfoMBT () {
19
}
20
21
__forceinline PrimInfoMBT (EmptyTy)
22
: CentGeom<BBox>(empty), object_range(0,0), num_time_segments(0), max_num_time_segments(0), max_time_range(0.0f,1.0f), time_range(1.0f,0.0f) {}
23
24
__forceinline PrimInfoMBT (size_t begin, size_t end)
25
: CentGeom<BBox>(empty), object_range(begin,end), num_time_segments(0), max_num_time_segments(0), max_time_range(0.0f,1.0f), time_range(1.0f,0.0f) {}
26
27
template<typename PrimRef>
28
__forceinline void add_primref(const PrimRef& prim)
29
{
30
CentGeom<BBox>::extend_primref(prim);
31
time_range.extend(prim.time_range);
32
object_range._end++;
33
num_time_segments += prim.size();
34
if (max_num_time_segments < prim.totalTimeSegments()) {
35
max_num_time_segments = prim.totalTimeSegments();
36
max_time_range = prim.time_range;
37
}
38
}
39
40
__forceinline void merge(const PrimInfoMBT& other)
41
{
42
CentGeom<BBox>::merge(other);
43
time_range.extend(other.time_range);
44
object_range._begin += other.object_range.begin();
45
object_range._end += other.object_range.end();
46
num_time_segments += other.num_time_segments;
47
if (max_num_time_segments < other.max_num_time_segments) {
48
max_num_time_segments = other.max_num_time_segments;
49
max_time_range = other.max_time_range;
50
}
51
}
52
53
static __forceinline const PrimInfoMBT merge2(const PrimInfoMBT& a, const PrimInfoMBT& b) {
54
PrimInfoMBT r = a; r.merge(b); return r;
55
}
56
57
__forceinline size_t begin() const {
58
return object_range.begin();
59
}
60
61
__forceinline size_t end() const {
62
return object_range.end();
63
}
64
65
/*! returns the number of primitives */
66
__forceinline size_t size() const {
67
return object_range.size();
68
}
69
70
__forceinline float halfArea() const {
71
return time_range.size()*expectedApproxHalfArea(geomBounds);
72
}
73
74
__forceinline float leafSAH() const {
75
return time_range.size()*expectedApproxHalfArea(geomBounds)*float(num_time_segments);
76
}
77
78
__forceinline float leafSAH(size_t block_shift) const {
79
return time_range.size()*expectedApproxHalfArea(geomBounds)*float((num_time_segments+(size_t(1)<<block_shift)-1) >> block_shift);
80
}
81
82
__forceinline float align_time(float ct) const
83
{
84
//return roundf(ct * float(numTimeSegments)) / float(numTimeSegments);
85
float t0 = (ct-max_time_range.lower)/max_time_range.size();
86
float t1 = roundf(t0 * float(max_num_time_segments)) / float(max_num_time_segments);
87
return t1*max_time_range.size()+max_time_range.lower;
88
}
89
90
/*! stream output */
91
friend embree_ostream operator<<(embree_ostream cout, const PrimInfoMBT& pinfo)
92
{
93
return cout << "PrimInfo { " <<
94
"object_range = " << pinfo.object_range <<
95
", time_range = " << pinfo.time_range <<
96
", time_segments = " << pinfo.num_time_segments <<
97
", geomBounds = " << pinfo.geomBounds <<
98
", centBounds = " << pinfo.centBounds <<
99
"}";
100
}
101
102
public:
103
range<size_t> object_range; //!< primitive range
104
size_t num_time_segments; //!< total number of time segments of all added primrefs
105
size_t max_num_time_segments; //!< maximum number of time segments of a primitive
106
BBox1f max_time_range; //!< time range of primitive with max_num_time_segments
107
BBox1f time_range; //!< merged time range of primitives when merging prims, or additionally clipped with build time range when used in SetMB
108
};
109
110
typedef PrimInfoMBT<typename PrimRefMB::BBox> PrimInfoMB;
111
112
struct SetMB : public PrimInfoMB
113
{
114
static const size_t PARALLEL_THRESHOLD = 3 * 1024;
115
static const size_t PARALLEL_FIND_BLOCK_SIZE = 1024;
116
static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128;
117
118
typedef mvector<PrimRefMB>* PrimRefVector;
119
120
__forceinline SetMB() {}
121
122
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims)
123
: PrimInfoMB(pinfo_i), prims(prims) {}
124
125
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims, range<size_t> object_range_in, BBox1f time_range_in)
126
: PrimInfoMB(pinfo_i), prims(prims)
127
{
128
object_range = object_range_in;
129
time_range = intersect(time_range,time_range_in);
130
}
131
132
__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims, BBox1f time_range_in)
133
: PrimInfoMB(pinfo_i), prims(prims)
134
{
135
time_range = intersect(time_range,time_range_in);
136
}
137
138
void deterministic_order() const
139
{
140
/* required as parallel partition destroys original primitive order */
141
PrimRefMB* prim = prims->data();
142
std::sort(&prim[object_range.begin()],&prim[object_range.end()]);
143
}
144
145
template<typename RecalculatePrimRef>
146
__forceinline LBBox3fa linearBounds(const RecalculatePrimRef& recalculatePrimRef) const
147
{
148
auto reduce = [&](const range<size_t>& r) -> LBBox3fa
149
{
150
LBBox3fa cbounds(empty);
151
for (size_t j = r.begin(); j < r.end(); j++)
152
{
153
PrimRefMB& ref = (*prims)[j];
154
const LBBox3fa bn = recalculatePrimRef.linearBounds(ref, time_range);
155
cbounds.extend(bn);
156
};
157
return cbounds;
158
};
159
160
return parallel_reduce(object_range.begin(), object_range.end(), PARALLEL_FIND_BLOCK_SIZE, PARALLEL_THRESHOLD, LBBox3fa(empty),
161
reduce,
162
[&](const LBBox3fa& b0, const LBBox3fa& b1) -> LBBox3fa { return embree::merge(b0, b1); });
163
}
164
165
template<typename RecalculatePrimRef>
166
__forceinline LBBox3fa linearBounds(const RecalculatePrimRef& recalculatePrimRef, const LinearSpace3fa& space) const
167
{
168
auto reduce = [&](const range<size_t>& r) -> LBBox3fa
169
{
170
LBBox3fa cbounds(empty);
171
for (size_t j = r.begin(); j < r.end(); j++)
172
{
173
PrimRefMB& ref = (*prims)[j];
174
const LBBox3fa bn = recalculatePrimRef.linearBounds(ref, time_range, space);
175
cbounds.extend(bn);
176
};
177
return cbounds;
178
};
179
180
return parallel_reduce(object_range.begin(), object_range.end(), PARALLEL_FIND_BLOCK_SIZE, PARALLEL_THRESHOLD, LBBox3fa(empty),
181
reduce,
182
[&](const LBBox3fa& b0, const LBBox3fa& b1) -> LBBox3fa { return embree::merge(b0, b1); });
183
}
184
185
template<typename RecalculatePrimRef>
186
const SetMB primInfo(const RecalculatePrimRef& recalculatePrimRef, const LinearSpace3fa& space) const
187
{
188
auto computePrimInfo = [&](const range<size_t>& r) -> PrimInfoMB
189
{
190
PrimInfoMB pinfo(empty);
191
for (size_t j=r.begin(); j<r.end(); j++)
192
{
193
PrimRefMB& ref = (*prims)[j];
194
PrimRefMB ref1 = recalculatePrimRef(ref,time_range,space);
195
pinfo.add_primref(ref1);
196
};
197
return pinfo;
198
};
199
200
const PrimInfoMB pinfo = parallel_reduce(object_range.begin(), object_range.end(), PARALLEL_FIND_BLOCK_SIZE, PARALLEL_THRESHOLD,
201
PrimInfoMB(empty), computePrimInfo, PrimInfoMB::merge2);
202
203
return SetMB(pinfo,prims,object_range,time_range);
204
}
205
206
public:
207
PrimRefVector prims;
208
};
209
//}
210
}
211
212