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