示例#1
0
 typename BVHN<N>::NodeRef BVHN<N>::layoutLargeNodesRecursion(NodeRef& node, FastAllocator::ThreadLocal& allocator)
 {
   if (node.isBarrier()) {
     node.clearBarrier();
     return node;
   }
   else if (node.isAlignedNode()) 
   {
     AlignedNode* oldnode = node.alignedNode();
     AlignedNode* newnode = (BVHN::AlignedNode*) allocator.malloc(sizeof(BVHN::AlignedNode),byteNodeAlignment);
     *newnode = *oldnode;
     for (size_t c=0; c<N; c++)
       newnode->child(c) = layoutLargeNodesRecursion(oldnode->child(c),allocator);
     return encodeNode(newnode);
   }
   else return node;
 }
示例#2
0
  void BVHN<N>::layoutLargeNodes(size_t num)
  {
    struct NodeArea 
    {
      __forceinline NodeArea() {}

      __forceinline NodeArea(NodeRef& node, const BBox3fa& bounds)
        : node(&node), A(node.isLeaf() ? float(neg_inf) : area(bounds)) {}

      __forceinline bool operator< (const NodeArea& other) const {
        return this->A < other.A;
      }

      NodeRef* node;
      float A;
    };
    std::vector<NodeArea> lst;
    lst.reserve(num);
    lst.push_back(NodeArea(root,empty));

    while (lst.size() < num)
    {
      std::pop_heap(lst.begin(), lst.end());
      NodeArea n = lst.back(); lst.pop_back();
      if (!n.node->isAlignedNode()) break;
      AlignedNode* node = n.node->alignedNode();
      for (size_t i=0; i<N; i++) {
        if (node->child(i) == BVHN::emptyNode) continue;
        lst.push_back(NodeArea(node->child(i),node->bounds(i)));
        std::push_heap(lst.begin(), lst.end());
      }
    }

    for (size_t i=0; i<lst.size(); i++)
      lst[i].node->setBarrier();
      
    root = layoutLargeNodesRecursion(root,*alloc.threadLocal2()->alloc0);
  }
示例#3
0
    BBox3fa BVHNRefitter<N>::recurse_bottom(NodeRef& ref)
    {
      /* this is a leaf node */
      if (unlikely(ref.isLeaf()))
        return leafBounds.leafBounds(ref);
      
      /* recurse if this is an internal node */
      AlignedNode* node = ref.alignedNode();

      /* enable exclusive prefetch for >= AVX platforms */      
#if defined(__AVX__)      
      ref.prefetchW();
#endif      
      BBox3fa bounds[N];

      for (size_t i=0; i<N; i++)
        if (unlikely(node->child(i) == BVH::emptyNode))
        {
          bounds[i] = BBox3fa(empty);          
        }
      else
        bounds[i] = recurse_bottom(node->child(i));
      
      /* AOS to SOA transform */
      BBox3vf<N> boundsT = transpose<N>(bounds);
      
      /* set new bounds */
      node->lower_x = boundsT.lower.x;
      node->lower_y = boundsT.lower.y;
      node->lower_z = boundsT.lower.z;
      node->upper_x = boundsT.upper.x;
      node->upper_y = boundsT.upper.y;
      node->upper_z = boundsT.upper.z;

      return merge<N>(bounds);
    }
示例#4
0
    BBox3fa BVHNRefitter<N>::refit_toplevel(NodeRef& ref,
                                            size_t &subtrees,
											const BBox3fa *const subTreeBounds,
                                            const size_t depth)
    {
      if (depth >= MAX_SUB_TREE_EXTRACTION_DEPTH) 
      {
        assert(subtrees < MAX_NUM_SUB_TREES);
        assert(subTrees[subtrees] == ref);
        return subTreeBounds[subtrees++];
      }

      if (ref.isAlignedNode())
      {
        AlignedNode* node = ref.alignedNode();
        BBox3fa bounds[N];

        for (size_t i=0; i<N; i++)
        {
          NodeRef& child = node->child(i);

          if (unlikely(child == BVH::emptyNode)) 
            bounds[i] = BBox3fa(empty);
          else
            bounds[i] = refit_toplevel(child,subtrees,subTreeBounds,depth+1); 
        }
        
        BBox3vf<N> boundsT = transpose<N>(bounds);
      
        /* set new bounds */
        node->lower_x = boundsT.lower.x;
        node->lower_y = boundsT.lower.y;
        node->lower_z = boundsT.lower.z;
        node->upper_x = boundsT.upper.x;
        node->upper_y = boundsT.upper.y;
        node->upper_z = boundsT.upper.z;
        
        return merge<N>(bounds);
      }
      else
        return leafBounds.leafBounds(ref);
    }
示例#5
0
    void BVHNRefitter<N>::gather_subtree_refs(NodeRef& ref,
                                              size_t &subtrees,
                                              const size_t depth)
    {
      if (depth >= MAX_SUB_TREE_EXTRACTION_DEPTH) 
      {
        assert(subtrees < MAX_NUM_SUB_TREES);
        subTrees[subtrees++] = ref;
        return;
      }

      if (ref.isAlignedNode())
      {
        AlignedNode* node = ref.alignedNode();
        for (size_t i=0; i<N; i++) {
          NodeRef& child = node->child(i);
          if (unlikely(child == BVH::emptyNode)) continue;
          gather_subtree_refs(child,subtrees,depth+1); 
        }
      }
    }
示例#6
0
 typename BVHNStatistics<N>::Statistics BVHNStatistics<N>::statistics(NodeRef node, const double A, const BBox1f t0t1)
 {
   Statistics s;
   double dt = max(0.0f,t0t1.size());
   if (node.isAlignedNode())
   {
     AlignedNode* n = node.alignedNode();
     for (size_t i=0; i<N; i++) {
       if (n->child(i) == BVH::emptyNode) continue;
       s.statAlignedNodes.numChildren++;
       const double Ai = max(0.0f,halfArea(n->extend(i)));
       s = s + statistics(n->child(i),Ai,t0t1); 
     }
     s.statAlignedNodes.numNodes++;
     s.statAlignedNodes.nodeSAH += dt*A;
     s.depth++;
   }
   else if (node.isUnalignedNode())
   {
     UnalignedNode* n = node.unalignedNode();
     for (size_t i=0; i<N; i++) {
       if (n->child(i) == BVH::emptyNode) continue;
       s.statUnalignedNodes.numChildren++;
       const double Ai = max(0.0f,halfArea(n->extend(i)));
       s = s + statistics(n->child(i),Ai,t0t1); 
     }
     s.statUnalignedNodes.numNodes++;
     s.statUnalignedNodes.nodeSAH += dt*A;
     s.depth++;
   }
   else if (node.isAlignedNodeMB())
   {
     AlignedNodeMB* n = node.alignedNodeMB();
     for (size_t i=0; i<N; i++) {
       if (n->child(i) == BVH::emptyNode) continue;
       s.statAlignedNodesMB.numChildren++;
       const double Ai = max(0.0f,halfArea(n->extend0(i)));
       s = s + statistics(n->child(i),Ai,t0t1);
     }
     s.statAlignedNodesMB.numNodes++;
     s.statAlignedNodesMB.nodeSAH += dt*A;
     s.depth++;
   }
   else if (node.isUnalignedNodeMB())
   {
     UnalignedNodeMB* n = node.unalignedNodeMB();
     for (size_t i=0; i<N; i++) {
       if (n->child(i) == BVH::emptyNode) continue;
       s.statUnalignedNodesMB.numChildren++;
       const double Ai = max(0.0f,halfArea(n->extend0(i)));
       s = s + statistics(n->child(i),Ai,t0t1); 
     }
     s.statUnalignedNodesMB.numNodes++;
     s.statUnalignedNodesMB.nodeSAH += dt*A;
     s.depth++;
   }
   else if (node.isTransformNode())
   {
     s.statTransformNodes.numNodes++;
     s.statTransformNodes.nodeSAH += dt*A;
     s.depth++;
   }
   else if (node.isQuantizedNode())
   {
     QuantizedNode* n = node.quantizedNode();
     for (size_t i=0; i<N; i++) {
       if (n->child(i) == BVH::emptyNode) continue;
       s.statQuantizedNodes.numChildren++;
       const double Ai = max(0.0f,halfArea(n->extend(i)));
       s = s + statistics(n->child(i),Ai,t0t1); 
     }
     s.statQuantizedNodes.numNodes++;
     s.statQuantizedNodes.nodeSAH += dt*A;
     s.depth++;
   }
   else if (node.isLeaf())
   {
     size_t num; const char* tri = node.leaf(num);
     if (num)
     {
       for (size_t i=0; i<num; i++) {
         s.statLeaf.numPrims += bvh->primTy.size(tri+i*bvh->primTy.bytes);
       }
       s.statLeaf.numLeaves++;
       s.statLeaf.numPrimBlocks += num;
       s.statLeaf.leafSAH += dt*A*num;
       if (num-1 < Statistics::LeafStat::NHIST) {
         s.statLeaf.numPrimBlocksHistogram[num-1]++;
       }
     }
   }
   else {
     throw std::runtime_error("not supported node type in bvh_statistics");
   }
   return s;
 } 
示例#7
0
  void BVHNStatistics<N>::statistics(NodeRef node, const float A, size_t& depth)
  {
    if (node.isNode())
    {
      numAlignedNodes++;
      AlignedNode* n = node.node();
      bvhSAH += A*travCostAligned;
      depth = 0;
      for (size_t i=0; i<N; i++) {
        if (n->child(i) == BVH::emptyNode) continue;
        childrenAlignedNodes++;
        const float Ai = max(0.0f,halfArea(n->extend(i)));
        size_t cdepth; statistics(n->child(i),Ai,cdepth); 
        depth=max(depth,cdepth);
      }
      depth++;
    }
    else if (node.isUnalignedNode())
    {
      numUnalignedNodes++;
      UnalignedNode* n = node.unalignedNode();
      bvhSAH += A*travCostUnaligned;
      
      depth = 0;
      for (size_t i=0; i<N; i++) {
        if (n->child(i) == BVH::emptyNode) continue;
        childrenUnalignedNodes++;
        const float Ai = max(0.0f,halfArea(n->extend(i)));
        size_t cdepth; statistics(n->child(i),Ai,cdepth); 
        depth=max(depth,cdepth);
      }
      depth++;
    }
    else if (node.isNodeMB())
    {
      numAlignedNodesMB++;
      AlignedNodeMB* n = node.nodeMB();
      bvhSAH += A*travCostAligned;
      
      depth = 0;
      for (size_t i=0; i<N; i++) {
        if (n->child(i) == BVH::emptyNode) continue;
        childrenAlignedNodesMB++;
        const float Ai = max(0.0f,halfArea(n->extend0(i)));
        size_t cdepth; statistics(n->child(i),Ai,cdepth); 
        depth=max(depth,cdepth);
      }
      depth++;
    }
    else if (node.isUnalignedNodeMB())
    {
      numUnalignedNodesMB++;
      UnalignedNodeMB* n = node.unalignedNodeMB();
      bvhSAH += A*travCostUnaligned;
      
      depth = 0;
      for (size_t i=0; i<N; i++) {
        if (n->child(i) == BVH::emptyNode) continue;
        childrenUnalignedNodesMB++;
        const float Ai = max(0.0f,halfArea(n->extend0(i)));
        size_t cdepth; statistics(n->child(i),Ai,cdepth); 
        depth=max(depth,cdepth);
      }
      depth++;
    }
    else if (node.isTransformNode())
    {
      numTransformNodes++;
      TransformNode* n = node.transformNode();
      bvhSAH += A*travCostTransform;

      depth = 0;
      const BBox3fa worldBounds = xfmBounds(n->local2world,n->localBounds);
      const float Ai = max(0.0f,halfArea(worldBounds));
      //size_t cdepth; statistics(n->child,Ai,cdepth); 
      //depth=max(depth,cdepth)+1;
    }
    else
    {
      depth = 0;
      size_t num; const char* tri = node.leaf(num);
      if (!num) return;
      
      numLeaves++;
      numPrimBlocks += num;
      for (size_t i=0; i<num; i++)
        numPrims += bvh->primTy.size(tri+i*bvh->primTy.bytes);
      
      float sah = A * intCost * num;
      leafSAH += sah;
    }
  } 
示例#8
0
  void BVH4Statistics::statistics(NodeRef node, const float A, size_t& depth)
  {
    if (node.isNode())
      {
	hash += 0x1234;
	numAlignedNodes++;
	AlignedNode* n = node.node();
	bvhSAH += A*BVH4::travCostAligned;
	depth = 0;
	for (size_t i=0; i<BVH4::N; i++) {
	  if (n->child(i) == BVH4::emptyNode) continue;
	  childrenAlignedNodes++;
	  const float Ai = max(0.0f,halfArea(n->extend(i)));
	  size_t cdepth; statistics(n->child(i),Ai,cdepth); 
	  depth=max(depth,cdepth);
	}
	depth++;
	hash += 0x76767*depth;
      }
    else if (node.isUnalignedNode())
      {
	hash += 0x1232344;
	numUnalignedNodes++;
	UnalignedNode* n = node.unalignedNode();
	bvhSAH += A*BVH4::travCostUnaligned;

	depth = 0;
	for (size_t i=0; i<BVH4::N; i++) {
	  if (n->child(i) == BVH4::emptyNode) continue;
	  childrenUnalignedNodes++;
	  const float Ai = max(0.0f,halfArea(n->extend(i)));
	  size_t cdepth; statistics(n->child(i),Ai,cdepth); 
	  depth=max(depth,cdepth);
	}
	depth++;
	hash += 0x76767*depth;
      }
    else if (node.isNodeMB())
      {
	hash += 0xEF343;
	numAlignedNodesMB++;
	BVH4::NodeMB* n = node.nodeMB();
	bvhSAH += A*BVH4::travCostAligned;

	depth = 0;
	for (size_t i=0; i<BVH4::N; i++) {
	  if (n->child(i) == BVH4::emptyNode) continue;
	  childrenAlignedNodesMB++;
	  const float Ai = max(0.0f,halfArea(n->extend0(i)));
	  size_t cdepth; statistics(n->child(i),Ai,cdepth); 
	  depth=max(depth,cdepth);
	}
	depth++;
	hash += 0x76767*depth;
      }
    else if (node.isUnalignedNodeMB())
      {
	hash += 0x1EEF4;
	numUnalignedNodesMB++;
	BVH4::UnalignedNodeMB* n = node.unalignedNodeMB();
	bvhSAH += A*BVH4::travCostUnaligned;

	depth = 0;
	for (size_t i=0; i<BVH4::N; i++) {
	  if (n->child(i) == BVH4::emptyNode) continue;
	  childrenUnalignedNodesMB++;
	  const float Ai = max(0.0f,halfArea(n->extend0(i)));
	  size_t cdepth; statistics(n->child(i),Ai,cdepth); 
	  depth=max(depth,cdepth);
	}
	depth++;
	hash += 0x76767*depth;
      }
    else
      {
	depth = 0;
	size_t num; const char* tri = node.leaf(num);
	hash += 0xDD776*num+0x878;
	if (!num) return;

	hash += bvh->primTy.hash(tri,num);
      
	numLeaves++;
	numPrims += num;
	float sah = A * BVH4::intCost * num;
	bvhSAH += sah;
      }
  }