__m256 BVH2Intersector8Chunk<TriangleIntersector>::occluded(const BVH2Intersector8Chunk* This, Ray8& ray, const __m256 valid_i)
  {
    avxb valid = valid_i;
    avxb terminated = !valid;
    const BVH2* bvh = This->bvh;
    STAT3(shadow.travs,1,popcnt(valid),8);

    NodeRef stack[1+BVH2::maxDepth]; //!< stack of nodes that still need to get traversed
    NodeRef* stackPtr = stack;                    //!< current stack pointer
    NodeRef cur = bvh->root;                      //!< in cur we track the ID of the current node

    /* let inactive rays miss all boxes */
    const avx3f rdir = rcp_safe(ray.dir);
    avxf rayFar  = select(terminated,avxf(neg_inf),ray.tfar);

    while (true)
    {
      /*! downtraversal loop */
      while (likely(cur.isNode()))
      {
        STAT3(normal.trav_nodes,1,popcnt(valid),8);

        /* intersect packet with box of both children */
        const Node* node = cur.node();
        const size_t hit0 = intersectBox(ray.org,rdir,ray.tnear,rayFar,node,0);
        const size_t hit1 = intersectBox(ray.org,rdir,ray.tnear,rayFar,node,1);
        
        /*! if two children are hit push both onto stack */
        if (likely(hit0 != 0 && hit1 != 0)) {
          *stackPtr = node->child(0); stackPtr++; cur = node->child(1);
        }
        
        /*! if one child hit, continue with that child */
        else {
          if      (likely(hit0 != 0)) cur = node->child(0);
          else if (likely(hit1 != 0)) cur = node->child(1);
          else goto pop_node;
        }
      }

      /*! leaf node, intersect all triangles */
      {
        STAT3(shadow.trav_leaves,1,popcnt(valid),8);
        size_t num; Triangle* tri = (Triangle*) cur.leaf(NULL,num);
        for (size_t i=0; i<num; i++) {
          terminated |= TriangleIntersector::occluded(valid,ray,tri[i],bvh->vertices);
          if (all(terminated)) return terminated;
        }

        /* let terminated rays miss all boxes */
        rayFar = select(terminated,avxf(neg_inf),rayFar);
      }

      /*! pop next node from stack */
pop_node:
      if (unlikely(stackPtr == stack)) break;
      cur = *(--stackPtr);
    }
    return terminated;
  }
Beispiel #2
0
bool BezierCurve::intersectBox(const BoundingBox & box)
{
    BoundingBox ab = calculateBBox();

    if(!ab.intersect(box)) return false;
    
	const unsigned ns = numSegments();
    for(unsigned i=0; i < ns; i++) {
        BezierSpline sp;
        getSegmentSpline(i, sp);   
        if(intersectBox(sp, box)) return true;
    }
	
	return false;
}
  void BVH2Intersector8Chunk<TriangleIntersector>::intersect(const BVH2Intersector8Chunk* This, Ray8& ray, const __m256 valid_i)
  {
    avxb valid = valid_i;
    const BVH2* bvh = This->bvh;
    STAT3(normal.travs,1,popcnt(valid),8);

    struct StackItem {
      NodeRef ptr;
      avxf dist;
    };
    
    StackItem stack[1+BVH2::maxDepth];   //!< stack of nodes that still need to get traversed
    StackItem* stackPtr = stack;                       //!< current stack pointer
    NodeRef cur = bvh->root;                        //!< in cur we track the ID of the current node

    /* let inactive rays miss all boxes */
    const avx3f rdir = rcp_safe(ray.dir);
    ray.tfar = select(valid,ray.tfar,avxf(neg_inf));

    while (true)
    {
      /*! downtraversal loop */
      while (likely(cur.isNode()))
      {
        STAT3(normal.trav_nodes,1,popcnt(valid),8);

        /* intersect packet with box of both children */
        const Node* node = cur.node();
        avxf dist0; size_t hit0 = intersectBox(ray.org,rdir,ray.tnear,ray.tfar,node,0,dist0);
        avxf dist1; size_t hit1 = intersectBox(ray.org,rdir,ray.tnear,ray.tfar,node,1,dist1);

        /*! if two children hit, push far node onto stack and continue with closer node */
        if (likely(hit0 != 0 && hit1 != 0)) {
          if (any(valid & (dist0 < dist1))) { 
            stackPtr->ptr = node->child(1); stackPtr->dist = dist1; stackPtr++; cur = node->child(0); 
          } else { 
            stackPtr->ptr = node->child(0); stackPtr->dist = dist0; stackPtr++; cur = node->child(1); 
          }
        }

        /*! if one child hit, continue with that child */
        else {
          if      (likely(hit0 != 0)) cur = node->child(0);
          else if (likely(hit1 != 0)) cur = node->child(1);
          else goto pop_node;
        }
      }

      /*! leaf node, intersect all triangles */
      {
        STAT3(normal.trav_leaves,1,popcnt(valid),8);
        size_t num; Triangle* tri = (Triangle*) cur.leaf(NULL,num);
        for (size_t i=0; i<num; i++) {
          TriangleIntersector::intersect(valid,ray,tri[i],bvh->vertices);
        }
      }

      /*! pop next node from stack */
pop_node:
      if (unlikely(stackPtr == stack)) break;
      --stackPtr;
      cur = stackPtr->ptr;
      if (unlikely(all(stackPtr->dist > ray.tfar))) goto pop_node;
    }
  }
Beispiel #4
0
bool PrimitiveSuperellipsoid::allIntersectionRay( const TRay &ray,
						  TIntersectionStack &IStack ) const {
  //  int i, cnt, Found = FALSE;
  //  DBL dists[PLANECOUNT+2];
  //  DBL t, t1, t2, v0, v1, len;
  //  VECTOR P, D, P0, P1, P2, P3;
  bool found;

  // Intersect superellipsoid's bounding box.
  float t1, t2;
  if ( !intersectBox( ray, &t1, &t2) )
    return false;

  // Test if superellipsoid lies 'behind' the ray origin.
  if ( t2 < DEPTH_TOLERANCE )
    return false;

  int cnt = 0;

  if ( t1 < DEPTH_TOLERANCE )
    t1 = DEPTH_TOLERANCE;

  float dists[PLANECOUNT+2];
  dists[cnt++] = t1;
  dists[cnt++] = t2;

  // Intersect ray with planes cutting superellipsoids in pieces.
  cnt = findRayPlanePoints( ray, cnt, dists, t1, t2 );

  if ( cnt <= 1 )
    return false;

  TPoint3 P0 = ray.origin + ( ray.direction * dists[0] );

  float v0 = evaluateSuperellipsoid( P0 );

  if ( fabsf( v0 ) < ZERO_TOLERANCE ) {
    IStack.push( dists[0] );
    found = true;
  }
  for ( int i = 1; i < cnt; i++ ) {
    TPoint3 P1 = ray.origin + ( ray.direction * dists[i] );
    float v1 = evaluateSuperellipsoid( P1 );

    if ( fabsf(v1) < ZERO_TOLERANCE) {
      IStack.push( dists[i] );
      found = true;
    }
    else {
      TPoint3 P2;
      if ( v0 * v1 < 0.0f ) {
        // Opposite signs, there must be a root between
        solveHit1( v0, P0, v1, P1, P2 );
	
	TPoint3 P3 = P2 - ray.origin;
	float t = P3.magnitude();

	IStack.push( t );
	found = true;
      }
      else {
	// Although there was no sign change, we may actually be approaching
	// the surface. In this case, we are being fooled by the shape of the
	// surface into thinking there isn't a root between sample points. 
	float t;
        if ( checkHit2( ray, dists[i-1], P0, v0, dists[i], &t, P2 ) ) {
	  IStack.push( t );
	  found = true;
	}
      }
    }

    v0 = v1;
    P0 = P1;
  }

  return found;
}
// new define
void
LevelFluxRegisterEdge::define(
                              const DisjointBoxLayout& a_dbl,
                              const DisjointBoxLayout& a_dblCoarse,
                              const ProblemDomain& a_dProblem,
                              int a_nRefine,
                              int a_nComp)
{
  m_isDefined = true;
  CH_assert(a_nRefine > 0);
  CH_assert(a_nComp > 0);
  CH_assert(!a_dProblem.isEmpty());
  m_nComp = a_nComp;
  m_nRefine = a_nRefine;
  m_domainCoarse = coarsen(a_dProblem, a_nRefine);
  CH_assert (a_dblCoarse.checkPeriodic(m_domainCoarse));

  // allocate copiers
  m_crseCopiers.resize(SpaceDim*2);

  SideIterator side;

  // create a Vector<Box> of the fine boxes which also includes periodic images,
  // since we don't really care about the processor layouts, etc
  Vector<Box> periodicFineBoxes;
  CFStencil::buildPeriodicVector(periodicFineBoxes, a_dProblem, a_dbl);
  // now coarsen these boxes...
  for (int i=0; i<periodicFineBoxes.size(); i++)
    {
      periodicFineBoxes[i].coarsen(m_nRefine);
    }

  for (int idir=0 ; idir<SpaceDim; ++idir)
  {
    for (side.begin(); side.ok(); ++side)
    {
      // step one, build fineBoxes, flux register boxes
      // indexed by the fine level but in the coarse index
      // space
      DisjointBoxLayout fineBoxes,tmp;
      // first create coarsened dbl, then compute flux register boxes
      // adjacent to coarsened fine boxes
      coarsen(tmp, a_dbl, m_nRefine);
      if (side() == Side::Lo)
        {
          adjCellLo(fineBoxes, tmp, idir,1);
        }
      else
        {
          adjCellHi(fineBoxes, tmp, idir,1);
        }

      // now define the FluxBoxes of fabFine on this DisjointBoxLayout
      m_fabFine[index(idir, side())].define(fineBoxes, a_nComp);



      LayoutData<Vector<Vector<IntVectSet> > >& ivsetsVect
        = m_refluxLocations[index(idir, side())];
      ivsetsVect.define(a_dblCoarse);

      LayoutData<Vector<DataIndex> >& mapsV =
        m_coarToCoarMap[index(idir, side())];
      mapsV.define(a_dblCoarse);

      DisjointBoxLayout coarseBoxes = a_dblCoarse;
      DataIterator dit = a_dblCoarse.dataIterator();
      for (dit.begin(); dit.ok(); ++dit)
        {
          unsigned int thisproc = a_dblCoarse.procID(dit());
          if (thisproc == procID())
          {
            ivsetsVect[DataIndex(dit())].resize(SpaceDim);
          }
          const Box& coarseBox = a_dblCoarse[dit()];
          int count = 0;
          for (int i=0; i<periodicFineBoxes.size(); i++)
            {
              Box regBox;
              if (side() == Side::Lo)
                {
                  regBox = adjCellLo(periodicFineBoxes[i], idir, 1);
                }
              else
                {
                  regBox = adjCellHi(periodicFineBoxes[i], idir, 1);
                }

              // do this little dance in order to ensure that
              // we catch corner cells which might be in different
              // boxes.
              Box testBox(regBox);
              testBox.grow(1);
              testBox.grow(idir,-1);
              if (testBox.intersectsNotEmpty(coarseBox))
                {
                  testBox &= coarseBox;
                  ++count;
                  unsigned int proc = a_dblCoarse.procID(dit());
                  const DataIndex index = DataIndex(dit());
                  if (proc == procID())
                  {
                    mapsV[DataIndex(dit())].push_back(index);
                    // loop over face directions here
                    for (int faceDir=0; faceDir<SpaceDim; faceDir++)
                    {
                      // do nothing in normal direction
                      if (faceDir != idir)
                      {
                        // this should give us the face indices for the
                        // faceDir-centered faces adjacent to the coarse-fine
                        // interface which are contained in the current
                        // coarse box
                        Box intersectBox(regBox);
                        Box coarseEdgeBox(coarseBox);
                        coarseEdgeBox.surroundingNodes(faceDir);
                        intersectBox.surroundingNodes(faceDir);
                        intersectBox &= coarseEdgeBox;
                        intersectBox.shiftHalf(faceDir,1);
                        IntVectSet localIV(intersectBox);
                        ivsetsVect[DataIndex(dit())][faceDir].push_back(localIV);
                      }
                    }
                  }
                }
            } // end loop over boxes on coarse level
        }
      m_regCoarse.define(coarseBoxes, a_nComp, IntVect::Unit);

      // last thing to do is to define copiers
      m_crseCopiers[index(idir, side())].define(fineBoxes, coarseBoxes,
                                                IntVect::Unit);
    }
  }
}
Beispiel #6
0
bool BezierCurve::intersectBox(unsigned icomponent, const BoundingBox & box)
{
	BezierSpline sp;
	getSegmentSpline(icomponent, sp);   
    return intersectBox(sp, box);
}
bool BoxRayDragger::pick(const ONTransform& newTransformation,const Ray& ray,const Vector& viewPlaneNormal)
	{
	/* Set the initial transformation: */
	initialTransformation=newTransformation;
	
	/* Transform the ray to box coordinates: */
	Ray boxRay(initialTransformation.inverseTransform(ray.getOrigin()),initialTransformation.inverseTransform(ray.getDirection()));
	
	/* Calculate the half-sizes of the box, the edges and the vertices: */
	Scalar bs=boxSize*Scalar(0.5);
	Scalar es=boxSize*Scalar(0.075*0.5);
	Scalar vs=boxSize*Scalar(0.15*0.5);
	
	/* Initialize the hit result: */
	Scalar minLambda=Math::Constants<Scalar>::max;
	
	Point center;
	Scalar s[3];
	
	/* Intersect the ray with all box vertices: */
	s[0]=s[1]=s[2]=vs;
	for(int vertex=0;vertex<8;++vertex)
		{
		/* Use some bit masking magic to calculate the coordinates of the vertex: */
		for(int i=0;i<3;++i)
			center[i]=vertex&(1<<i)?bs:-bs;
		
		/* Intersect the ray with the vertex box: */
		Interval vi=intersectBox(boxRay,center,s);
		
		/* Check if this intersection is valid and closer than the current one: */
		if(vi.first<=vi.second&&vi.first<minLambda)
			{
			minLambda=vi.first;
			dragMode=DRAG_VERTEX;
			
			/* Initialize vertex dragging: */
			dragPlaneNormal=dragPlaneNormal;
			initialPoint=ray(minLambda);
			dragPlaneOffset=initialPoint*viewPlaneNormal;
			rotateCenter=initialTransformation.getOrigin();
			}
		}
	
	/* Intersect the ray with all box edges: */
	for(int edgeDirection=0;edgeDirection<3;++edgeDirection)
		{
		/* Calculate the size of the edge boxes: */
		s[edgeDirection]=bs;
		for(int i=1;i<3;++i)
			s[(edgeDirection+i)%3]=es;
		
		for(int edge=0;edge<4;++edge)
			{
			/* Use some more bit masking magic to calculate the center point of the edge: */
			center[edgeDirection]=0.0;
			for(int i=0;i<2;++i)
				center[(edgeDirection+i+1)%3]=edge&(1<<i)?bs:-bs;
			
			/* Intersect the ray with the edge box: */
			Interval ei=intersectBox(boxRay,center,s);
			
			/* Check if this intersection is valid and closer than the current one: */
			if(ei.first<=ei.second&&ei.first<minLambda)
				{
				minLambda=ei.first;
				dragMode=DRAG_EDGE;
				
				/* Initialize edge dragging: */
				dragPlaneNormal=viewPlaneNormal;
				initialPoint=ray(minLambda);
				dragPlaneOffset=initialPoint*dragPlaneNormal;
				for(int i=0;i<3;++i)
					rotateAxis[i]=i==edgeDirection?Scalar(1):Scalar(0);
				rotateCenter=initialTransformation.getOrigin();
				rotateAxis=initialTransformation.transform(rotateAxis);
				rotateDragDirection=Geometry::cross(rotateAxis,viewPlaneNormal);
				rotateDragDirection.normalize();
				}
			}
		}
	
	/* Intersect the ray with all box faces: */
	for(int faceDirection=0;faceDirection<3;++faceDirection)
		{
		/* Calculate the size of the face boxes: */
		s[faceDirection]=0.0;
		for(int i=1;i<3;++i)
			s[(faceDirection+i)%3]=bs;
		
		for(int face=0;face<2;++face)
			{
			/* Use even more bit masking magic to calculate the center point of the face: */
			center[faceDirection]=face&0x1?bs:-bs;
			for(int i=0;i<2;++i)
				center[(faceDirection+i+1)%3]=Scalar(0);
			
			/* Intersect the ray with the face box: */
			Interval fi=intersectBox(boxRay,center,s);
			
			/* Check if this intersection is valid and closer than the current one: */
			if(fi.first<=fi.second&&fi.first<minLambda)
				{
				minLambda=fi.first;
				dragMode=DRAG_FACE;
				
				/* Initialize face dragging: */
				for(int i=0;i<3;++i)
					dragPlaneNormal[i]=i==faceDirection?Scalar(1):Scalar(0);
				dragPlaneNormal=initialTransformation.transform(dragPlaneNormal);
				initialPoint=ray(minLambda);
				dragPlaneOffset=initialPoint*dragPlaneNormal;
				}
			}
		}
	
	/* Initialize the transient transformations: */
	dragTransformation=ONTransform::identity;
	currentTransformation=initialTransformation;
	
	return dragMode!=DRAG_NONE;
	}