__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; }
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; } }
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); } } }
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; }