Пример #1
0
    FallBackSplit FallBackSplit::find(size_t threadIndex, PrimRefBlockAlloc<BezierPrim>& alloc, BezierRefList& prims, 
				      BezierRefList& lprims_o, PrimInfo& linfo_o,
				      BezierRefList& rprims_o, PrimInfo& rinfo_o)
    {
      size_t num = 0;
      BBox3fa lbounds = empty, rbounds = empty;
      BezierRefList::item* lblock = lprims_o.insert(alloc.malloc(threadIndex));
      BezierRefList::item* rblock = rprims_o.insert(alloc.malloc(threadIndex));
      linfo_o.reset();
      rinfo_o.reset();
      
      while (BezierRefList::item* block = prims.take()) 
      {
	for (size_t i=0; i<block->size(); i++) 
	{
	  const BezierPrim& prim = block->at(i); 
	  const BBox3fa bounds = prim.bounds();
	  
	  if ((num++)%2) 
	  {
	    linfo_o.add(bounds,prim.center2()); 
	    if (likely(lblock->insert(prim))) continue; 
	    lblock = lprims_o.insert(alloc.malloc(threadIndex));
	    lblock->insert(prim);
	  } 
	  else 
	  {
	    rinfo_o.add(bounds,prim.center2()); 
	    if (likely(rblock->insert(prim))) continue;
	    rblock = rprims_o.insert(alloc.malloc(threadIndex));
	    rblock->insert(prim);
	  }
	}
	alloc.free(threadIndex,block);
      }
      return FallBackSplit(linfo_o.geomBounds,linfo_o.size(),rinfo_o.geomBounds,rinfo_o.size());
    }
    void StrandSplit::Split::split<false>(size_t threadIndex, size_t threadCount, LockStepTaskScheduler* scheduler, PrimRefBlockAlloc<BezierPrim>& alloc, 
					  BezierRefList& prims, 
					  BezierRefList& lprims_o, PrimInfo& linfo_o, 
					  BezierRefList& rprims_o, PrimInfo& rinfo_o) const 
    {
      BezierRefList::item* lblock = lprims_o.insert(alloc.malloc(threadIndex));
      BezierRefList::item* rblock = rprims_o.insert(alloc.malloc(threadIndex));
      linfo_o.reset();
      rinfo_o.reset();
      
      while (BezierRefList::item* block = prims.take()) 
      {
	for (size_t i=0; i<block->size(); i++) 
	{
	  const BezierPrim& prim = block->at(i); 
	  const Vec3fa axisi = normalize(prim.p3-prim.p0);
	  const float cos0 = abs(dot(axisi,axis0));
	  const float cos1 = abs(dot(axisi,axis1));
	  
	  if (cos0 > cos1) 
	  {
	    linfo_o.add(prim.bounds(),prim.center());
	    if (likely(lblock->insert(prim))) continue; 
	    lblock = lprims_o.insert(alloc.malloc(threadIndex));
	    lblock->insert(prim);
	  } 
	  else 
	  {
	    rinfo_o.add(prim.bounds(),prim.center());
	    if (likely(rblock->insert(prim))) continue;
	    rblock = rprims_o.insert(alloc.malloc(threadIndex));
	    rblock->insert(prim);
	  }
	}
	alloc.free(threadIndex,block);
      }
    }
    void SpatialSplit::Split::split<false>(size_t threadIndex, size_t threadCount, LockStepTaskScheduler* scheduler, PrimRefBlockAlloc<BezierPrim>& alloc, 
					   Scene* scene, BezierRefList& prims, 
					   BezierRefList& lprims_o, PrimInfo& linfo_o, 
					   BezierRefList& rprims_o, PrimInfo& rinfo_o) const
    {
      assert(valid());
      BezierRefList::item* lblock = lprims_o.insert(alloc.malloc(threadIndex));
      BezierRefList::item* rblock = rprims_o.insert(alloc.malloc(threadIndex));
      linfo_o.reset();
      rinfo_o.reset();

      while (BezierRefList::item* block = prims.take()) 
      {
	for (size_t i=0; i<block->size(); i++) 
	{
	  const BezierPrim& prim = block->at(i);
	  const int bin0 = mapping.bin(min(prim.p0,prim.p3))[dim];
	  const int bin1 = mapping.bin(max(prim.p0,prim.p3))[dim];
	  
	  /* sort to the left side */
	  if (bin0 < pos && bin1 < pos) // FIXME: optimize
	  {
	    linfo_o.add(prim.bounds(),prim.center());
	    if (likely(lblock->insert(prim))) continue; 
	    lblock = lprims_o.insert(alloc.malloc(threadIndex));
	    lblock->insert(prim);
	    continue;
	  }
	  
	  /* sort to the right side */
	  if (bin0 >= pos && bin1 >= pos)// FIXME: optimize
	  {
	    rinfo_o.add(prim.bounds(),prim.center());
	    if (likely(rblock->insert(prim))) continue;
	    rblock = rprims_o.insert(alloc.malloc(threadIndex));
	    rblock->insert(prim);
	    continue;
	  }
	  
	  /* split and sort to left and right */
	  BezierPrim left,right;
	  float fpos = mapping.pos(pos,dim);
	  if (prim.split(dim,fpos,left,right)) 
	  {
	    if (!left.bounds().empty()) {
	      linfo_o.add(left.bounds(),left.center());
	      if (!lblock->insert(left)) {
		lblock = lprims_o.insert(alloc.malloc(threadIndex));
		lblock->insert(left);
	      }
	    }
	    if (!right.bounds().empty()) {
	      rinfo_o.add(right.bounds(),right.center());
	      if (!rblock->insert(right)) {
		rblock = rprims_o.insert(alloc.malloc(threadIndex));
		rblock->insert(right);
	      }
	    }
	    continue;
	  }
	  
	  /* insert to left side as fallback */
	  linfo_o.add(prim.bounds(),prim.center());
	  if (!lblock->insert(prim)) {
	    lblock = lprims_o.insert(alloc.malloc(threadIndex));
	    lblock->insert(prim);
	  }
	}
	alloc.free(threadIndex,block);
      }
    }