Esempio n. 1
0
  /* prints the bvh4.triangle4v data structure */
  void print_bvh4_triangle4v(BVH4::NodeRef node, size_t depth)
  {
    if (node.isNode())
    {
      BVH4::Node* n = node.node();
      
      std::cout << "Node {" << std::endl;
      for (size_t i=0; i<BVH4::N; i++) 
      {
        for (size_t k=0; k<depth; k++) std::cout << "  ";
        std::cout << "  bounds" << i << " = " << n->bounds(i) << std::endl;
      }

      for (size_t i=0; i<BVH4::N; i++) 
      {
        if (n->child(i) == BVH4::emptyNode)
          continue;

        for (size_t k=0; k<depth; k++) std::cout << "  ";
        std::cout << "  child" << i << " = ";
        print_bvh4_triangle4v(n->child(i),depth+1); 
      }
      for (size_t k=0; k<depth; k++) std::cout << "  ";
      std::cout << "}" << std::endl;
    }
    else
    {
      size_t num; 
      const Triangle4v* tri = (const Triangle4v*) node.leaf(num);

      std::cout << "Leaf {" << std::endl;
      for (size_t i=0; i<num; i++) {
        for (size_t j=0; j<tri[i].size(); j++) {
          for (size_t k=0; k<depth; k++) std::cout << "  ";
          std::cout << "  Triangle { v0 = (" << tri[i].v0.x[j] << ", " << tri[i].v0.y[j] << ", " << tri[i].v0.z[j] << "),  "
            "v1 = (" << tri[i].v1.x[j] << ", " << tri[i].v1.y[j] << ", " << tri[i].v1.z[j] << "), "
            "v2 = (" << tri[i].v2.x[j] << ", " << tri[i].v2.y[j] << ", " << tri[i].v2.z[j] << "), "
            "geomID = " << tri[i].geomID(j) << ", primID = " << tri[i].primID(j) << " }" << std::endl;
        }
      }
      for (size_t k=0; k<depth; k++) std::cout << "  ";
      std::cout << "}" << std::endl;
    }
  }
 void BVH4BuilderTopLevel::open_sequential()
 {
   size_t N = max(2*refs.size(),size_t(MIN_OPEN_SIZE));
   refs.reserve(N);
   
   std::make_heap(refs.begin(),refs.end());
   while (refs.size()+3 <= N)
   {
     std::pop_heap (refs.begin(),refs.end()); 
     BVH4::NodeRef ref = refs.back().node;
     if (ref.isLeaf()) break;
     refs.pop_back();    
     
     BVH4::Node* node = ref.node();
     for (size_t i=0; i<4; i++) {
       if (node->child(i) == BVH4::emptyNode) continue;
       refs.push_back(BuildRef(node->bounds(i),node->child(i)));
       std::push_heap (refs.begin(),refs.end()); 
     }
   }
 }
    void BVH4BuilderTopLevel::task_open_parallel(size_t threadIndex, size_t threadCount, size_t taskIndex, size_t taskCount, TaskScheduler::Event* event)
    {
      size_t N = global_dest;
      size_t M = refs1.size();
      const size_t start0 = (threadIndex+0)*N/threadCount;
      const size_t end0   = (threadIndex+1)*N/threadCount;
      const size_t start1 = (threadIndex+0)*M/threadCount;
      const size_t end1   = (threadIndex+1)*M/threadCount;
      assert(end1-start1 >= end0-start0);
      BuildRef* prefs1 = &refs1[0];
      
      /* copy from refs buffer to refs1 buffer */
      for (size_t i=start0, j=start1; i<end0; i++, j++) 
        refs1[j] = refs[i];
      
      /* create max heap in our set of items */
      size_t start = start1;
      size_t end   = start1+end0-start0;
      std::make_heap(&prefs1[start],&prefs1[end]);
      float max_volume = 0.0f;
      
      while (true) 
      {
        barrier.wait(threadIndex,threadCount);
        if (threadIndex == 0) global_max_volume = 0.0f;
        barrier.wait(threadIndex,threadCount);
        
        /* parallel calculation of maximal volume */
        max_volume = 0.0f;
        if (end+3 <= end1)
          for (size_t i=start; i<end; i++)
            max_volume = max(max_volume,prefs1[i].lower.w);
        
        atomic_max_f32(&global_max_volume,max_volume);
        
        barrier.wait(threadIndex,threadCount);
        max_volume = global_max_volume;
        barrier.wait(threadIndex,threadCount);
        
        /* if maximal volume is 0, all threads are finished */
        if (max_volume == 0.0f) break;
                
        /* open all nodes that are considered large in this iteration */
        while (end+3 <= end1)
        {
		  if (end-start == 0) break;
          std::pop_heap(&prefs1[start],&prefs1[end]); 
          BVH4::NodeRef ref = prefs1[end-1].node;
          float vol = prefs1[end-1].lower.w;
		  if (ref.isLeaf() || vol < 0.5f*max_volume) {
			std::push_heap(&prefs1[start],&prefs1[end]); 
			break;
		  }
          end--;
          
          BVH4::Node* node = ref.node();
          for (size_t i=0; i<4; i++) {
            if (node->child(i) == BVH4::emptyNode) continue;
            prefs1[end++] = BuildRef(node->bounds(i),node->child(i));
            std::push_heap(&prefs1[start],&prefs1[end]); 
          }
        }
      }
      
      if (threadIndex == 0) global_dest = 0;
      barrier.wait(threadIndex,threadCount);
      
      /* copy again back to refs array */
      size_t dest = atomic_add(&global_dest,end-start);
      for (size_t i=start, j=dest; i<end; i++, j++) 
        refs[j] = refs1[i];
    }