Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h
9906 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "bvh_node_base.h"
7
8
namespace embree
9
{
10
/*! Motion Blur AABBNode */
11
template<typename NodeRef, int N>
12
struct AABBNodeMB_t : public BaseNode_t<NodeRef, N>
13
{
14
using BaseNode_t<NodeRef,N>::children;
15
typedef BVHNodeRecord<NodeRef> NodeRecord;
16
typedef BVHNodeRecordMB<NodeRef> NodeRecordMB;
17
typedef BVHNodeRecordMB4D<NodeRef> NodeRecordMB4D;
18
19
struct Create
20
{
21
template<typename BuildRecord>
22
__forceinline NodeRef operator() (BuildRecord* children, const size_t num, const FastAllocator::CachedAllocator& alloc) const
23
{
24
AABBNodeMB_t* node = (AABBNodeMB_t*) alloc.malloc0(sizeof(AABBNodeMB_t),NodeRef::byteNodeAlignment); node->clear();
25
return NodeRef::encodeNode(node);
26
}
27
};
28
29
struct Set
30
{
31
template<typename BuildRecord>
32
__forceinline NodeRecordMB operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRecordMB* children, const size_t num) const
33
{
34
#if defined(DEBUG)
35
// check that empty children are only at the end of the child list
36
bool emptyChild = false;
37
for (size_t i=0; i<num; i++) {
38
emptyChild |= (children[i].ref == NodeRef::emptyNode);
39
assert(emptyChild == (children[i].ref == NodeRef::emptyNode));
40
}
41
#endif
42
AABBNodeMB_t* node = ref.getAABBNodeMB();
43
44
LBBox3fa bounds = empty;
45
for (size_t i=0; i<num; i++) {
46
node->setRef(i,children[i].ref);
47
node->setBounds(i,children[i].lbounds);
48
bounds.extend(children[i].lbounds);
49
}
50
return NodeRecordMB(ref,bounds);
51
}
52
};
53
54
struct SetTimeRange
55
{
56
__forceinline SetTimeRange(BBox1f tbounds) : tbounds(tbounds) {}
57
58
template<typename BuildRecord>
59
__forceinline NodeRecordMB operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRecordMB* children, const size_t num) const
60
{
61
AABBNodeMB_t* node = ref.getAABBNodeMB();
62
63
LBBox3fa bounds = empty;
64
for (size_t i=0; i<num; i++) {
65
node->setRef(i, children[i].ref);
66
node->setBounds(i, children[i].lbounds, tbounds);
67
bounds.extend(children[i].lbounds);
68
}
69
return NodeRecordMB(ref,bounds);
70
}
71
72
BBox1f tbounds;
73
};
74
75
/*! Clears the node. */
76
__forceinline void clear() {
77
lower_x = lower_y = lower_z = vfloat<N>(pos_inf);
78
upper_x = upper_y = upper_z = vfloat<N>(neg_inf);
79
lower_dx = lower_dy = lower_dz = vfloat<N>(0.0f);
80
upper_dx = upper_dy = upper_dz = vfloat<N>(0.0f);
81
BaseNode_t<NodeRef,N>::clear();
82
}
83
84
/*! Sets ID of child. */
85
__forceinline void setRef(size_t i, NodeRef ref) {
86
children[i] = ref;
87
}
88
89
/*! Sets bounding box of child. */
90
__forceinline void setBounds(size_t i, const BBox3fa& bounds0_i, const BBox3fa& bounds1_i)
91
{
92
/*! for empty bounds we have to avoid inf-inf=nan */
93
BBox3fa bounds0(min(bounds0_i.lower,Vec3fa(+FLT_MAX)),max(bounds0_i.upper,Vec3fa(-FLT_MAX)));
94
BBox3fa bounds1(min(bounds1_i.lower,Vec3fa(+FLT_MAX)),max(bounds1_i.upper,Vec3fa(-FLT_MAX)));
95
bounds0 = bounds0.enlarge_by(4.0f*float(ulp));
96
bounds1 = bounds1.enlarge_by(4.0f*float(ulp));
97
Vec3fa dlower = bounds1.lower-bounds0.lower;
98
Vec3fa dupper = bounds1.upper-bounds0.upper;
99
100
lower_x[i] = bounds0.lower.x; lower_y[i] = bounds0.lower.y; lower_z[i] = bounds0.lower.z;
101
upper_x[i] = bounds0.upper.x; upper_y[i] = bounds0.upper.y; upper_z[i] = bounds0.upper.z;
102
103
lower_dx[i] = dlower.x; lower_dy[i] = dlower.y; lower_dz[i] = dlower.z;
104
upper_dx[i] = dupper.x; upper_dy[i] = dupper.y; upper_dz[i] = dupper.z;
105
}
106
107
/*! Sets bounding box of child. */
108
__forceinline void setBounds(size_t i, const LBBox3fa& bounds) {
109
setBounds(i, bounds.bounds0, bounds.bounds1);
110
}
111
112
/*! Sets bounding box of child. */
113
__forceinline void setBounds(size_t i, const LBBox3fa& bounds, const BBox1f& tbounds) {
114
setBounds(i, bounds.global(tbounds));
115
}
116
117
/*! Sets bounding box and ID of child. */
118
__forceinline void set(size_t i, NodeRef ref, const BBox3fa& bounds) {
119
lower_x[i] = bounds.lower.x; lower_y[i] = bounds.lower.y; lower_z[i] = bounds.lower.z;
120
upper_x[i] = bounds.upper.x; upper_y[i] = bounds.upper.y; upper_z[i] = bounds.upper.z;
121
children[i] = ref;
122
}
123
124
/*! Sets bounding box and ID of child. */
125
__forceinline void set(size_t i, const NodeRecordMB4D& child)
126
{
127
setRef(i, child.ref);
128
setBounds(i, child.lbounds, child.dt);
129
}
130
131
/*! Return bounding box for time 0 */
132
__forceinline BBox3fa bounds0(size_t i) const {
133
return BBox3fa(Vec3fa(lower_x[i],lower_y[i],lower_z[i]),
134
Vec3fa(upper_x[i],upper_y[i],upper_z[i]));
135
}
136
137
/*! Return bounding box for time 1 */
138
__forceinline BBox3fa bounds1(size_t i) const {
139
return BBox3fa(Vec3fa(lower_x[i]+lower_dx[i],lower_y[i]+lower_dy[i],lower_z[i]+lower_dz[i]),
140
Vec3fa(upper_x[i]+upper_dx[i],upper_y[i]+upper_dy[i],upper_z[i]+upper_dz[i]));
141
}
142
143
/*! Returns bounds of node. */
144
__forceinline BBox3fa bounds() const {
145
return BBox3fa(Vec3fa(reduce_min(min(lower_x,lower_x+lower_dx)),
146
reduce_min(min(lower_y,lower_y+lower_dy)),
147
reduce_min(min(lower_z,lower_z+lower_dz))),
148
Vec3fa(reduce_max(max(upper_x,upper_x+upper_dx)),
149
reduce_max(max(upper_y,upper_y+upper_dy)),
150
reduce_max(max(upper_z,upper_z+upper_dz))));
151
}
152
153
/*! Return bounding box of child i */
154
__forceinline BBox3fa bounds(size_t i) const {
155
return merge(bounds0(i),bounds1(i));
156
}
157
158
/*! Return linear bounding box of child i */
159
__forceinline LBBox3fa lbounds(size_t i) const {
160
return LBBox3fa(bounds0(i),bounds1(i));
161
}
162
163
/*! Return bounding box of child i at specified time */
164
__forceinline BBox3fa bounds(size_t i, float time) const {
165
return lerp(bounds0(i),bounds1(i),time);
166
}
167
168
/*! Returns the expected surface area when randomly sampling the time. */
169
__forceinline float expectedHalfArea(size_t i) const {
170
return lbounds(i).expectedHalfArea();
171
}
172
173
/*! Returns the expected surface area when randomly sampling the time. */
174
__forceinline float expectedHalfArea(size_t i, const BBox1f& t0t1) const {
175
return lbounds(i).expectedHalfArea(t0t1);
176
}
177
178
/*! swap two children of the node */
179
__forceinline void swap(size_t i, size_t j)
180
{
181
assert(i<N && j<N);
182
std::swap(children[i],children[j]);
183
184
std::swap(lower_x[i],lower_x[j]);
185
std::swap(upper_x[i],upper_x[j]);
186
std::swap(lower_y[i],lower_y[j]);
187
std::swap(upper_y[i],upper_y[j]);
188
std::swap(lower_z[i],lower_z[j]);
189
std::swap(upper_z[i],upper_z[j]);
190
191
std::swap(lower_dx[i],lower_dx[j]);
192
std::swap(upper_dx[i],upper_dx[j]);
193
std::swap(lower_dy[i],lower_dy[j]);
194
std::swap(upper_dy[i],upper_dy[j]);
195
std::swap(lower_dz[i],lower_dz[j]);
196
std::swap(upper_dz[i],upper_dz[j]);
197
}
198
199
/*! compacts a node (moves empty children to the end) */
200
__forceinline static void compact(AABBNodeMB_t* a)
201
{
202
/* find right most filled node */
203
ssize_t j=N;
204
for (j=j-1; j>=0; j--)
205
if (a->child(j) != NodeRef::emptyNode)
206
break;
207
208
/* replace empty nodes with filled nodes */
209
for (ssize_t i=0; i<j; i++) {
210
if (a->child(i) == NodeRef::emptyNode) {
211
a->swap(i,j);
212
for (j=j-1; j>i; j--)
213
if (a->child(j) != NodeRef::emptyNode)
214
break;
215
}
216
}
217
}
218
219
/*! Returns reference to specified child */
220
__forceinline NodeRef& child(size_t i) { assert(i<N); return children[i]; }
221
__forceinline const NodeRef& child(size_t i) const { assert(i<N); return children[i]; }
222
223
/*! stream output operator */
224
friend embree_ostream operator<<(embree_ostream cout, const AABBNodeMB_t& n)
225
{
226
cout << "AABBNodeMB {" << embree_endl;
227
for (size_t i=0; i<N; i++)
228
{
229
const BBox3fa b0 = n.bounds0(i);
230
const BBox3fa b1 = n.bounds1(i);
231
cout << " child" << i << " { " << embree_endl;
232
cout << " bounds0 = " << b0 << ", " << embree_endl;
233
cout << " bounds1 = " << b1 << ", " << embree_endl;
234
cout << " }";
235
}
236
cout << "}";
237
return cout;
238
}
239
240
public:
241
vfloat<N> lower_x; //!< X dimension of lower bounds of all N children.
242
vfloat<N> upper_x; //!< X dimension of upper bounds of all N children.
243
vfloat<N> lower_y; //!< Y dimension of lower bounds of all N children.
244
vfloat<N> upper_y; //!< Y dimension of upper bounds of all N children.
245
vfloat<N> lower_z; //!< Z dimension of lower bounds of all N children.
246
vfloat<N> upper_z; //!< Z dimension of upper bounds of all N children.
247
248
vfloat<N> lower_dx; //!< X dimension of lower bounds of all N children.
249
vfloat<N> upper_dx; //!< X dimension of upper bounds of all N children.
250
vfloat<N> lower_dy; //!< Y dimension of lower bounds of all N children.
251
vfloat<N> upper_dy; //!< Y dimension of upper bounds of all N children.
252
vfloat<N> lower_dz; //!< Z dimension of lower bounds of all N children.
253
vfloat<N> upper_dz; //!< Z dimension of upper bounds of all N children.
254
};
255
}
256
257