19 #if !defined(__SAH_KDTREE4_H)
20 #define __SAH_KDTREE4_H
43 const Float temp = 1.0f / (extents.x * extents.y
44 + extents.y*extents.z + extents.x*extents.z);
47 extents.y * extents.z * temp,
48 extents.x * extents.z * temp,
49 extents.x * extents.y * temp,
53 (extents.y + extents.z) * temp,
54 (extents.x + extents.z) * temp,
55 (extents.x + extents.y) * temp,
66 if (axis == 3 && m_temp1.w == std::numeric_limits<Float>::infinity()) {
67 return std::pair<Float, Float>(
68 std::numeric_limits<Float>::infinity(),
69 std::numeric_limits<Float>::infinity()
73 return std::pair<Float, Float>(
74 m_temp0[axis] + m_temp1[axis] * leftWidth,
75 m_temp0[axis] + m_temp1[axis] * rightWidth);
84 Float result = 2 * (extents[0] * extents[1] + extents[1] * extents[2]
85 + extents[2] * extents[0]);
112 template <
typename Derived>
121 SizeType primCount = this->cast()->getPrimitiveCount();
122 KDLog(
EInfo,
"Constructing a 4D SAH kd-tree (%i primitives) ..", primCount);
163 template<
bool shadowRay> FINLINE
165 Float &t,
void *temp)
const {
168 static const int prevAxisTable[] = { 2, 0, 1 };
169 static const int nextAxisTable[] = { 1, 2, 0 };
172 #if defined(MTS_KD_MAILBOX_ENABLED)
178 stack[enPt].
t = mint;
179 stack[enPt].
p = ray(mint);
183 stack[exPt].
t = maxt;
184 stack[exPt].
p = ray(maxt);
185 stack[exPt].
node = NULL;
187 bool foundIntersection =
false;
188 const KDNode * __restrict currNode = this->m_nodes;
189 while (currNode != NULL) {
190 while (EXPECT_TAKEN(!currNode->isLeaf())) {
191 const Float splitVal = (
Float) currNode->getSplit();
192 const int axis = currNode->getAxis();
193 const KDNode * __restrict farChild;
196 if (ray.time <= splitVal)
197 currNode = currNode->getLeft();
199 currNode = currNode->getRight();
201 }
else if (stack[enPt].p[axis] <= splitVal) {
202 if (stack[exPt].p[axis] <= splitVal) {
204 currNode = currNode->getLeft();
211 if (stack[enPt].p[axis] == splitVal) {
213 currNode = currNode->getRight();
218 currNode = currNode->getLeft();
219 farChild = currNode + 1;
221 if (splitVal < stack[exPt].p[axis]) {
223 currNode = currNode->getRight();
227 farChild = currNode->getLeft();
228 currNode = farChild + 1;
232 Float distToSplit = (splitVal - ray.o[axis]) * ray.dRcp[axis];
240 stack[exPt].
prev = tmp;
241 stack[exPt].
t = distToSplit;
242 stack[exPt].
node = farChild;
247 stack[exPt].
p = ray(distToSplit);
248 stack[exPt].
p[axis] = splitVal;
250 const int nextAxis = nextAxisTable[axis];
251 const int prevAxis = prevAxisTable[axis];
252 stack[exPt].
p[axis] = splitVal;
253 stack[exPt].
p[nextAxis] = ray.o[nextAxis]
254 + distToSplit*ray.d[nextAxis];
255 stack[exPt].
p[prevAxis] = ray.o[prevAxis]
256 + distToSplit*ray.d[prevAxis];
262 for (
IndexType entry=currNode->getPrimStart(),
263 last = currNode->getPrimEnd(); entry != last; entry++) {
264 const IndexType primIdx = this->m_indices[entry];
266 #if defined(MTS_KD_MAILBOX_ENABLED)
273 result = this->cast()->intersect(ray, primIdx, mint, maxt, t, temp);
275 result = this->cast()->intersect(ray, primIdx, mint, maxt);
281 foundIntersection =
true;
284 #if defined(MTS_KD_MAILBOX_ENABLED)
285 mailbox.
put(primIdx);
289 if (stack[exPt].t > maxt)
294 currNode = stack[exPt].
node;
295 exPt = stack[enPt].
prev;
298 return foundIntersection;
void put(IndexType primIndex)
Definition: sahkdtree4.h:134
FINLINE bool rayIntersectHavran(const Ray &ray, Float mint, Float maxt, Float &t, void *temp) const
Ray tracing kd-tree traversal loop (Havran variant)
Definition: sahkdtree4.h:164
#define KDLog(level, fmt,...)
Definition: gkdtree.h:642
KDTreeBase< AABB4 >::KDNode KDNode
Definition: sahkdtree4.h:117
std::pair< Float, Float > operator()(int axis, Float leftWidth, Float rightWidth) const
Definition: sahkdtree4.h:65
bool contains(IndexType primIndex) const
Definition: sahkdtree4.h:138
const KDNode *__restrict node
Definition: sahkdtree4.h:148
KDTreeBase< AABB4 >::SizeType SizeType
Definition: sahkdtree4.h:115
static Float getQuantity(const AABB4 &aabb)
Definition: sahkdtree4.h:82
#define KDAssert(expr)
Definition: gkdtree.h:56
void buildInternal()
Definition: sahkdtree4.h:120
Base class of all kd-trees.
Definition: gkdtree.h:441
Float t
Definition: sahkdtree4.h:150
TAABB< Point4 > AABB4
Definition: fwd.h:157
#define MTS_KD_MAXDEPTH
Activate lots of extra checks.
Definition: gkdtree.h:37
More relevant debug / information message.
Definition: formatter.h:31
TVector4< Float > Vector4
Definition: fwd.h:122
HashedMailbox()
Definition: sahkdtree4.h:130
Optimized KD-tree acceleration data structure for n-dimensional (n<=4) shapes and various queries on ...
Definition: gkdtree.h:706
Point p
Definition: sahkdtree4.h:154
VectorType getExtents() const
Calculate the bounding box extents.
Definition: aabb.h:292
Implements the four-dimensional surface area heuristic for use by the GenericKDTree construction algo...
Definition: sahkdtree4.h:32
#define MTS_KD_MAILBOX_SIZE
Definition: sahkdtree3.h:31
Hashed mailbox implementation.
Definition: sahkdtree4.h:129
Ray traversal stack entry for Havran-style incoherent ray tracing.
Definition: sahkdtree4.h:146
#define MTS_KD_MAILBOX_MASK
Definition: sahkdtree3.h:32
Definition: sahkdtree4.h:113
uint32_t prev
Definition: sahkdtree4.h:152
SurfaceAreaHeuristic4(const AABB4 &aabb)
Initialize the surface area heuristic with the bounds of a parent node.
Definition: sahkdtree4.h:41
KDTreeBase< AABB4 >::IndexType IndexType
Definition: sahkdtree4.h:116