Example #1
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;
 } 
Example #2
0
      void build(size_t, size_t) 
      {
        /* progress monitor */
        auto progress = [&] (size_t dn) { bvh->scene->progressMonitor(dn); };
        auto virtualprogress = BuildProgressMonitorFromClosure(progress);

        /* fast path for empty BVH */
        const size_t numPrimitives = scene->getNumPrimitives<BezierCurves,1>();
        if (numPrimitives == 0) {
          prims.clear();
          bvh->set(BVH::emptyNode,empty,0);
          return;
        }

        double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "BuilderHairSAH");

        //profile(1,5,numPrimitives,[&] (ProfileTimer& timer) {
        
        /* create primref array */
        bvh->alloc.init_estimate(numPrimitives*sizeof(Primitive));
        prims.resize(numPrimitives);
        const PrimInfo pinfo = createBezierRefArray<1>(scene,prims,virtualprogress);
        
        /* build hierarchy */
        typename BVH::NodeRef root = bvh_obb_builder_binned_sah<N>
          (
            [&] () { return bvh->alloc.threadLocal2(); },

            [&] (const PrimInfo* children, const size_t numChildren, 
                 HeuristicArrayBinningSAH<BezierPrim> alignedHeuristic, 
                 FastAllocator::ThreadLocal2* alloc) -> Node*
            {
              Node* node = (Node*) alloc->alloc0.malloc(sizeof(Node),16); node->clear();
              for (size_t i=0; i<numChildren; i++)
                node->set(i,children[i].geomBounds);
              return node;
            },
            
            [&] (const PrimInfo* children, const size_t numChildren, 
                 UnalignedHeuristicArrayBinningSAH<BezierPrim> unalignedHeuristic, 
                 FastAllocator::ThreadLocal2* alloc) -> UnalignedNode*
            {
              UnalignedNode* node = (UnalignedNode*) alloc->alloc0.malloc(sizeof(UnalignedNode),16); node->clear();
              for (size_t i=0; i<numChildren; i++) 
              {
                const LinearSpace3fa space = unalignedHeuristic.computeAlignedSpace(children[i]); 
                const PrimInfo       sinfo = unalignedHeuristic.computePrimInfo(children[i],space);
                node->set(i,OBBox3fa(space,sinfo.geomBounds));
              }
              return node;
            },

            [&] (size_t depth, const PrimInfo& pinfo, FastAllocator::ThreadLocal2* alloc) -> NodeRef
            {
              size_t items = pinfo.size();
              size_t start = pinfo.begin;
              Primitive* accel = (Primitive*) alloc->alloc1.malloc(items*sizeof(Primitive));
              NodeRef node = bvh->encodeLeaf((char*)accel,items);
              for (size_t i=0; i<items; i++) {
                accel[i].fill(prims.data(),start,pinfo.end,bvh->scene,false);
              }
              return node;
            },
            progress,
            prims.data(),pinfo,N,BVH::maxBuildDepthLeaf,1,1,BVH::maxLeafBlocks);
        
        bvh->set(root,pinfo.geomBounds,pinfo.size());
        
        //});
        
        /* clear temporary data for static geometry */
        if (scene->isStatic()) {
          prims.clear();
          bvh->shrink();
        }
        bvh->cleanup();
        bvh->postBuild(t0);
      }
Example #3
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;
    }
  } 
Example #4
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;
      }
  }